推送新分支后自动设置上游分支

4
这里是事情的关键:
$ git checkout -b new-branch
Switched to a new branch 'new-branch'

$ git push
...
 * [new branch]      new-branch -> new-branch

$ git pull
There is no tracking information for the current branch.
Please specify which branch you want to rebase against.
See git-pull(1) for details.

    git pull <remote> <branch>

If you wish to set tracking information for this branch you can do so with:

    git branch --set-upstream-to=origin/<branch> new-branch

我看到过其他问题,答案建议在第一次推送时执行git push -u。但是我总是忘记这样做。

是否有配置选项可以在从我的仓库推送新分支到远程仓库时自动设置上游跟踪分支?

3个回答

3

是否有配置选项可以在使用 git push 创建分支时暗示使用 -u 参数?

可能应该有这样的选项,但实际上没有。不过,你可以使用 git branch --set-upstream-to 来修复问题,就像 Git 错误信息中所述。

与其他答案类似,你可以设置一些别名。更进一步地,如 fracz's answer 所述,每次使用 -u 选项是安全的:这将在每次推送时设置上游,但假设你总是推送到同一个地方,则每次都会将上游从 origin/branch 更改为 origin/branch,即实际上并未更改任何内容。

除了进度输出,甚至没有办法知道git push是否真的在远程创建了分支。(push命令本身可以告诉你,但它只将此作为消息[new branch]或不是[new branch]报告。)在推送之前运行git ls-remote可以得到相当接近的结果,但这里存在竞争:如果ls-remote报告该分支不存在,并且推送成功,则您无法确定您的推送是否创建了它,因为有一种非常微小的可能性是其他人创建了它,但您的推送仍然成功。

但是,在git push开始之前很容易知道是否存在上游。

以下是一个(有点不完美且完全未经测试)脚本,它执行我认为git push应该实际执行的操作。

#! /bin/sh
#
# Push, and set upstream if the push succeeds and
# there was no upstream set before the push started,
# based on "push.set-upstream" setting

die() {
    printf "%s\n" "$1" 1>&2
    exit 1
}

get_current_branch() {
    git symbolic-ref -q --short HEAD ||
        die "fatal: not currently on a branch"
}

get_remote() {
    git config --get branch."$1".remote || echo origin
}

upstream_is_set() {
    git rev-parse -q --verify "$1@{u}" >/dev/null 2>&1
}

# arguments are: [remote [branch]]
# we do not accept arbitrary refspecs here!

case $# in
0)  branch=$(get_current_branch) || exit $?
    remote=$(get_remote "$branch")
    ;;
1)  remote="$1"
    branch=$(get_current_branch) || exit $?
    ;;
2)  remote="$1" branch="$2";; # should check $2 ref format?
*)  die "usage: gitpush [remote [branch]]";;
esac

how_to_set=$(git config --get push.set-upstream || echo auto)

case "$how_to_set" in
always|true) do_set=true;;
false) do_set=false;;
auto|only-if-unset) if upstream-is-set "$branch"; then
        do_set=false
    else
        do_set=true
    fi;;
*) die "fatal: don't understand push.set-upstream=$how_to_set";;
esac

# figured everything out, so now push; fail if push fails
git push "$remote" "$branch" || exit $?

# last, set upstream if still needed
if $do_set; then git branch --set-upstream-to "$remote/$branch"; fi

你可以使用git branch --set-upstream-to来修复问题,就像Git错误信息中所示。但是,如果至少该消息已准备好被复制/粘贴就好了。但我必须手动替换<branch> - warvariuc
然而,在你的 git push 开始之前很容易判断是否存在上游。为什么不在推送时检查标准输出中的 [new branch] 并执行 --set-upstream-to 呢?这样可以解决竞争条件并且速度更快,只需要第一次执行即可。 - warvariuc
因为(a)它不是发送到标准输出的消息(而是发送到stderr); (b)在某些情况下不会产生(尽管您可以使用--progress强制执行); 并且(c)它仅是实现的副作用; 它是国际化的(因此您必须覆盖$LANG); 它过去已经更改了格式,所以将来可能会再次更改格式。换句话说,它并不是非常可靠的。 - torek

2

您可以通过创建一个别名来自动使用-u开关,从而实现您可以接受的某些内容。例如:

git config --global alias.pu "push -u"

然后像这样使用

git pu

很不幸,你不能用git别名覆盖任何原始的git命令。你可以尝试使用bash别名代替git push命令,并以此方式默认添加-u开关。


-1
使用 git push -u origin <branch> 作为您的第一次推送,这将设置跟踪。

1
我已经在问题中涉及了这种情况。它不适合我。 - warvariuc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接