如何在Git中停止追踪远程分支?

787

如何在Git中停止追踪一个远程分支?

我想要停止追踪是因为在我的具体情况下,我想要删除本地分支,但不删除远程分支。如果删除了本地分支并将其推送到远程,则会同时删除远程分支:

我可以只运行git branch -d the_branch吗?那样会在我稍后执行git push时被传播吗?

只有当我稍后运行git push origin :the_branch时才会传播吗?

11个回答

1094

Yoshua Wuyts 在他的回答中所提到,使用 git branch 命令:

git branch --unset-upstream

其他选项:

您不必删除本地分支。

只需删除跟踪远程分支的本地分支:

git branch -d -r origin/<remote branch name>

-r, --remotes参数告诉git删除远程跟踪分支(即删除设置为跟踪远程分支的分支)。这个操作不会删除远程仓库上的分支!

详见"Having a hard time understanding git-fetch"

本地跟踪分支并不存在,只有远程跟踪分支。
因此,origin/masterorigin仓库中master分支的远程跟踪分支。

Dobes Vandermeer回答中所述,你还需要重置与本地分支相关联的配置。

git config --unset branch.<branch>.remote
git config --unset branch.<branch>.merge

移除 <branchname> 的上游信息。
如果没有指定分支,则默认为当前分支。

(git 1.8+,2012年10月,提交记录 b84869eCarlos Martín Nieto (carlosmn) 提交)

这将使任何 push/pull 完全不知道 origin/<remote branch name> 存在。


10
git fetch之后,远程跟踪分支会被重新创建。是否有可能排除这些分支? - Matt R
1
@Matt:我认为可以通过设置remote.<name>.fetch refspec配置来完成,但我不确定在指定refspec时是否可以排除一个分支。 - VonC
9
这是完全正常的:git branch -d -r origin/<远程分支名称>将删除在你的本地仓库中声明的远程跟踪分支。它不会删除远程仓库本身上的该分支(只有git push :development才能做到这一点)。因此,当你推送具有与远程开发分支(在远程仓库上)不同历史记录的本地development时,仍会收到“非快进”的警告。 - VonC
1
@Marco 是的,但我还是更喜欢这样做,我觉得这样更加“干净”。 - VonC
2
@GabrielStaples 我同意。有关远程跟踪的更多信息:https://stackoverflow.com/a/44081446/6309,https://stackoverflow.com/a/38202006/6309和https://dev59.com/t4fca4cB1Zd3GeqPkZDJ#28341622。 - VonC
显示剩余10条评论

278

要删除当前分支的上游,请执行以下操作:

$ git branch --unset-upstream

