关于GitHub:如何克隆Git中的所有远程分支?

How to clone all remote branches in Git?

我有一个master和一个development分支,都被推到了github。我有cloned、pulled和fetched,但除了master分支,我还是找不到别的东西。

我肯定我遗漏了一些明显的东西,但我已经阅读了手册,我一点也不高兴。


首先,克隆一个远程Git存储库和CD:

1
2
$ git clone git://example.com/myproject
$ cd myproject

接下来,查看存储库中的本地分支:

1
2
$ git branch
* master

但在您的存储库中还隐藏着其他分支!使用-a标志可以看到这些:

1
2
3
4
5
6
$ git branch -a
* master
  remotes/origin/HEAD
  remotes/origin/master
  remotes/origin/v1.0-stable
  remotes/origin/experimental

如果您只想快速浏览上游分支,可以直接查看:

1
$ git checkout origin/experimental

但是,如果您想在该分支上工作,则需要创建一个本地跟踪分支,该分支自动通过以下方式完成:

1
$ git checkout experimental

你会看到

1
2
Branch experimental set up to track remote branch experimental from origin.
Switched to a new branch 'experimental'

最后一句话让一些人觉得:"新的分支"—嗯?它真正意味着分支是从索引中提取的,并在本地为您创建的。上一行实际上提供了更多信息,因为它告诉您正在设置分支以跟踪远程分支,这通常意味着源/分支名称分支

现在,如果你看看当地的分支机构,你会发现:

1
2
3
$ git branch
* experimental
  master

实际上,您可以使用git remote跟踪多个远程存储库。

1
2
3
4
5
6
7
8
9
$ git remote add win32 git://example.com/users/joe/myproject-win32-port
$ git branch -a
* master
  remotes/origin/HEAD
  remotes/origin/master
  remotes/origin/v1.0-stable
  remotes/origin/experimental
  remotes/win32/master
  remotes/win32/new-widgets

此时,事情变得非常疯狂,所以运行gitk查看发生了什么:

1
$ gitk --all &


如果有许多远程分支要一次提取,请执行以下操作:

1
$ git pull --all

现在,您可以根据需要签出任何分支,而无需点击远程存储库。


这个bash脚本帮助我:

1
2
3
4
#!/bin/bash
for branch in $(git branch --all | grep '^\s*remotes' | egrep --invert-match '(:?HEAD|master)$'); do
    git branch --track"${branch##*/}""$branch"
done

它将为所有远程分支创建跟踪分支,但master(您可能从原始克隆命令中获得)除外。我想你还是需要做一个

1
2
git fetch --all
git pull --all

当然可以。

One liner: git branch -a | grep -v HEAD | perl -ne 'chomp($_); s|^\*?\s*||; if (m|(.+)/(.+)| && not $d{$2}) {print qq(git branch --track $2 $1/$2
)} else {$d{$_}=1}' | csh -xfs
As usual: test in your setup before copying rm -rf universe as we know it

Credits for one-liner go to user cfi


使用--mirror选项似乎可以正确复制remote跟踪分支。但是,它将存储库设置为一个空的存储库,因此您必须在之后将其转换回正常的存储库。

1
2
3
4
git clone --mirror path/to/original path/to/dest/.git
cd path/to/dest
git config --bool core.bare false
git checkout anybranch

参考:Git常见问题解答:如何使用所有远程跟踪的分支克隆存储库?


您可以轻松地切换到分支,而无需使用花哨的"git checkout-b somebranch origin/somebranch"语法。你只需做:

1
git checkout somebranch

Git会自动做正确的事情:

1
2
3
$ git checkout somebranch
Branch somebranch set up to track remote branch somebranch from origin.
Switched to a new branch 'somebranch'

Git将检查一个远程中是否存在同名的分支,如果存在,它将以与您明确指定它是远程分支相同的方式跟踪它。从git 1.8.2.1的git checkout手册页:

If is not found but there does exist a tracking branch in
exactly one remote (call it ) with a matching name, treat as
equivalent to

1
$ git checkout -b <branch> --track <remote>/<branch>


关于,

$ git checkout -b experimental origin/experimental

使用

1
$ git checkout -t origin/experimental

或者更详细但更容易记住

1
$ git checkout --track origin/experimental

在跟踪远程存储库方面可能会更好。


