我的情况是这样的......在同一个仓库工作的人已经从他的本地和远程仓库中删除了一个分支......
大多数在 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':
的部分中
为什么?
x/y
) 时存在细微差别:已修复(参见 my answer below)
我不怪你为此感到沮丧。最好的观察方法是这个。每个远程分支可能有三个版本:
远程存储库上的实际分支(例如,位于 https://example.com/repo.git、refs/heads/master 的远程存储库) 您在本地的该分支的快照(存储在 refs/remotes/... 下)(例如, local repo, refs/remotes/origin/master) 和一个可能正在跟踪远程分支的本地分支 (例如, local repo, refs/heads/master)
让我们从 git prune
开始。这将删除不再被引用的对象,它不会删除引用。就您而言,您有一个本地分支机构。这意味着有一个名为 random_branch_I_want_deleted
的 ref 引用了一些代表该分支历史的对象。因此,根据定义,git prune
不会删除 random_branch_I_want_deleted
。实际上,git prune
是一种删除在 Git 中积累但未被任何东西引用的数据的方法。一般来说,它不会影响您对任何分支的看法。
git remote prune origin
和 git fetch --prune
都对 refs/remotes/...
下的引用进行操作(我将它们称为远程引用)。它不影响本地分支机构。如果您只想删除特定遥控器下的远程引用,git remote
版本很有用。否则,两者做完全相同的事情。因此,简而言之,git remote prune
和 git fetch --prune
在上面的数字 2 上运行。例如,如果您使用 git web GUI 删除了一个分支,并且不希望它再出现在您的本地分支列表中 (git branch -r
),那么这就是您应该使用的命令。
要删除本地分支,您应该使用 git branch -d
(或 -D
,如果它没有在任何地方合并)。 FWIW,如果远程分支消失,没有 git 命令可以自动删除本地跟踪分支。
git remote prune
和 git fetch --prune
做同样的事情:如你所说,删除远程不存在的分支的引用。第二个命令连接到远程并在修剪之前获取其当前分支。
但是它不会触及您已签出的本地分支,您可以简单地删除
git branch -d random_branch_I_want_deleted
如果分支未在其他地方合并,则将 -d
替换为 -D
git prune
做了一些不同的事情,它清除无法访问的对象,即那些在任何分支或标签中都无法访问的提交,因此不再需要。
git prune
不仅查找分支和标签,还查找所有其他引用。
git remote prune
)
万一有人感兴趣。这是一个快速的 shell 脚本,它将删除所有未远程跟踪的本地分支。提醒一句:这将摆脱任何未被远程跟踪的分支,无论它是否被合并。
如果你们看到任何问题,请告诉我,我会解决它(等等)
将其保存在 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 $@
请注意,Tom Miller (tmiller
)(对于 git 1.9/2.0,2014 年第一季度)使用 commit 10a6cc8 修复了 git remote --prune
和 git fetch --prune
之间的一个区别:
当我们从之前的 fetch 中有一个名为“frotz/nitfol”的远程跟踪分支,而上游现在有一个名为“**frotz”** 的分支时,fetch 将无法使用“git fetch”删除“frotz/nitfol” --prune”从上游。 git 会通知用户使用“git remote prune”来解决问题。
所以:当 upstream repo 有一个与 branch hierarchy 同名的分支(“frotz”)时(“frotz/xxx”,可能的 branch naming convention ),git remote --prune
成功(从您的存储库中清除远程跟踪分支),但 git fetch --prune
失败。
不再:
通过在获取操作之前移动修剪操作来改变“fetch --prune”的工作方式。这样,它不会警告用户发生冲突,而是自动修复它。
不定期副业成功案例分享
xargs git branch -D
,但请注意,您创建但从未推送到服务器的任何新分支都将被删除,因此请谨慎行事:git branch -r | awk '{print $1}' | egrep -v -f /dev/fd/0 <(git branch -vv | grep origin) | awk '{print $1}'
.git
区域中的packed-refs
文件),因此通过文件资源管理器删除它们不一定是简单的事情。最好使用命令来确保两者都得到正确处理。