git remote prune,git prune,git fetch –prune等有什么区别?

我的情况是这样的…一个在同一个仓库工作的人从他的本地和远程仓库删除了一个分支…

大多数在Stack Overflow或其他站点上询问过这种问题的人都会遇到在远程跟踪分支列表中仍然显示分支的问题git branch -a在底部:

 * master develop feature_blah remotes/origin/master remotes/origin/develop remotes/origin/feature_blah remotes/origin/random_branch_I_want_deleted 

然而,在我的情况下,不应该在那里的分支是本地的:

 * master develop feature_blah random_branch_I_want_deleted remotes/origin/master remotes/origin/develop remotes/origin/feature_blah 

当我执行以下任何操作时,它不会被本地删除:

 $ git prune 

我也试过:

 $ git remote prune origin $ git fetch --prune 

更有用的信息:当我检查git remote show origin这是它看起来如何:

 * remote origin Fetch URL: utilities:homeconnections_ui.git Push URL: utilities:homeconnections_ui.git HEAD branch: master Remote branches: master tracked develop tracked feature_blah tracked other123 tracked other444 tracked other999 tracked Local branches configured for 'git pull': develop merges with remote develop feature_blah merges with remote other999 master merges with remote master random_branch_I_want_deleted merges with remote random_branch_I_want_deleted Local refs configured for 'git push': develop pushes to develop (local out of date) master pushes to master (up to date) feature_blah pushes to feature_blah(up to date) 

请注意,它只在标题Local branches configured for 'git pull':部分Local branches configured for 'git pull':

为什么?

我不怪你因此而感到沮丧。 最好的方法是看这个。 每个远程分支可能有三个版本:

  1. 远程存储库上的实际分支
  2. 您本地的分支快照(存储在refs/remotes/...
  3. 还有一个可能跟踪远程分支的本地分支

我们从git prune开始。 这将删除不再被引用的对象 ,而不是引用。 就你而言,你有一个本地分支。 这意味着有一个名为random_branch_I_want_deleted引用表示该分支历史logging的一些对象。 所以,根据定义, git prune不会删除random_branch_I_want_deleted 。 这是删除在Git中积累的数据的一种方法,但不会被任何有用的东西引用。 一般来说,这不会影响你对任何分支的看法。

git remote prune origingit fetch --prune都在refs/remotes/...下引用(我将把它们称为远程引用)。 它不影响当地的分支机构。 如果您只想删除特定远程下的远程引用, git remote版本很有用。 否则,二者完全一样。 所以,简而言之, git remote prunegit fetch --prune在上面的第二个数字上运行。

要删除一个本地分支,你应该使用git branch -d (或者-D如果它没有被合并到任何地方)。 FWIW,如果远程分支消失,没有git命令自动删除本地跟踪分支。

git remote prunegit fetch --prune做同样的事情:删除不存在于远程的分支的引用,就像你说的那样。 第二个命令连接到远程并在修剪之前获取其当前分支。

但是,它不会触及你已经签出的本地分行,你可以简单地删除

 git branch -d random_branch_I_want_deleted 

如果分支未在其他位置合并,请将-dreplace为-D

git prune做了一些不同的事情,它清除了无法访问的对象,那些不能在任何分支或标记中访问的提交,因此不再需要。

请注意, git remote --prunegit fetch --prune之间的一个区别正在被Tom Miller( tmiller )的 commit 10a6cc8 (git 1.9 / 2.0,Q1 2014)所修正:

当我们有一个名为“ frotz/nitfol ”的远程跟踪分支从上一次获取, 而上游现在有一个名为“** frotz ”** 的分支时fetch将无法删除“ frotz/nitfol ”与“ git fetch --prune来自上游的“ git fetch --prune ”。
git会通知用户使用“ git remote prune ”来解决这个问题。

所以:当一个上游回购有一个分支(“frotz”)与分支层次同名(“frotz / xxx”,一个可能的分支命名约定 )时, git remote --prune成功了(在清理远程跟踪从你的回购分支),但是git fetch --prune失败了。

不再:

fetch --prune操作之前,通过移动修剪操作来改变“ fetch --prune ”的工作方式。
这样,而不是警告冲突的用户,它会自动修复它。

如果有人会感兴趣。 这是一个快速的shell脚本,它将删除所有没有远程跟踪的本地分支。 谨慎的一句话:这将摆脱任何不被远程追踪的分支,不pipe它是否被合并。

如果你们看到这个问题,请让我知道,我会解决它(等等)

将它保存在一个名为git-rm-ntb的文件(在PATH调用它)并运行:

git-rm-ntb <remote1:optional> <remote2:optional> ...

 clean() { REMOTES="$@"; if [ -z "$REMOTES" ]; then REMOTES=$(git remote); fi REMOTES=$(echo "$REMOTES" | xargs -n1 echo) RBRANCHES=() while read REMOTE; do CURRBRANCHES=($(git ls-remote $REMOTE | awk '{print $2}' | grep 'refs/heads/' | sed 's:refs/heads/::')) RBRANCHES=("${CURRBRANCHES[@]}" "${RBRANCHES[@]}") done < <(echo "$REMOTES" ) [[ $RBRANCHES ]] || exit LBRANCHES=($(git branch | sed 's:\*::' | awk '{print $1}')) for i in "${LBRANCHES[@]}"; do skip= for j in "${RBRANCHES[@]}"; do [[ $i == $j ]] && { skip=1; echo -e "\033[32m Keeping $i \033[0m"; break; } done [[ -n $skip ]] || { echo -e "\033[31m $(git branch -D $i) \033[0m"; } done } clean $@ 

这有点残酷,但如果你不关心本地历史,所有重要的分支已经承诺。 这是一个快速重置:

 rm -rf .git git init git remote add origingit@github.com:my/test.git git checkout master -f