当我第一次开始使用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
需要两个参数:要设置其上游的分支的名称和要设置的上游的名称。但它确实清楚地表明,无论当前分支是br1
、br2
还是main
,git push -u origin main
开始做与git push origin main
相同的事情:
- 将
origin
翻译为URL - 调用Git软件在该URL上响应的任何内容
- 向他们发送您有但没有的任何提交,这些提交导致并包括您在您的
main
上的提示提交;以及 - 要求他们将他们的
main
设置为指向与main
相同的提交
换句话说,您的br1
和br2
名称在此操作中不起任何作用。
让我们假设您现在在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
的提示提交的提交,无论这些提交可能是他们还没有的,然后要求他们——origin
Git存储库——将他们的名称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