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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20106712/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 17:20:50  来源:igfitidea点击:

What are the differences between git remote prune, git prune, git fetch --prune, etc

gitremote-branch

提问by gogogadgetinternet

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 -aat 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 originthis 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':

Why?

为什么?

回答by John Szakmeister

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
    (e.g., remote repo at https://example.com/repo.git, refs/heads/master)
  2. Your snapshot of that branch locally (stored under refs/remotes/...)
    (e.g., local repo, refs/remotes/origin/master)
  3. And a local branch that might be tracking the remote branch
    (e.g., local repo, refs/heads/master)
  1. 远程仓库上的实际分支
    (例如https://example.com/repo.git上的远程仓库,refs/heads/master
  2. 您本地该分支的快照(存储在 下refs/remotes/...
    (例如,本地存储库,refs/remotes/origin/master
  3. 以及可能正在跟踪远程分支的
    本地分支(例如,本地仓库refs/heads/master

Let's start with git prune. This removes objectsthat 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_deletedthat refers to some objects that represent the history of that branch. So, by definition, git prunewill not remove random_branch_I_want_deleted. Really, git pruneis a way to delete data that has accumulated in Git but is not being referenced by anything. In general, it doesn't affect your view of any branches.

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

git remote prune originand git fetch --pruneboth operate on references under refs/remotes/...(I'll refer to these as remote references). It doesn't affect local branches. The git remoteversion is useful if you only want to remove remote references under a particular remote. Otherwise, the two do exactly the same thing. So, in short, git remote pruneand git fetch --pruneoperate on number 2 above. 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 remote prune origin并且git fetch --prune都对下的引用进行操作refs/remotes/...(我将它们称为远程引用)。它不会影响本地分支机构。git remote如果您只想删除特定远程下的远程引用,该版本很有用。否则,两者会做完全相同的事情。所以,简而言之,git remote prunegit fetch --prune在上面的数字 2 上操作。例如,如果您使用 git web GUI 删除了一个分支,并且不希望它再出现在您的本地分支列表中 ( git branch -r),那么这就是您应该使用的命令。

To remove a local branch, you should use git branch -d(or -Dif it's not merged anywhere). FWIW, there is no git command to automatically remove the local tracking branches if a remote branch disappears.

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

回答by CharlesB

git remote pruneand git fetch --prunedo the same thing: deleting the refs to the branches that don't exist on the remote, as you said. The second command connects to the remote and fetches its current branches before pruning.

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

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 -dby -Dif the branch is not merged elsewhere

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

git prunedoes something different, it purges unreachable objects, those commits that aren't reachable in any branch or tag, and thus not needed anymore.

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

回答by D.Mill

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. A word of caution: This will get rid of any branch that isn't tracked remotely regardless of whether it was merged or not.

如果有人感兴趣的话。这是一个快速的 shell 脚本,它将删除所有未远程跟踪的本地分支。警告:这将摆脱任何未远程跟踪的分支,无论是否合并。

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 PATHand run:

将它保存在一个名为git-rm-ntb(随便命名)的文件中PATH并运行:

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

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 }' | grep 'refs/heads/' | sed 's:refs/heads/::'))
    RBRANCHES=("${CURRBRANCHES[@]}" "${RBRANCHES[@]}")
  done < <(echo "$REMOTES" )
  [[ $RBRANCHES ]] || exit
  LBRANCHES=($(git branch | sed 's:\*::' | awk '{print }'))
  for i in "${LBRANCHES[@]}"; do
    skip=
    for j in "${RBRANCHES[@]}"; do
      [[ $i == $j ]] && { skip=1; echo -e "3[32m Keeping $i 3[0m"; break; }
    done
    [[ -n $skip ]] || { echo -e "3[31m $(git branch -D $i) 3[0m"; }
  done
}

clean $@

回答by VonC

Note that one difference between git remote --pruneand git fetch --pruneis 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)(对于 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"**, fetchwould fail to remove "frotz/nitfol" with a "git fetch --prune" from the upstream.
git would inform the user to use "git remote prune" to fix the problem.

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

So: when a upstream repohas a branch ("frotz") with the same name as a branch hierarchy("frotz/xxx", a possible branch naming convention), git remote --prunewas succeeding (in cleaning up the remote tracking branch from your repo), but git fetch --prunewas 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.
This way, instead of warning the user of a conflict, it automatically fixes it.

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