Git中清理过期分支的正确方法是什么?

3
如果我运行git fetch --all --prune,这会在本地删除过时的分支,还是它首先从克隆中获取所有分支,然后再进行清理。
我注意到一个情况,我在一台机器上使用git push --delete origin some_branch,然后当我在另一个完整的实例中执行git fetch --all --prune然后git pull之后,该分支仍然存在。
我不理解这种行为,正确的清理过时分支的方法是什么?

我从Atlassian对这个问题的回答中学到了新东西: git prune通常不会直接执行。Prune被认为是垃圾收集命令,是git gc命令的子命令。 https://www.atlassian.com/git/tutorials/git-prune - Mike S.
1个回答

4
首先,请注意git fetch中的--all表示所有远程仓库,而不是所有引用。也就是说,如果你只有一个名为origin的远程仓库,--all实际上什么也不做。
其次,请记住分支名称(即refs/heads/下的名称,例如refs/heads/master)与远程跟踪名称之间的区别,后者有时称为远程跟踪分支名称,它是refs/remotes/下的参考,后跟远程仓库的名称。 --prune的作用是删除没有对应的远程仓库名称的远程跟踪名称。 git fetch通常执行以下操作:
  1. 使用存储在该远程仓库中的URL调用Git,例如从origin获取时使用git config --get remote.origin.url中的URL。

  2. 请他们列出其引用名称(运行git ls-remote查看这些引用名称)。

  3. 与该Git进行对话,以获取他们拥有的Git对象,通常是提交对象,但是步骤2中的任何对象都是候选对象,这些对象我们没有,而我们想要(基于给git fetch提供的任何其他参数或配置设置)。

  4. 最后,在获取所有对象之后,根据在该远程仓库上看到的分支名称创建或更新本地名称,通常形式为refs/remotes/remote/name。但请参阅下面的内容,因为此步骤存在问题。

    在此更新期间,如果启用了修剪功能(通过--prune或配置选项),则您的Git可能会删除其中一些远程跟踪名称。所有这些操作均在运行git pull的第二个Git命令之前完成,后者会运行git fetch,然后再运行第二个Git命令。

最后,需要注意的是,为使--prune正常工作,你需要一个典型的remote.remote.fetch设置,例如remote.origin.fetch将会显示+refs/heads*:refs/remotes/origin/*,然后执行git fetch --prune时,如果在Git仓库remote.origin.url中不存在refs/heads/xyzzy,则会从你自己的仓库中移除refs/remotes/origin/xyzzy。如果你使用了--single-branch克隆,则remote.origin.fetch行的内容将不同,并且--prune将无效。
根据你观察到的情况,似乎你设置了非标准的remote.origin.fetch,可能是由于以单分支克隆创建克隆造成的。

什么是单分支克隆,如何检查设置“remote.origin.fetch”以进行验证? - Jim
1
我不明白如何解决这个问题,即如何强制清理。 - Jim
机器中进行清理的最佳方法是什么? - Jim
1
这是一个正常的(非单分支)克隆。如果git branch -aremotes/origin/下没有列出它,那么它就是一个(本地)分支;fetch不会删除它。如果你运行git branch -d <name>,你的Git会在操作安全的情况下删除它(意思是你不会丢失任何提交)。如果你确定要删除它,即使它安全(可能会丢失提交),你可以使用git branch -D <name>(大写D-删除来强制删除)。较新版本的Git也接受git branch --force -d <name> - torek
1
因为你的分支是你自己的。我在我的Git仓库上做的事情,或者其他人在其他人的仓库上做的事情,为什么要改变你的分支? - torek
显示剩余4条评论

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