本文翻译自:What are the differences between git remote prune, git prune, git fetch --prune, etc
My situation is this... someone working on the same repo has deleted a branch from his local & remote repo... 我的情况是这样......在同一个仓库工作的人从他的本地和远程仓库中删除了一个分支......
Most people who have asked about this kind of problem on Stack Overflow, or other sites have the issue of branches still showing in their remote tracking branch list git branch -a
at the bottom: 大多数在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
However, in MY situation the branch that shouldn't be there, is local: 但是,在我的情况下,不应该在那里的分支是本地的:
* master
develop
feature_blah
random_branch_I_want_deleted
remotes/origin/master
remotes/origin/develop
remotes/origin/feature_blah
When I do any of the following, it doesn't get removed locally: 当我执行以下任何操作时,它不会在本地删除:
$ git prune
I also tried: 我也尝试过:
$ git remote prune origin
$ git fetch --prune
More useful info: When I check git remote show origin
this is how it looks: 更有用的信息:当我检查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)
Notice that it's only in the section titled Local branches configured for 'git pull':
请注意,它仅在标题Local branches configured for 'git pull':
的部分中Local branches configured for 'git pull':
Why? 为什么?
参考:https://stackoom.com/question/1MMfo/git-remote-prune-git-prune-git-fetch-prune等有什么区别
git remote prune
and git fetch --prune
do the same thing: deleting the refs to the branches that don't exist on the remote, as you said. git remote prune
和git fetch --prune
做同样的事情:删除refs到遥控器上不存在的分支,如你所说。 The second command connects to the remote and fetches its current branches before pruning. 第二个命令连接到远程并在修剪之前获取其当前分支。
However it doesn't touch the local branches you have checked out, that you can simply delete with 但是,它不会触及您已检出的本地分支,您只需删除即可
git branch -d random_branch_I_want_deleted
Replace -d
by -D
if the branch is not merged elsewhere 如果分支未在其他地方合并,请将-d
替换为-D
git prune
does something different, it purges unreachable objects, those commits that aren't reachable in any branch or tag, and thus not needed anymore. git prune
做了不同的事情,它清除了无法访问的对象,那些在任何分支或标记中都无法访问的提交,因此不再需要它们。
I don't blame you for getting frustrated about this. 我不会因为对此感到沮丧而责备你。 The best way to look at is this. 最好的方法是看这个。 There are potentially three versions of every remote branch: 每个远程分支可能有三个版本:
refs/heads/master
) (例如, https : refs/heads/master
远程回购) refs/remotes/...
) 您在本地分支的快照(存储在refs/remotes/...
) refs/remotes/origin/master
) (例如,本地回购, refs/remotes/origin/master
) refs/heads/master
) (例如,本地回购, refs/heads/master
) Let's start with git prune
. 让我们从git prune
开始吧。 This removes objects that are no longer being referenced, it does not remove references. 这将删除不再被引用的对象 ,但不会删除引用。 In your case, you have a local branch. 在您的情况下,您有一个本地分支。 That means there's a ref named random_branch_I_want_deleted
that refers to some objects that represent the history of that branch. 这意味着有一个名为random_branch_I_want_deleted
的引用,它引用了一些表示该分支历史的对象。 So, by definition, git prune
will not remove random_branch_I_want_deleted
. 因此,根据定义, git prune
不会删除random_branch_I_want_deleted
。 Really, git prune
is a way to delete data that has accumulated in Git but is not being referenced by anything. 实际上, git prune
是一种删除Git中累积但未被任何东西引用的数据的方法。 In general, it doesn't affect your view of any branches. 通常,它不会影响您对任何分支的查看。
git remote prune origin
and git fetch --prune
both operate on references under refs/remotes/...
(I'll refer to these as remote references). git remote prune origin
和git fetch --prune
都在refs/remotes/...
下的引用上运行(我将它们称为远程引用)。 It doesn't affect local branches. 它不会影响本地分支机构。 The git remote
version is useful if you only want to remove remote references under a particular remote. 如果您只想删除特定远程下的远程引用,则git remote
版本非常有用。 Otherwise, the two do exactly the same thing. 否则,两者完全一样。 So, in short, git remote prune
and git fetch --prune
operate on number 2 above. 所以,简而言之, git remote prune
和git fetch --prune
在上面的数字2上运行。 For example, if you deleted a branch using the git web GUI and don't want it to show up in your local branch list anymore ( git branch -r
), then this is the command you should use. 例如,如果您使用git Web GUI删除了分支,并且不希望它再次显示在您的本地分支列表中( git branch -r
),那么这是您应该使用的命令。
To remove a local branch, you should use git branch -d
(or -D
if it's not merged anywhere). 要删除本地分支,您应该使用git branch -d
(如果未在任何地方合并,则使用-D
)。 FWIW, there is no git command to automatically remove the local tracking branches if a remote branch disappears. FWIW,如果远程分支消失,则没有git命令自动删除本地跟踪分支。
Note that one difference between git remote --prune
and git fetch --prune
is being fixed, with commit 10a6cc8 , by Tom Miller ( tmiller
) (for git 1.9/2.0, Q1 2014): 请注意, git remote --prune
和git fetch --prune
之间的一个区别是使用提交10a6cc8 ,由Tom Miller( tmiller
) tmiller
(对于git 1.9 / 2.0,2014年第一季度):
When we have a remote-tracking branch named "
frotz/nitfol
" from a previous fetch, and the upstream now has a branch named "**frotz "**,fetch
would fail to remove "frotz/nitfol
" with a "git fetch --prune
" from the upstream. 当我们有一个名为“frotz/nitfol
”的远程跟踪分支来自之前的提取, 并且上游现在有一个名为“** frotz ”** 的分支时 ,fetch
将无法使用“git fetch --prune
”删除“frotz/nitfol
”git fetch --prune
“来自上游。
git would inform the user to use "git remote prune
" to fix the problem. git会通知用户使用“git remote prune
”来解决问题。
So: when a upstream repo has a branch ("frotz") with the same name as a branch hierarchy ("frotz/xxx", a possible branch naming convention ), git remote --prune
was succeeding (in cleaning up the remote tracking branch from your repo), but git fetch --prune
was failing. 所以:当一个上游仓库有一个与分支层次结构同名的分支(“frotz”)(“frotz / xxx”,一个可能的分支命名约定 )时, git remote --prune
成功(在清理远程跟踪时)从你的回购分支),但git fetch --prune
失败了。
Not anymore: 不再:
Change the way "
fetch --prune
" works by moving the pruning operation before the fetching operation. 通过在提取操作之前移动修剪操作来更改“fetch --prune
”的工作方式。
This way, instead of warning the user of a conflict, it automatically fixes it. 这样,它不会警告用户冲突,而是自动修复它。
In the event that anyone would be interested. 如果有人会感兴趣。 Here's a quick shell script that will remove all local branches that aren't tracked remotely. 这是一个快速shell脚本,它将删除所有未远程跟踪的本地分支。 A word of caution: This will get rid of any branch that isn't tracked remotely regardless of whether it was merged or not. 需要注意的是:无论是否合并,都将删除任何未远程跟踪的分支。
If you guys see any issues with this please let me know and I'll fix it (etc. etc.) 如果你们看到任何问题请告诉我,我会解决它(等等)
Save it in a file called git-rm-ntb
(call it whatever) on PATH
and run: 将它保存在PATH
上名为git-rm-ntb
(无论如何)的文件中并运行:
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 $@