当你不在BRANCH上时,git push-u origin BRANCH会做什么



当我第一次开始使用git时,另一个团队成员告诉我要始终使用进行推送

git push -u origin MYBRANCH

因为这样可以防止我意外地将代码推送到错误的分支。我没有完全理解,今天我试图理解这意味着什么。

我创建了一个本地repo,并提供了我的确切命令,这样你就可以复制/粘贴它来复制我所做的事情。

在这个测试中,我有一个本地(磁盘上)回购和两个分支:

git branch
main
* feature/fixthis

我在feature/fixthis分支上运行:

git push -u origin main
# NOTE: the current branch is feature/fixthis

我是不是不小心把我的功能分支推到了main上

我的解决方案(使用本地测试自己计算)

为了亲自测试,我做了以下操作。这些命令的编写方式使得您可以将其复制/传递到UNIX bash shell,以重现本地git repo并创建我所询问的确切场景。

# Step 1:  Create local repo
mkdir so-test; cd so-test; git init --bare local-git-repo.git
# Step 2: git clone local (empty repo).
git clone ./local-git-repo.git test-this
# Step 3: Add a Readme.md file, commit and push the change 
cd test-this; echo hi > README.md; git add README.md; git commit -m "initial commit"; git push -u origin main
# Step 4: Check the branch feature/fixit.
git co -b feature/fixit
# Step 5: Make change and accidentally push it to main.  
echo In feature/fixit >> README.md; git add -u .; git commit -m "change on feature/fixit"; 
# Step 6: Do the push from the feature/fixit branch to main
git push -u origin main

命令git push -u origin main是否意外更新了主分支

当我查看日志时,我不知道上次推送发生了什么,它似乎没有更新origin/main分支,因为我没有看到origin/feature/fifixit标记(在任何提交中)。

git log
commit 1bba12ad200080cb0a59aa0e2fb518a1e284b135 (HEAD -> feature/fixit)
Author: me@example.com
Date:   Thu Apr 7 14:25:19 2022 +0000
change on feature/fixit
commit dcf8098bda7c937c80bc60ee974ac6eb9a895ced (origin/main, main)
Author: me@example.com
Date:   Thu Apr 7 14:20:06 2022 +0000
initial commit

正在搜索答案

  • 搜索〔git〕git push-u origin-大约20000个结果。。。哼……那不行,让我在类别中再加一个问题。:-)

  • ";u〃;做什么"git push-u原始主机";vs";git-push原始主机"-很好的答案,有很多好的技术材料。它可能会回答我的问题,但如果它回答了,我就没有看到。

许多其他

-u选项仅告诉git push在推送完成后运行git branch --set-upstream-to,前提是推送本身成功完成。

这并不能完全实现,因为git branch --set-upstream-to需要两个参数:要设置其上游的分支的名称和要设置的上游的名称。但它确实清楚地表明,无论当前分支是br1br2还是maingit push -u origin main开始做与git push origin main相同的事情:

  • origin翻译为URL
  • 调用Git软件在该URL上响应的任何内容
  • 向他们发送您有但没有的任何提交,这些提交导致并包括您在您的main上的提示提交;以及
  • 要求他们将他们的main设置为指向与main相同的提交

换句话说,您的br1br2名称在此操作中不起任何作用。

让我们假设您现在在br1分支上,并且此git push步骤已成功完成。他们的(origin的)main现在命名与main命名的提交相同的提交,而origin/main现在也命名该提交。现在,-u选项中的运行git branch --set-upstream-to操作开始生效。这将把一个分支名称的上游设置为一个origin/名称。哪个(本地)分行名称在这里有意义?什么origin/的名字在这里有意义1可能性包括:

git branch --set-upstream-to=origin/br2 br2

即使您在br1并且刚刚推送br2。不过,这完全没有道理。另一种可能性是:

git branch --set-upstream-to=origin/main br1

但这不是很明智,因为你没有推你的br1(即使你是on branch br1,正如git status所说)。你推了你的main。因此,实际命令是:

git branch --set-upstream-to=origin/main main

这就是-u所做的:在成功发送分支的提示提交和其他提交(如果需要的话),并使用它们设置相同名称的分支,然后设置相应的origin/远程跟踪名称后,-u操作将该(命名的)分支的上游设置为该远程跟踪名称。

最复杂的情况是eftshift0提示的情况。我们可以运行,例如:

git switch main
git push -u origin br2:new-name

这将向origin传递导致br2的提示提交的提交,无论这些提交可能是他们还没有的,然后要求他们——originGit存储库——将他们的名称new-name设置为指向我们发送的提示最多的提交(或者如果他们已经有了,则不必发送)。但是git branch --set-upstream-to会发生什么呢?好吧,让我们试试:

$ git push -u origin fix-signal:new-br
Total 0 (delta 0), reused 0 (delta 0), pack-reused 0
To [redacted]
* [new branch]      fix-signal -> new-br
Branch 'fix-signal' set up to track remote branch 'new-br' from 'origin'.

事实上,git branch -vv现在包括:

fix-signal e068bdf [origin/new-br] make signal handler work in py2k and py3k

(请注意,我是这个存储库中的on管理员)。如果我现在删除origin/newbr:

$ git push origin :new-br
...
- [deleted]         new-br
$ git branch -vv --list fix-signal
fix-signal e068bdf [origin/new-br: gone] make signal handler work in py2k and py3k

我现在应该运行git branch --unset-upstream fix-signal,因为我已经没有origin/new-br了。(像这样有一个断开的上游并不完全有害,只是没用。分支早些时候没有上游,所以我确实这么做了。)


1使用";这里有什么意义;这个规则有点危险,因为并不是Git所做的每件事都有意义,但它是一个不错的指南。

该命令只是将本地分支MYBRANCH(远程分支同名)推入远程origin。当您正在处理分支a并且希望将分支B推入远程时,会使用此选项。

如果你愿意的话,你甚至可以用不同的名字进入分支机构:

git push origin a-local-branch-name:a-remote-branch-name

相关内容

最新更新