如何获取所有的Git分支?

2285

我克隆了一个包含许多分支的Git代码库。然而,git branch 只显示了一个分支:

$ git branch
* master

如何在本地拉取所有分支,使得执行git branch命令时显示以下结果?

$ git branch
* master
* staging
* etc...

3
这个问题展示了如何在使用--single-branch克隆设置后获取所有分支:https://dev59.com/e2Mm5IYBdhLWcg3wT9mU(如果您只指定了一个分支,则`git fetch --all`永远不会起作用!) - Matthew Wilcoxson
3
您将永远看不到那个输出,因为星号代表当前所选的分支。由于一次只能有一个分支被选中,因此您的分支列表左侧只能有一个星号。 - Robino
1
下面排名最高的答案没能满足提问者的意图。我建议您查看 https://dev59.com/YXVD5IYBdhLWcg3wKYP-#72156。`git checkout -b <branch>` 看起来是最可能的答案。 - Reece
9
我看到了很多答案,但没有一个提到我认为可能是实现你想要的最简单方式:git clone --bare <repo url> .git (请注意,在克隆存储库时需要添加“--bare”和“.git”作为“bare”存储库),然后运行git config --bool core.bare false(将“bare”标志设置为false),接着执行git reset --hard(将HEAD移动到存储库的当前HEAD)。现在,如果你运行git branch,你应该能够看到从所克隆的存储库中获取的所有分支。 - Gabriel Ferraz
6
那么你正在滥用 Stack Overflow 上的评论功能。用户可以给你的评论点赞,但不能踩。 - pipe
显示剩余5条评论
35个回答

3020

简短回答

git branch -r | grep -v '\->' | sed "s,\x1B\[[0-9;]*[a-zA-Z],,g" | while read remote; do git branch --track "${remote#origin/}" "$remote"; done
git fetch --all
git pull --all

看起来pull会从所有远程仓库获取所有分支,但我总是先fetch以确保。

只有在服务器上存在本地分支未跟踪的远程分支时才运行第一个命令。

完整答案

你可以这样从所有远程仓库获取所有分支:

git fetch --all

这基本上是一种权力行动

fetch会更新远程分支的本地副本,因此对于您的本地分支来说总是安全的,但是

  1. fetch不会更新本地跟踪远程分支的分支;如果要更新本地分支,仍然需要拉取每个分支。

  2. fetch不会创建本地跟踪远程分支的分支,您需要手动执行此操作。如果要列出所有远程分支: git branch -a

更新跟踪远程分支的本地分支:

git pull --all

然而,这可能仍然不足够。它只适用于跟踪远程分支的本地分支。要跟踪所有远程分支,请在git pull --all之前执行此单行命令:
git branch -r | grep -v '\->' | sed "s,\x1B\[[0-9;]*[a-zA-Z],,g" | while read remote; do git branch --track "${remote#origin/}" "$remote"; done

顺便提一句,据我所知,git fetch --allgit remote update 是等价的。



Kamil Szot的comment,人们发现它很有用。

I had to use:

