自动化 Git push

Table of Contents


背景

我在使用 Git 时,如果要提交代码到远程仓库,我经常会这样做:

cd <target directory>
git add .
git commit -m "commit message"
git push

注:如果想在一个分支中直接使用 git push,要保证使用过 git push –set-upstream origin <branch_name>

这些命令模式固定而且繁琐,终于有一天我忍受不了了。 所以我的目标是把这些操作简化为一条命令。

最终的成果如下:

push                # default message in current directory
push "message"      # push with specified message in current directory
push blog                       # default message in the directory of blog
push blog "message" # push with specified directory and message

上面的 blog 是我的配置文件中的一条配置,它其实就是一个目录:

blog_path='~/workspace/blog/public_html'

实现

auto_push() {
git add .
        local desc=$1
if [ -z "$1" ]; then
    desc="Auto commit" # default message
fi
git commit -m "$desc"
git push
}

到这里我们其实就可以使用:

auto_push
auto_push "message"

现在还有个问题,我们首先需要 cd 到某个目录中操作。

如果我们能够不需要 cd,而且可以在任意的目录中操作就完美了。

改进

首先先看代码:

    read_config() {
    CONFIG="~/.config/zsh-command/path.config"
    source $CONFIG

    if [ -z "$1" ]; then
        auto_push
    elif ! cat $CONFIG | grep "$1" > /dev/null; then
        auto_push $1
    else
        temp=${1}_path
        # https://superuser.com/questions/935374/difference-between-and-in-shell-script
        # https://unix.stackexchange.com/questions/68035/foo-and-zsh
        pushd ${(P)temp} > /dev/null # we use pushd instead of cd
        auto_push $2
        popd > /dev/null
    fi
}

其中 CONFIG 是配置文件的目录。配置文件如下,

blog_path='~/workspace/blog/public_html'
emacs_path='~/.emacs.d'

使用 source $CONFIG 后就可以直接使用$blog_path 和 $emacs_path 变量了。

注意 ${(P)temp} ,这里为什么要加一个 "(P)" 呢?我们如果不加的话, 它其实就是 temp 的值也就是 blog_path,但是我们想获得 $blog_path 的值加 "(P)" 就是完成了这个功能。还有一点 "(P)" 是在 zsh 中的用法, 如果用 bash 需要把 "(P)" 改为 "!"。

下一个有趣的问题时 pushd。如果你没见过这个命令,你可能感觉它很奇怪, 其实它和 cd 做的事情差不多。这里我们没有用 cd 的原因是,cd 在 shell 中命令无法正确的执行。网上有很多的解决办法,我认为比较优雅的方法是用 pushd 和 popd。

最后加一句:

alias push="read_config"

如果想更简化,直接用单个字母代替单词。

p b <= push blog
p e <= push emacs

现在,顿时一切竟然变得如此简单。