您正在执行的提取应该获取所有远程分支,但它不会为它们创建本地分支。如果您使用gitk,那么应该看到描述为"remotes/origin/dev"的远程分支或类似的分支。

要基于远程分支创建本地分支,请执行以下操作:

1
git checkout -b dev refs/remotes/origin/dev

它应该返回如下内容:

1
2
Branch dev set up to track remote branch refs/remotes/origin/dev.
Switched to a new branch"dev"

现在,当您在dev分支上时,"git pull"将把本地dev更新到与远程dev分支相同的点。注意,它会把所有的树枝都拔出来,但只会把你的树枝拉到树顶上。


当您执行"git clone git://location"时,将提取所有分支和标记。

为了在特定远程分支上工作,假设它是源站远程分支:

1
git checkout -b branch origin/branchname


使用别名。虽然没有任何本地的git-one行程序,但是您可以将自己的定义为

1
git config --global alias.clone-branches '! git branch -a | sed -n"/\/HEAD /d; /\/master$/d; /remotes/p;" | xargs -L1 git checkout -t'

然后将其用作

1
git clone-branches


这并不是太复杂,非常简单直接的步骤如下:

git fetch origin这将把所有的远程分支带到本地。

git branch -a这将显示所有远程分支。

git checkout --track origin/

通过以下命令验证您是否在所需的分支中;

1
git branch

输出将像这样;

1
2
3
*your current branch
some branch2
some branch3

注意表示当前分支的*符号。


迟做总比不做好,但最好的方法是:

1
2
3
4
5
mkdir repo
cd repo
git clone --bare path/to/repo.git .git
git config --unset core.bare
git reset --hard

此时,您已经拥有远程回购及其所有分支的完整副本(使用git branch进行验证)。如果远程回购有自己的远程设备,则可以使用--mirror而不是--bare


为什么你只看到"大师"

git clone下载所有远程分支,但仍然认为它们是"远程的",即使这些文件位于新的存储库中。有一个例外,那就是克隆过程从名为"master"的远程分支创建一个名为"master"的本地分支。默认情况下,git branch只显示本地分支,所以您只能看到"master"。

git branch -a显示所有分支,包括远程分支。

如何获取本地分支机构

如果你真的想在一个分支上工作,你可能需要它的"本地"版本。要简单地从远程分支创建本地分支(不签出它们,从而更改工作目录的内容),可以这样做:

1
2
3
git branch branchone origin/branchone
git branch branchtwo origin/branchtwo
git branch branchthree origin/branchthree

在本例中,branchone是基于origin/branchone创建的本地分支的名称;如果您希望创建具有不同名称的本地分支,可以这样做:

1
git branch localbranchname origin/branchone

创建本地分支后,您可以使用git branch查看它(记住,不需要-a查看本地分支)。


只要这样做:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ git clone git://example.com/myproject
$ cd myproject
$ git checkout branchxyz
Branch branchxyz set up to track remote branch branchxyz from origin.
Switched to a new branch 'branchxyz'
$ git pull
Already up-to-date.
$ git branch
* branchxyz
  master
$ git branch -a
* branchxyz
  master
  remotes/origin/HEAD -> origin/master
  remotes/origin/branchxyz
  remotes/origin/branch123

你看,'git clone git://example.com/myprojectt'获取所有东西,甚至是分支,你只需要签出它们,然后就可以创建本地分支。


您只需要使用"git clone"来获取所有分支。

1
git clone <your_http_url>

即使您只看到主分支,也可以使用"git branch-a"查看所有分支。

1
git branch -a

你可以切换到你已经拥有的任何分支。

1
git checkout <your_branch_name>

不用担心,在你"Git克隆"之后,你不需要连接远程回购,"Git分支-A"和"Git结算"可以在你关闭WiFi时成功运行。因此,事实证明,当您执行"git克隆"时,它已经从远程repo复制了所有分支。在那之后,你不需要远程回购,你的本地已经有了所有分行的代码。


一个git clone应该复制整个存储库。尝试克隆它,然后运行git branch -a。它应该列出所有的分支。如果您想切换到分支"foo"而不是"master",请使用git checkout foo


使用我的工具git_remote_branch(您的机器上需要安装Ruby)。它是专门为使远程分支操作变得简单而构建的。

每次它代表您执行操作时,都会在控制台上以红色打印它。随着时间的推移,它们最终会进入你的大脑:—)