for remote in `git branch -r`; do git branch --track ${remote#origin/} $remote; done

because your code created local branches named origin/branchname and I was getting "refname 'origin/branchname' is ambiguous whenever I referred to it.


50
抱歉,我无法想象这是否是原帖作者真正想要的。'pull' 命令实际上是 'fetch+merge',合并部分会将所有分支叠加在一起,留下一个巨大的混乱。 - GoZoner
13
那个获取操作不会创建一个新的远程分支,你仍然需要使用 git checkout -b localname remotename/remotebranch 命令将其检出到本地分支。 - Learath2
145
我不得不使用 for remote in \git branch -r`; do git branch --track ${remote#origin/} $remote; done`,因为你的代码创建了名为 origin/branchname 的本地分支,每当我引用它时都会出现“refname 'origin/branchname' is ambiguous”的错误提示。 - Kamil Szot
24
我不确定我是否在使用不同版本的GIT,但是我必须修改脚本为 git pull --all; for remote in \git branch -r | grep -v >`; do git branch --track ${remote#origin/} $remote; done`。这个改动去掉了HEAD。 - kim3er
19
针对Windows用户:for /F %remote in ('git branch -r') do ( git branch --track %remote) && git fetch --all && git pull --all的意思是,在命令行窗口中执行该命令,它会获取远程存储库中所有分支的信息,并在本地创建相应的跟踪分支。然后,它会从远程存储库获取所有变更并将其合并到本地存储库中。 - Max
显示剩余35条评论

1209
列出远程分支:

要列出远程分支:

git branch -r

将远程分支检出为本地分支:

git checkout -b local_branch_name origin/remote_branch_name

153
当我发现上面的问题时,这正是我所寻找的内容。我怀疑很多人在寻找如何拉取远程分支时,肯定不想将该分支合并到他们当前的工作副本中,但他们确实想要一个与远程分支完全相同的本地分支。 - Frug
31
即使本地看不到该分支,我也可以使用 git checkout remotebranchname 命令,并成功切换到该分支。那么这种方法和你提供的解决方案有什么不同呢? - François Romain
26
现在这是默认的行为,但在旧版的git中不是这样。使用git checkout remotebranchname以前只会创建一个名为_remotebranchname_的无关分支。 - Learath2
19
被接受的答案做了一些根本不同的事情,坦率地说,我甚至不理解为什么它被接受为答案。 - Learath2
21
OP要求所有分支,而这个答案只涉及一个。 - Ted Bigham
显示剩余10条评论

222

您需要创建本地分支来跟踪远程分支。

假设您只有一个名为 origin 的远程仓库,以下代码片段将会为所有远程跟踪分支创建本地分支:

```bash git branch -r | awk '{print $1}' | grep -v HEAD | while read remote; do git branch --track "${remote#origin/}" "$remote"; done ```
for b in `git branch -r | grep -v -- '->'`; do git branch --track ${b##origin/} $b; done

之后,git fetch --all 将更新所有远程分支的本地副本。

此外,git pull --all 将更新您的本地跟踪分支,但根据您的本地提交以及如何设置“合并”配置选项,它可能会创建一个合并提交、快进或失败。


6
这样做可以使解决方案更加稳健,防止分支名称包含 shell 特殊字符(根据 pinkeen 在其他答案中的评论),并避免出现错误输出:git branch -r | grep -v -- ' -> ' | while read remote; do git branch --track "${remote#origin/}" "$remote" 2>&1 | grep -v ' already exists'; done。 - Daira Hopwood
11
你确定 git pull --all 命令会更新所有本地跟踪分支吗?据我所知,它只会从所有远程仓库更新当前分支。 - Andy
4
这样做了。未创建与远程分支匹配的本地分支。请问有哪个git命令可以简单地说“拉取所有远程分支,如果不存在则创建本地分支”? - JosephK
@JosephK 或许你的远程仓库不叫做 origin?请参考这个答案,它适用于所有远程仓库名称。 - Tom Hale
@TomHale,原本是“origin”,但还是谢谢你的回答——不过有些疯狂,需要这么多步骤来完成本应只需一两个标志的操作。我现在正在尝试gitless,以避免Git某些方面的疯狂。 - JosephK

161
如果你这样做:
git fetch origin

然后它们都将在本地。如果你执行:

git branch -a

你会看到它们被列为remotes/origin/branch-name。既然它们在本地,你可以随意对它们进行操作。例如:

git diff origin/branch-name 
或者
git merge origin/branch-name
或者
git checkout -b some-branch origin/branch-name

5
刚在谷歌上找到了这个页面...这正是我正在寻找的答案类型。我尝试了第一个命令,但收到了一个错误: [$ git fetch --all origin fatal: fetch --all does not take a repository argument] ---使用"git fetch --all"似乎就解决了问题。感谢你提供的线索! - longda
20
git fetch -all 命令会获取所有远程仓库的所有分支。git fetch origin 命令则只会获取远程仓库 origin 的所有分支。后者是 OP 所询问的内容。 - GoZoner
6
"--all" 表示“所有远程仓库”,而不是“给定远程仓库的所有分支”。后者可以通过从远程仓库获取任何内容来隐含表示。 - spacediver
1
OP要求的是使“branch”变为可用,而不是“branch -a”。 - Ted Bigham
3
这不是从远程仓库拉取所有分支到本地仓库的方法。 - Vladimir Despotovic
显示剩余3条评论

127
$ git remote update
$ git pull --all

这假设所有的分支都被跟踪。
如果它们没有被跟踪,你可以在Bash中执行以下命令:
for remote in `git branch -r `; do git branch --track $remote; done

然后运行命令。
注意:请留意下方的警告(所有远程仓库将跟踪相同的本地分支main)。

4
当我尝试这样做时,我仍然得到与上面相同的结果。 - David542
4
和@JacobLowe一样,我也遇到了错误,但是它仍然能够运行;“fatal: A branch named 'origin/master' already exists.” - AnneTheAgile
4
此外,它不起作用。我的输出是:Branch 'origin/quote-filenames' set up to track local branch 'master'。期望的输出是:分支'quote-filenames'已设置为跟踪来自'origin'的远程分支'quote-filenames'。这是反向的,将本地分支设为跟踪远程分支的来源。请参阅此答案以获取修复方法。 - Tom Hale
1
一个小改进,以排除HEAD分支上的错误:for REMOTE in git branch -r | grep -v HEAD; do git branch --track ${REMOTE}; done - Antonio Petricca
1
追踪远程分支的命令根本不起作用。它创建了一堆指向最后一个主分支提交的分支。 - Thomas Glaser
显示剩余5条评论

101

Bash的for循环对我不起作用,但这正是我想要的。我的起源中的所有分支都被镜像为相同的本地名称。

git checkout --detach
git fetch origin '+refs/heads/*:refs/heads/*'

请参见Mike DuPont在下面的评论。我认为我试图在Jenkins服务器上执行此操作,这会使其处于分离的头状态。


6
简化版:克隆后出现“fatal: Refusing to fetch into current branch refs/heads/master of non-bare repository”,需要先分离HEAD。使用“git checkout <SHA>”命令可以实现此操作。 - brannerchinese
8
我的解决方案是使用以下命令:"git checkout --detach"(分离HEAD),然后再运行 "git fetch origin '+refs/heads/:refs/heads/'"。 - Mike DuPont
1
这个对我有用,除了我还使用了--tags参数。我希望有一个标准的、简单的git前端,因为在git中需要10多个堆栈溢出答案的简单事情太荒谬了! - kristianp
1
@kristianp 你有试用过Ungit或GitKraken吗? - dragon788
1
@Pegues 我认为很多混淆都存在于跟踪的工作方式以及其在更新本地存储库中的作用上。你完全正确,这篇文章中的命令确实会执行获取操作,但如果你没有跟踪分支,它就不会获取它们。我想我的评论更适合初学者。此外,你提到的更新分支的方法是100%合法的,但也有其他方法可以做到^^ - basickarl
显示剩余8条评论

60

使用git fetch && git checkout RemoteBranchName

对我来说非常有效...


6
这是最新的最佳答案。我不知道之前是否可能实现,但至少Git的最近版本会注意到您正在尝试检出远程分支,并自动为您设置本地跟踪分支(您不需要指定 origin/branch;只需说 branch 就足够了)。 - Neil Traft
14
这并没有回答原始问题:“如何将所有分支拉到本地?”这是逐个拉取它们,这不可扩展。 - ingyhere
2
这是唯一一个让我在遇到的每种情况下都能拉取远程分支的答案。 - Emmanuel Buckshi

48

当您克隆存储库时,所有分支的信息都会被下载,但这些分支是隐藏的。通过使用命令

$ git branch -a

您可以展示所有存储库的分支,在命令中使用

$ git checkout -b branchname origin/branchname

您可以手动逐个“下载”它们。


但是,其实有一种更加简洁快速的方法,虽然有点复杂。您需要完成三个步骤:

  1. 第一步

    在您的电脑上创建一个新的空文件夹,并克隆存储库中.git文件夹的镜像副本:

$ cd ~/Desktop && mkdir my_repo_folder && cd my_repo_folder
$ git clone --mirror https://github.com/planetoftheweb/responsivebootstrap.git .git

my_repo_folder 文件夹内的本地仓库仍然是空的,现在只有一个隐藏的 .git 文件夹,您可以通过终端的 "ls -alt" 命令看到。

  • 第二步

    通过将 git 配置中的布尔值 "bare" 切换为 false,将此存储库从空(裸)存储库切换为常规存储库:

  • $ git config --bool core.bare false
    
  • 第三步

    获取当前文件夹中的所有内容,并在本地计算机上创建所有分支,从而使其成为普通仓库。

  • $ git reset --hard
    

    现在你只需输入命令git branch,就可以看到所有分支已下载。

    这是一种快速的方式,可以一次克隆包含所有分支的 git 仓库,但并不适用于每个项目。


    1
    因为提到了隐藏分支,我点了个赞。这帮助我极大地理解了本地分支跟踪。 - mburke05
    这是一个很好的答案,但问题暗示了每天使用的东西。每次克隆存储库都不切实际。 - Bernardo Dal Corno
    为什么重置会在本地创建所有分支? - Bernardo Dal Corno
    @Z.Khullah,不是重置操作创建了所有的分支,而是克隆--mirror。不幸的是,这也会创建一个裸仓库,这就是步骤2和3要更改的内容。 - ScottJ

    42
    您可以通过以下方式获取所有分支:

    git fetch --all

    git fetch --all
    

    或者:

    git fetch origin --depth=10000 $(git ls-remote -h -t origin)
    
    --depth=10000 参数可以帮助您拉取浅层仓库的内容。
    要拉取所有分支,请使用:
    git pull --all
    

    如果以上方法无效,则在上述命令前加上以下内容:
    git config remote.origin.fetch '+refs/heads/*:refs/remotes/origin/*'
    

    由于remote.origin.fetch只能在获取时支持特定的分支,尤其是当您使用--single-branch克隆仓库时,请检查此设置:git config remote.origin.fetch

    之后,您就可以检出任何分支了。

    另请参阅:


    要将所有分支推送到远程,请使用以下命令:

    git push --all
    

    最终使用 --mirror 命令以镜像所有引用。


    如果您的目标是复制存储库,请参阅 GitHub 上的复制存储库文章。


    1
    太棒了!在尝试过这页上所有其他的解决方案之后,你的解决方案终于让我成功了。非常感谢! - Sujoy
    2
    我使用了浅克隆(depth=1),配置中还指定了一个特定的分支用于fetch - depth=1000参数是帮助我检出特定远程分支的修复方法。 - Sandra
    2
    pull --all 不会拉取所有分支,而是拉取所有远程分支。 - Bernardo Dal Corno
    不错的配置技巧!虽然会一次性获取所有数据。 - Bernardo Dal Corno
    我按照你写的检查了配置,但仍然只能在当前分支上工作。看起来这里所有的答案都对我无效... - Alex Martian

    32
    我通常只使用这样的命令:

    我通常只使用这样的命令:

    git fetch origin
    git checkout --track origin/remote-branch
    

    简短版本:

    git fetch origin
    git checkout -t origin/remote-branch
    

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