当前位置: 首页 > 工具软件 > git-issues > 使用案例 >

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

庞乐池
2023-12-01

本文翻译自: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? 为什么?


#1楼

参考:https://stackoom.com/question/1MMfo/git-remote-prune-git-prune-git-fetch-prune等有什么区别


#2楼

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 prunegit 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做了不同的事情,它清除了无法访问的对象,那些在任何分支或标记中都无法访问的提交,因此不再需要它们。


#3楼

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: 每个远程分支可能有三个版本:

  1. The actual branch on the remote repository 远程存储库上的实际分支
    (eg, remote repo at https://example.com/repo.git , refs/heads/master ) (例如, httpsrefs/heads/master远程回购)
  2. Your snapshot of that branch locally (stored under refs/remotes/... ) 您在本地分支的快照(存储在refs/remotes/...
    (eg, local repo, refs/remotes/origin/master ) (例如,本地回购, refs/remotes/origin/master
  3. And a local branch that might be tracking the remote branch 以及可能正在跟踪远程分支的本地分支
    (eg, local repo, 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 origingit 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 prunegit 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命令自动删除本地跟踪分支。


#4楼

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 --prunegit fetch --prune之间的一个区别是使用提交10a6cc8 ,由Tom Miller( tmillertmiller (对于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/nitfolgit 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. 这样,它不会警告用户冲突,而是自动修复它。


#5楼

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 $@
 类似资料: