git remote prune,git prune,git fetch --prune等有什么区别

gog*_*net 334 git remote-branch

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

大多数在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
Run Code Online (Sandbox Code Playgroud)

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

* master
  develop
  feature_blah
  random_branch_I_want_deleted
  remotes/origin/master
  remotes/origin/develop
  remotes/origin/feature_blah
Run Code Online (Sandbox Code Playgroud)

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

$ git prune
Run Code Online (Sandbox Code Playgroud)

我也尝试过:

$ git remote prune origin
$ git fetch --prune
Run Code Online (Sandbox Code Playgroud)

更有用的信息:当我检查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)
Run Code Online (Sandbox Code Playgroud)

请注意,它仅在标题为的部分中 Local branches configured for 'git pull':

为什么?

Joh*_*ter 621

我不会因为对此感到沮丧而责备你.最好的方法是看这个.每个远程分支可能有三个版本:

  1. 对远程仓库的实际分支
    (例如,在远程回购https://example.com/repo.git,refs/heads/master)
  2. 您在本地(存储在refs/remotes/...)下的分支快照
    (例如,本地仓库refs/remotes/origin/master)
  3. 并且可能正在跟踪远程分支的
    本地分支(例如,本地存储库refs/heads/master)

让我们开始吧git prune.这将删除不再被引用的对象,但不会删除引用.在您的情况下,您有一个本地分支.这意味着有一个名为ref的引用random_branch_I_want_deleted,它引用了一些表示该分支历史的对象.因此,根据定义,git prune不会删除random_branch_I_want_deleted.实际上,这git prune是一种删除Git中累积但未被任何内容引用的数据的方法.通常,它不会影响您对任何分支的查看.

git remote prune origin并且git fetch --prune都在refs/remotes/...(我将它们称为远程引用)之下的引用上运行.它不会影响本地分支机构.git remote如果您只想删除特定远程下的远程引用,则该版本很有用.否则,两者完全一样.所以,简而言之,git remote prunegit fetch --prune在上面的第2号操作.例如,如果您使用git Web GUI删除了分支,并且不希望它再次显示在本地分支列表中(git branch -r),那么这是您应该使用的命令.

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

  • 通过解释相关的差异,这可以更好地解决整个问题.它还回答了我从上面提到的其他问题. (18认同)
  • 此命令将显示没有相应远程分支的所有本地分支的列表.你_could_把它传递给`xargs git branch -D`,但请注意,你创建但从未推送到服务器的任何新分支都会被删除,所以请小心谨慎:`git branch -r | awk'{print $ 1}'| egrep -v -f/dev/fd/0 <(git branch -vv | grep origin)| awk'{print $ 1}'` (14认同)
  • @Seed不,不.:-(它只删除本地远程跟踪引用.我只是用版本2.7.0进行了双重检查. (4认同)

Cha*_*esB 52

git remote prunegit fetch --prune做同样的事情:正如你所说,删除refs到遥控器上不存在的分支.第二个命令连接到远程并在修剪之前获取其当前分支.

但是,它不会触及您已检出的本地分支,您只需删除即可

git branch -d  random_branch_I_want_deleted
Run Code Online (Sandbox Code Playgroud)

如果分支未在其他地方合并-d,-D则替换为

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

  • IMO使用"prune"进行对象集合*和*reference-cleanup的git命名约定是混乱的地方.但这只是git中许多UI难题之一.:-) (4认同)

Von*_*onC 13

注意之间的一个差git remote --prune,并git fetch --prune正被固定的,提交10a6cc8,由汤姆米勒(tmiller)(对于GIT中1.9/2.0,Q1 2014):

当我们有一个名为" frotz/nitfol" 的远程跟踪分支来自之前的提取,并且上游现在有一个名为"**frotz "**的分支时,fetch将无法从上游删除frotz/nitfol带有" git fetch --prune" 的分支.
git会通知用户使用" git remote prune"来解决问题.

所以:当一个上游仓库有一个与分支层次结构同名的分支("frotz")("frotz/xxx",一个可能的分支命名约定)时,git remote --prune成功(从你的仓库中清理远程跟踪分支)但是git fetch --prune失败了.

不再:

fetch --prune通过在提取操作之前移动修剪操作来更改" "的工作方式.
这样,它不会警告用户冲突,而是自动修复它.


D.M*_*ill 12

如果有人会感兴趣.这是一个快速shell脚本,它将删除所有未远程跟踪的本地分支.需要注意的是:无论是否合并,都将删除任何未远程跟踪的分支.

如果你们看到任何问题请告诉我,我会解决它(等等)

将其保存在一个名为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 $@
Run Code Online (Sandbox Code Playgroud)

  • $(git branch -d $i) 只删除合并的分支不是更安全吗? (2认同)