如果您不希望GRB代表您运行命令,只需使用"解释"功能即可。命令将打印到控制台,而不是为您执行。

最后,所有命令都有别名,以便于记忆。

注意这是alpha软件;-)

以下是运行GRB帮助时的帮助:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
git_remote_branch version 0.2.6

  Usage:

  grb create branch_name [origin_server]

  grb publish branch_name [origin_server]

  grb rename branch_name [origin_server]

  grb delete branch_name [origin_server]

  grb track branch_name [origin_server]



  Notes:
  - If origin_server is not specified, the name 'origin' is assumed
    (git's default)
  - The rename functionality renames the current branch

  The explain meta-command: you can also prepend any command with the
keyword 'explain'. Instead of executing the command, git_remote_branch
will simply output the list of commands you need to run to accomplish
that goal.

  Example:
    grb explain create
    grb explain create my_branch github

  All commands also have aliases:
  create: create, new
  delete: delete, destroy, kill, remove, rm
  publish: publish, remotize
  rename: rename, rn, mv, move
  track: track, follow, grab, fetch


我在这里看到的所有答案都是有效的,但是有一种更干净的方法可以克隆存储库并同时提取所有分支。

克隆存储库时,实际下载了分支的所有信息,但分支是隐藏的。用命令

1
$ git branch -a

您可以显示存储库的所有分支,并使用命令

1
$ git checkout -b branchname origin/branchname

然后您可以一次手动"下载"一个。

然而,当你想克隆一个有很多分支的回购,上面所描述的所有方法都是冗长和冗长的,关于一个更清洁和更快的方式,我要展示,虽然有点复杂。您需要三个步骤来完成此操作:

  • 第一步
  • 在您的计算机上新建一个空文件夹,并从存储库克隆.git文件夹的镜像副本:

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

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

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

    1
    $ git config --bool core.bare false
  • 第三步
  • 抓取当前文件夹中的所有内容,并在本地计算机上创建所有分支,因此这是一个正常的repo。

    1
    $ git reset --hard

    现在您只需键入命令"git branch",就可以看到所有的分支都已下载。

    这是一种快速的方法,您可以用所有分支同时克隆Git存储库,但这不是您想用这种方法为每个项目做的事情。


    好吧,当你复制你的回购协议时,你所有的分支都在那里…

    如果你只做git branch,它们是隐藏的…

    因此,如果您想查看所有分支的名称,只需添加--all标记,如下所示:

    git branch --allgit branch -a

    如果你只是到分行结帐,你就可以得到你所需要的一切。

    但是,如果克隆后由其他人创建的分支呢?

    在这种情况下,只需执行以下操作:

    git fetch

    再次检查所有分支…

    如果您希望同时提取和签出,可以执行以下操作:

    git fetch && git checkout your_branch_name

    还为您创建了下面的图像,以简化我所说的内容:

    git branch --all to get all branches


    看一看这个问题的答案,我发现可以缩短它:

    1
    2
    3
    for branch in  `git branch -r | grep -v 'HEAD\|master'`; do  
     git branch --track ${branch##*/} $branch;
    done

    但是要小心,如果其中一个远程分支被命名为管理主机,它将不会被下载!

    多亏了大鱼的创意


    1
    2
    3
    4
    #!/bin/bash
    for branch in `git branch -a | grep remotes | grep -v HEAD | grep -v master `; do
       git branch --track ${branch#remotes/origin/} $branch
    done

    这些代码将把所有远程分支代码拉到本地repo。


    从本地回购进行克隆不适用于git clone&git fetch:许多分支/标记将保持未蚀刻状态。

    以获得具有所有分支和标记的克隆。

    1
    git clone --mirror git://example.com/myproject myproject-local-bare-repo.git

    要获得具有所有分支和标记但同时具有工作副本的克隆,请执行以下操作:

    1
    2
    3
    4
    5
    git clone --mirror git://example.com/myproject myproject/.git
    cd myproject
    git config --unset core.bare
    git config receive.denyCurrentBranch updateInstead
    git checkout master

    对于复制粘贴到命令行:

    1
    git checkout master ; remote=origin ; for brname in `git branch -r | grep $remote | grep -v master | grep -v HEAD | awk '{gsub(/^[^\/]+\//,"",$1); print $1}'`; do git branch -D $brname ; git checkout -b $brname $remote/$brname ; done ; git checkout master

    为了提高可读性:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    git checkout master ;
    remote=origin ;
    for brname in `
        git branch -r | grep $remote | grep -v master | grep -v HEAD
        | awk '{gsub(/^[^\/]+\//,"",$1); print $1}'
    `; do
        git branch -D $brname ;
        git checkout -b $brname $remote/$brname ;
    done ;
    git checkout master

    这将:

  • 签出master(以便删除我们所在的分支)
  • 选择要签出的远程(将其更改为您拥有的任何远程)
  • 循环访问除master和head之外的所有远程分支
  • 删除本地分支(以便我们可以签出强制更新的分支)
  • 从远程签出分支
  • 退房主人(为了它)
  • 根据VONC的回答。


    我也需要这样做。这是我的红宝石脚本。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    #!/usr/bin/env ruby

    local = []
    remote = {}

    # Prepare
    %x[git reset --hard HEAD]
    %x[git checkout master] # Makes sure that * is on master.
    %x[git branch -a].each_line do |line|
      line.strip!
      if /origin\//.match(line)
         remote[line.gsub(/origin\//, '')] = line
       else
         local << line
       end
    end
    # Update
    remote.each_pair do |loc, rem|
      next if local.include?(loc)
      %x[git checkout --track -b #{loc} #{rem}]
    end
    %x[git fetch]


    我编写了这个小的PowerShell函数,以便能够签出所有位于origin-remote上的Git分支。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Function git-GetAllRemoteBranches {
         iex"git branch -r"                       <# get all remote branches #> `
         | % { $_ -Match"origin\/(?'name'\S+)" }  <# select only names of the branches #> `
         | % { Out-Null; $matches['name'] }        <# write does names #>
    }


    Function git-CheckoutAllBranches {
        git-GetAllRemoteBranches `
            | % { iex"git checkout $_" }          <# execute ' git checkout <branch>' #>
    }

    在我的Git设置报告中可以找到更多的Git函数


    Git通常(未指定时)从一个或多个其他存储库中获取所有分支和/或标记(refs,请参阅:git ls-refs)以及完成其历史记录所需的对象。换句话说,它获取已经下载的对象可以访问的对象。看:git fetch到底做了什么?

    有时您可能有与当前分支/标签没有直接连接的分支/标签,因此在这种情况下,git pull --all/git fetch --all不会有帮助,但您可以通过以下方式列出它们:

    1
    git ls-remote -h -t origin

    并通过知道引用名称手动获取它们。

    因此,要把它们全部取走,请尝试:

    1
    git fetch origin --depth=10000 $(git ls-remote -h -t origin)

    如果您已经浅化了存储库,那么--depth=10000参数可能会有所帮助。

    然后再次检查所有分支:

    1
    git branch -avv

    如果上面没有帮助,您需要手动将丢失的分支添加到跟踪列表中(因为它们不知何故丢失了):

    1
    2
    3
    4
    $ git remote -v show origin
    ...
      Remote branches:
        master      tracked

    git remote set-branches如:

    1
    git remote set-branches --add origin missing_branch

    因此,在获取之后,它可能出现在remotes/origin下:

    1
    2
    3
    4
    5
    6
    7
    $ git remote -v show origin
    ...
      Remote branches:
        missing_branch new (next fetch will store in remotes/origin)
    $ git fetch
    From github.com:Foo/Bar
     * [new branch]      missing_branch -> origin/missing_branch

    故障排除

    如果您仍然不能得到除主分支以外的任何东西,请检查以下内容:

    • 仔细检查遥控器(git remote -v号),例如
      • 确认git config branch.master.remoteorigin
      • 检查origin是否通过:git remote show origin指向正确的URL(见本帖)。

    这些答案都没有切中要害,除了用户,没有人在正确的轨道上。

    我在将repo从一个服务器/系统移动到另一个服务器/系统时遇到问题。当我克隆repo时,它只为master创建了一个本地分支,所以当我推到新的远程时,只推了master分支。

    所以我发现这两种方法非常有用。希望他们能帮助别人。

    方法1:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    git clone --mirror OLD_REPO_URL
    cd new-cloned-project
    mkdir .git
    mv * .git
    git config --local --bool core.bare false
    git reset --hard HEAD
    git remote add newrepo NEW_REPO_URL
    git push --all newrepo
    git push --tags newrepo

    方法2:

    1
    2
    3
    4
    5
    6
    7
    git config --global alias.clone-branches '! git branch -a | sed -n"/\/HEAD /d; /\/master$/d; /remotes/p;" | xargs -L1 git checkout -t'
    git clone OLD_REPO_URL
    cd new-cloned-project
    git clone-branches
    git remote add newrepo NEW_REPO_URL
    git push --all newrepo
    git push --tags newrepo


    使用可以记住的命令

    我使用的是BitBucket,它是一个Atlassian的存储库托管服务。所以我试着去看他们的医生。这对我来说非常有效。通过以下简单和简短的命令,您可以签出远程分支。

    首先克隆存储库,然后更改为目标文件夹。最后,但不是最不重要的是取和签出:

    1
    2
    3
    git clone <repo> <destination_folder>
    cd <destination_folder>
    git fetch && git checkout <branch>

    就是这样。这里有一个更真实的例子:

    1
    2
    3
    git clone https://[email protected]/team/repository.git project_folder
    cd project_folder
    git fetch && git checkout develop

    您将在文档中找到有关命令的详细信息:克隆命令、提取命令、签出命令


    截至2017年初,本评论的答案有效:

    以东十一〔十二〕带着树枝下来给你。虽然这不会一次拉动所有分支,但您可以为每个分支单独执行此操作。


    这是另一个简短的一行命令为所有远程分支创建本地分支:

    1
    (git branch -r | sed -n '/->/!s#^  origin/##p' && echo master) | xargs -L1 git checkout

    如果已经创建了跟踪本地分支,那么它也可以正常工作。您可以在第一个git clone之后或以后的任何时间调用它。

    如果克隆后不需要签出master分支,请使用

    1
    git branch -r | sed -n '/->/!s#^  origin/##p'| xargs -L1 git checkout

    原来回购的git clone --mirror对此效果很好。

    1
    2
    3
    git clone --mirror /path/to/original.git
    git remote set-url origin /path/to/new-repo.git
    git push -u origin

    我将在这里添加我的2美分,因为我在这里试图找出如何删除本地删除的远程分支。起源不是我的,我不想再经历克隆一切的麻烦。

    这对我很有用:

    假设您需要在本地重新创建分支:

    1
    2
    3
    git checkout -b recreated-branch-name
    git branch -a (to list remote branches)
    git rebase remotes/remote-origin/recreated-branch-name

    因此,如果我从gituser/master分支到sjp,然后将其分支到sjp/mynewbranch,它将如下所示:

    1
    2
    3
    4
    5
    6
    7
    $ git checkout -b mynewbranch
    $ git branch -a
      master
      remotes/sjp/master
      remotes/sjp/mynewbranch
    $ git fetch (habit to always do before)
    $ git rebase remotes/sjp/mynewbranch

    这种变体将克隆一个远程repo,所有分支都在本地可用,而不必逐个签出每个分支。不需要花哨的剧本。

    创建一个与要克隆和CD的repo同名的文件夹,例如:

    1
    2
    mkdir somerepo
    cd somerepo

    现在执行这些命令,但使用实际的repo usersname/reponename

    1
    2
    3
    4
    git clone --bare [email protected]:someuser/somerepo.git .git
    git config --bool core.bare false
    git reset --hard
    git branch

    沃伊拉!你有所有的树枝!


    派对稍微晚了一点,但我认为这就是诀窍:

    1
    2
    3
    4
    5
    6
    7
    8
    mkdir YourRepo
    cd YourRepo
    git init --bare .git                       # create a bare repo
    git remote add origin REMOTE_URL           # add a remote
    git fetch origin refs/heads/*:refs/heads/* # fetch heads
    git fetch origin refs/tags/*:refs/tags/*   # fetch tags
    git init                                   # reinit work tree
    git checkout master                        # checkout a branch

    如果这有什么不好的地方,我想知道。然而,到目前为止,这对我来说是可行的。


    下面是一个bash脚本,用于将Git项目的所有分支和标记作为快照提取到单独的文件夹中。

    网址:https://gist.github.com/hbossli/7562257

    也许不是直接问的问题,但有些人可能会来这里寻找这个解决方案。


    如果你用bitback,

    您可以使用导入存储库,这将导入所有git历史记录(所有分支和提交)