此功能适用于Git v.1.8.0或更高版本。(来源:1.7.9 ref1.8.0 ref

来源


13
如果你不想删除当前分支,只需输入以下命令: git branch --unset-upstream [branchname]。请注意,这个命令不会改变你的当前分支。 - Sonata
当然可以,如果你找到了答案,请随时回复,我会很乐意更新评论。 - Yoshua Wuyts
在执行了这个操作并尝试 git pull origin/master 后,我收到了“致命错误:'origin/master' 似乎不是一个 Git 存储库 致命错误:无法从远程存储库读取。”的提示。 - information_interchange
如果您想轻松查看正在跟踪的远程分支,请使用 git branch -vv - Daniel
@information_interchange 你应该执行 git pull origin master (两者之间有空格,而不是/)。git-fetch 和 git-pull 都需要一个 URL(或其别名,例如 origin)和一个分支(例如 master)。另一方面,git-log 和 git-branch 只需要一个分支,即 origin/master、other_remote_repo/develop 或者 my_local_branch。 - StephenM

112

要删除本地分支和远程分支之间的关联,请运行以下命令:

git config --unset branch.<local-branch-name>.remote
git config --unset branch.<local-branch-name>.merge

如果不需要该本地分支,可以选择在此之后删除它:

git branch -d <branch>

这不会删除远程分支。


11
删除分支的关联并不需要使用git branch -d <branch>命令。 - Marco
1
我正在使用JIRA。当我再次拉取分支时,该分支会出现。我该如何防止这种情况发生? - powder366
1
@Marco 正确,但如果您使用 git branch -vv,在执行 git branch -d <branch> 命令之前仍将看到旧分支。 - Seldom 'Where's Monica' Needy
1
@SeldomNeedy 我认为你可能没有理解分布式版本控制系统的重点?关键在于我可以有一个跟踪上游分支的分支,但是我可以将其分离以追求上游分支未使用的方法。在这种情况下,该分支既不是“旧的”(因为我仍在开发它),也不是“废弃的”(因为我正在使用它)。这是分布式版本控制系统设计的重要部分。明白了吗? - Marco
git branch -d不会删除远程跟踪分支(在git loggit br -a中显示的origin/blah)。VonC的回答中有你需要的-r标志。 - undefined
显示剩余3条评论

43

最简单的方法是编辑.git/config文件。

以下是一个示例文件。

[core]
        repositoryformatversion = 0
        filemode = true
        bare = false
        logallrefupdates = true
        ignorecase = true
[remote "origin"]
        url = git@example.com:repo-name
        fetch = +refs/heads/*:refs/remotes/origin/*
[branch "test1"]
        remote = origin
        merge = refs/heads/test1
[branch "master"]
        remote = origin
        merge = refs/heads/master

test1 分支部分删除行 merge = refs/heads/test1


5
我不能确定这是最简单的方法,但对我来说确实是最容易理解(因此希望也更容易记住)!+1 - sage
不错的解决方案 +1。这实际上是跟踪注册的地方,易于更改,清晰明了它的作用。命令行 .git/config 也可用。 - hakre
5
这与Dobes Vandermeer提出的“git config --unset”解决方案相同。 "git config"编辑此文件。 - J.Z.
在我的情况下,我不确定是否有人会遇到同样的问题。我设置了新的远程分支跟踪默认值,并且临时切换到了第二个远程,该远程与我的正常ssh远程不同,因为我当时在飞机上,ssh无法使用。它自动设置了远程,然后当我不在飞机上时,我删除了该分支,但是我无法再次检出它,因为它说有两个远程跟踪分支。最终,我只能删除该远程,直到下一次需要使用。 - nroose

22

本地跟踪分支

如果你正在谈论配置为向上游[远程分支] pushpull 的本地分支(例如maindev),那么你可以通过以下方式禁用它:

❯ git branch --unset-upstream <LOCALBRANCH>

E.g.:

❯ git branch --unset-upstream dev
❯ git branch --unset-upstream feature-x

远程跟踪分支

如果你在谈论一个名为 <REMOTE>/<BRANCH> 的分支(例如 origin/mainorigin/dev),它会出现在你的 git log 以及 .git/refs/remotes/<REMOTE>/ 目录中,显示远程分支的状态,那么你可以通过覆盖当前持有的远程跟踪分支列表来停止跟踪它(更新它)并创建新的自定义列表:

❯ git remote set-branches <REMOTE> [<REMOTE-BRANCH> …]

如果你不想在git log(以及.git/refs/remotes/<REMOTE>/目录)中再看到那些远程跟踪分支,那么你可以使用以下命令将它们删除:

❯ git branch --delete --remotes -- <REMOTE>/<BRANCH>
Deleted remote-tracking branch <REMOTE>/<BRANCH> (was 1f1a655).

E.g.:

# keep tracking `origin/main`, and `origin/dev`,
# untrack all other `origin/*` remote branches
❯ git remote set-branches origin main dev

# delete remote branches previously tracked, from the
# `.git/refs/remotes/<REMOTE>/` directory
❯ git branch --delete --remotes -- origin/feature-x origin/feature-y
❯ git branch --delete --remotes -- origin/hotfix-z

过期的远程分支

最后,如果有一些远程分支已经从远程仓库中删除(变成了过期状态),而你又想要更新本地仓库以反映这种变化,那么你可以通过删除(修剪)它们来实现:

# automatically
❯ git remote prune <REMOTE>
Pruning <REMOTE>
URL: <REMOTEURL>
 * [pruned] <REMOTE>/<BRANCH>

...or

# manually
❯ git branch --delete --remotes -- <REMOTE>/<BRANCH>
Deleted remote-tracking branch <REMOTE>/<BRANCH> (was 1f1a655).

PS

您可以使用以下方式检查跟踪状态:

❯ git remote show <REMOTE>

E.g.:

❯ git remote show origin
* remote origin
  Fetch URL: /Users/johndoe/bare-remote
  Push  URL: /Users/johndoe/bare-remote
  HEAD branch: ant
  Remote branches:
    brooms  tracked
    bull    tracked
    cat     tracked
    deer    tracked
    dog     tracked
    foxy    tracked
    john    tracked
    master  tracked
    new     tracked
    tim     tracked
    timothy tracked
  Local branches configured for 'git pull':
    ant    merges with remote ant
    master merges with remote master
  Local refs configured for 'git push':
    ant    pushes to ant    (up to date)
    master pushes to master (up to date)

  • git-remote(1):

    set-branches: 更改名为的远程仓库所跟踪的分支列表。这可以用于在远程的初始设置之后跟踪可用远程分支的子集。

    prune: 删除与关联的陈旧引用。默认情况下,会删除下的陈旧远程跟踪分支,但是根据全局配置和远程配置,我们甚至可能会删除尚未推送到此处的本地标记。

    show: 提供有关远程的一些信息。

  • git-branch(1):

    --unset-upstream: 删除的上游信息。

    --delete: 删除一个分支。

    --remotes: 列出或删除(如果与-d一起使用)远程跟踪分支。


有没有一种批量删除远程分支的方法?在我的情况下,这些分支不是过时的,而是远程本身已经过时了。对于每个分支执行 git branch --delete --remotes -- staleremote/hotfix 是很繁琐的。 - Mark Jeronimus
截至2023年8月,这是最干净的答案。 - maoizm

18
您可以使用以下命令删除远程跟踪分支:
git branch -d -r origin/<remote branch name>
如VonC所述,但如果您保留了分支的本地副本,则git push 仍将尝试推送该分支(这可能会导致非快进错误,就像ruffin一样)。这是因为配置文件push.default默认为matching,这意味着:

匹配-推送所有匹配的分支。在两端具有相同名称的所有分支都被视为匹配。这是默认值。

(参见push.default下的http://git-scm.com/docs/git-config
考虑到当您删除远程跟踪分支时这可能不是您想要的结果,您可以将push.default设置为upstream(如果您使用的是git < 1.7.4.3,则为tracking)。

上游-将当前分支推送到其上游分支。

使用
git config push.default upstream

并且 Git 将停止尝试推送您已“停止跟踪”的分支。

注意:更简单的解决方案是将本地分支重命名为其他名称。这也可以消除一些混淆的可能性。


4
这里有一行命令可以删除所有与模式匹配的远程跟踪分支: git branch -rd $(git branch -a | grep '{pattern}' | cut -d'/' -f2-10 | xargs) 请注意,此命令保留HTML标记。

如果只想取消跟踪(删除)远程跟踪分支,那么我认为这是更短的一行替代命令:git branch -r -D $(git branch -r | grep -v "master") - dma_k

1
这不是对问题的回答,但我无法弄清如何在上面的评论中获得良好的代码格式...所以不管自动降低声望,这是我的评论。
我在我的.gitconfig文件中使用@Dobes提交的配方作为一个花哨的[alias]条目:
# to untrack a local branch when I can't remember 'git config --unset'
cbr = "!f(){ git symbolic-ref -q HEAD 2>/dev/null | sed -e 's|refs/heads/||'; }; f"
bruntrack = "!f(){ br=${1:-`git cbr`};  \
    rm=`git config --get branch.$br.remote`; \
    tr=`git config --get branch.$br.merge`; \
    [ $rm:$tr = : ] && echo \"# untrack: not a tracking branch: $br\" && return 1; \
    git config --unset branch.$br.remote; git config --unset branch.$br.merge; \
    echo \"# untrack: branch $br no longer tracking $rm:$tr\"; return 0; }; f"

然后我只需运行。
$ git bruntrack branchname

1
+1。除了我上面的回答之外,这是一个很好的别名。 - VonC

0

最简单的方法是远程删除分支,然后使用:

git fetch --prune(又称 git fetch -p)


14
我感到困惑,原帖作者并不想删除远程分支。 - madth3
清理本地仓库中已从远程裸仓库删除的跟踪远程分支是一个好习惯。 - Marek Podyma
--prune:在获取之前,删除远程不存在的任何远程跟踪引用。虽然不是对原始问题的答案,但解决了我的变体:“如何停止跟踪Git中不再存在于远程的远程分支。” - nuala

-1

git branch --unset-upstream 停止跟踪所有本地分支,这是不可取的。

.git/config 文件中删除 [branch "branch-name"] 部分,然后执行

git branch -D 'branch-name' && git branch -D -r 'origin/branch-name'

对我来说是最好的选择。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接