如何获取所有Git分支?

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

$ git branch* master

我如何在本地拉取所有分支,这样当我做git branch时,它会显示以下内容?

$ git branch* master* staging* etc...
2308001 次浏览
$ git remote update$ git pull --all

这假设跟踪所有分支。

如果它们不是,你可以在Bash中触发它:

for remote in `git branch -r `; do git branch --track $remote; done

然后运行命令。

警告:请阅读下面的警告评论。

太长别读答案

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

(似乎拉取从所有远程获取所有分支,但我总是先获取只是为了确保。

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

完整答案

你可以像这样从所有遥控器获取所有分支:

git fetch --all

它基本上是一个强力移动

fetch更新远程分支的本地副本,因此这对您的本地分支始终是安全的但是

  1. fetch不会更新本地分支(其中轨道远程分支);如果要更新本地分支,仍然需要拉取每个分支。

  2. fetch不会创建本地分支(其中轨道远程分支),您必须手动执行此操作。如果要列出所有远程分支:git branch -a

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

git pull --all

但是,这仍然不够。它只适用于跟踪远程分支的本地分支。要跟踪所有远程分支,请执行此oneliner之前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

注:AFAIKgit fetch --allgit remote update是等价的。



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

我不得不使用:

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

因为您的代码创建了名为origin/branchname和我得到“refname”的起源/分支名称是模棱两可的每当我#36825;到它

要列出远程分支:

git branch -r

要将远程分支签出为本地分支:

git checkout -b local_branch_name origin/remote_branch_name

如果您这样做:

git fetch origin

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

git branch -a

您会看到它们被列为远程/起源/分支名称。由于它们在本地,您可以对它们做任何您想做的事情。例如:

git diff origin/branch-name

git merge origin/branch-name

git checkout -b some-branch origin/branch-name

Bashfor循环不适合我,但这正是我想要的。我起源的所有分支在本地镜像为相同的名称。

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

请参阅下面迈克杜邦的评论。我想我试图在Jenkins服务器上执行此操作,这使其处于分离头模式。

循环似乎对我不起作用,我想忽略源/主。这就是我的工作

git branch -r | grep -v HEAD | awk -F'/' '{print $2 " " $1"/"$2}' | xargs -L 1 git branch -f --track

之后:

git fetch --allgit pull --all

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

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

for b in `git branch -r | grep -v -- '->'`; do git branch --track ${b##origin/} $b; done

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

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

如果你在这里寻求一个解决方案来获取所有分支,然后将所有内容迁移到另一个Git服务器,我整理了以下过程。如果你只是想在本地更新所有分支,请停在第一个空行。

git clone <ORIGINAL_ORIGIN>git branch -r | awk -F'origin/' '!/HEAD|master|main/{print $2 " " $1"origin/"$2}' | xargs -L 1 git branch -f --trackgit fetch --all --prune --tagsgit pull --all
git remote set-url origin <NEW_ORIGIN>git pull<resolve_any_merge_conflicts>git push --allgit push --tags<check_NEW_ORIGIN_to_ensure_it_matches_ORIGINAL_ORIGIN>

克隆主存储库后,您就可以执行

git fetch && git checkout <branchname>

使用git fetch && git checkout RemoteBranchName

它对我工作得很好…

我写了一个小脚本来管理克隆一个新的repo并为所有远程分支创建本地分支。

您可以找到最新版本这里

#!/bin/bash
# Clones as usual but creates local tracking branches for all remote branches.# To use, copy this file into the same directory your git binaries are (git, git-flow, git-subtree, etc)
clone_output=$((git clone "$@" ) 2>&1)retval=$?echo $clone_outputif [[ $retval != 0 ]] ; thenexit 1fipushd $(echo $clone_output | head -1 | sed 's/Cloning into .\(.*\).\.\.\./\1/') > /dev/null 2>&1this_branch=$(git branch | sed 's/^..//')for i in $(git branch -r | grep -v HEAD); dobranch=$(echo $i | perl -pe 's/^.*?\///')# this doesn't have to be done for each branch, but that's how I did it.remote=$(echo $i | sed 's/\/.*//')if [[ "$this_branch" != "$branch" ]]; thengit branch -t $branch $remote/$branchfidonepopd > /dev/null 2>&1

要使用它,只需将其复制到您的git bin目录(对我来说,这是C:\Program Files (x86)\Git\bin\git-cloneall),然后在命令行上:

git cloneall [standard-clone-options] <url>

它像往常一样克隆,但为所有远程分支创建本地跟踪分支。

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

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

稍微短一点的版本:

git fetch origingit checkout -t origin/remote-branch

根据Learath2的回答,这是我在创建目录后执行git clone [...]cd操作后所做的:

git branch -r | grep -v master | awk {print\$1} | sed 's/^origin\/\(.*\)$/\1 &/' | xargs -n2 git checkout -b

对我有用,但我不知道对你有用。小心点。

只有这三个命令将获得所有分支:

git clone --mirror repo.git  .git     (gets just .git  - bare repository)
git config --bool core.bare false
git reset --hard

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

$ 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”命令查看。

  2. 第二步

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

    $ git config --bool core.bare false
  3. Third Step

    Grab everything that inside the current folder and create all the branches on the local machine, therefore making this a normal repo.

    $ git reset --hard

So now you can just type the command git branch and you can see that all the branches are downloaded.

This is the quick way in which you can clone a git repository with all the branches at once, but it's not something you wanna do for every single project in this way.

git remote add origin https://yourBitbucketLink
git fetch origin
git checkout -b yourNewLocalBranchName origin/requiredRemoteBranch (use tab :D)

现在本地你的yourNewLocalBranchName是你的requiredRemoteBranch

我们可以将所有分支或标签名称放在一个临时文件中,然后为每个名称/标签执行git拉取:

git branch -r | grep origin | grep -v HEAD| awk -F/ '{print $NF}' > /tmp/all.txtgit tag -l >> /tmp/all.txtfor tag_or_branch in `cat /tmp/all.txt`; do git checkout $tag_or_branch; git pull origin $tag_or_branch; done

我相信您已经通过以下方式克隆了存储库:

git clone https://github.com/pathOfrepository

现在使用cd转到该文件夹:

cd pathOfrepository

如果你输入git status,你可以看到所有:

   On branch masterYour branch is up-to-date with 'origin/master'.nothing to commit, working directory clean

查看所有隐藏的分支类型:

 git branch -a

它将列出所有远程分支。

现在,如果您想在任何特定分支上结帐,只需键入:

git checkout -b localBranchName origin/RemteBranchName

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

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克隆您的repo时。通过以下方式检查:git config remote.origin.fetch

之后,您应该能够结帐任何分支。

另见:


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

git push --all

最终--mirror镜像所有引用。


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

对于使用PowerShell的Windows用户:

git branch -r | ForEach-Object {# Skip default branch, this script assumes# you already checked-out that branch when cloned the repoif (-not ($_ -match " -> ")) {$localBranch = ($_ -replace "^.*?/", "")$remoteBranch = $_.Trim()git branch --track "$localBranch" "$remoteBranch"}}; git fetch --all; git pull --all

确保所有远程分支都可以在.git/config文件中获取。

在这个例子中,只有origin/production分支是可获取的,即使你尝试执行git fetch --all,除了获取production分支之外,什么都不会发生:

[origin]fetch = +refs/heads/production:refs/remotes/origin/production

这一行应改为:

[origin]fetch = +refs/heads/*:refs/remotes/origin/*

然后运行git fetch etc…

这里有一些我认为是健壮的:

  • 不更新现有分支的远程跟踪
  • 不要尝试将HEAD更新为轨道origin/HEAD
  • 允许以origin以外的名称命名的遥控器
  • 正确引用shell
for b in $(git branch -r --format='%(refname:short)'); do[[ "${b#*/}" = HEAD ]] && continuegit show-ref -q --heads "${b#*/}" || git branch --track "${b#*/}" "$b";donegit pull --all

不需要git fetch --all,因为传递-allgit pull将此选项传递给内部fetch

信用这个答案

以下是已接受答案中提供的一行程序的Perl版本:

git branch -r | perl -e 'while(<>) {chop; my $remote = $_; my ($local) = ($remote =~ /origin\/(.*)/); print "git branch --track $local $remote\n";}' > some-output-file

如果需要,您可以将输出文件作为Shell脚本运行。

我们不小心删除了我们的Stash项目存储库。幸运的是,有人在意外丢失之前创建了一个分叉。我将分叉克隆到我的本地(将省略我如何做到这一点的细节)。一旦我在本地完全拥有分叉,我运行了一行程序。我修改了远程的URL(在我的情况下是起源)以指向我们正在恢复的目标存储库:

git remote set-url origin <remote-url>

最后将所有分支推到原点,如下所示:

git push --all origin

然后我们又开始做生意了。

如果您遇到fetch --all问题,请跟踪您的远程分支:

git checkout --track origin/%branchname%

为了避免错误消息'致命:一个名为'起源/主'的分支已经存在。',您可以尝试我的解决方案:

git branch -r | grep -v '\->'  | grep -v `git branch | awk '/\*/ { print $2; }'`| while read remote; do git branch --track "${remote#origin/}" "$remote"; done

如何获取跟踪单个远程的所有Git分支。

这已经在Windows 10上的Red Hat和Git Bash上进行了测试和运行。


TLDR:

for branch in `git branch -r|grep -v ' -> '|cut -d"/" -f2`; do git checkout $branch; git fetch; done;

说明:

一个班轮签出,然后获取除HEAD之外的所有分支。

列出远程跟踪分支。

git branch -r

忽略头。

grep -v ' -> '

从远程(S)中删除分支名称。

cut -d"/" -f2

签出跟踪单个远程的所有分支。

git checkout $branch

获取签出分支。

git fetch

从技术上讲,新的本地分支不需要获取。

这可以用于fetchpull分支,这些分支既是新的,又是远程更改的。

只要确保你只拉,如果你准备合并。


测试设置

检查带有URLSSH存储库。

git clone git@repository.git

之前

检查当地的分支机构。

$ git branch* master

执行命令

执行一个班轮。

for branch in `git branch -r|grep -v ' -> '|cut -d"/" -f2`; do git checkout $branch; git fetch; done;

之后

检查本地分支是否包括远程分支。

$ git branchcicdmaster* preprod

对于Visual Studio用户,在包管理器控制台上:

git branch | %{ git fetch upstream; git merge upstream/master}

我尝试过很多方法,只有这一个是简单的,为我工作。

for branch in $(git ls-remote -h git@<your_repository>.git | awk '{print $2}' | sed 's:refs/heads/::')dogit checkout "$branch"git pulldone

您看不到远程分支,因为您没有跟踪它们。

  1. 确保您正在跟踪所有远程分支(或者你想追踪的任何一个)
  2. 更新本地分支以反映远程分支。

跟踪所有远程分支:

跟踪远程存储库中存在的所有分支。

手动执行:

您将用git branch -r的输出中显示的分支替换<branch>

git branch -rgit branch --track <branch>

使用bash脚本执行此操作:

for i in $(git branch -r | grep -vE "HEAD|master"); do git branch --track ${i#*/} $i; done

懒惰的方式(这可能会因为合并冲突而造成混乱,要小心):

git checkout mastergit pull

更新有关本地计算机上远程分支的信息:

这会从您在本地存储库中跟踪的远程存储库获取分支的更新。这不会更改您的本地分支。您的本地git存储库现在知道远程存储库分支上发生的事情。一个例子是,一个新的提交已被推送到远程主机,执行获取现在会提醒您您的本地主机落后1次提交。

git fetch --all

更新有关本地计算机上远程分支的信息并更新本地分支:

为从远程分支到本地分支的所有分支执行获取并合并。一个例子是,一个新的提交已被推送到远程主分支,执行拉取将更新您的本地存储库有关远程分支中的更改,然后它将这些更改合并到您的本地分支中。由于合并冲突,这可能会造成相当混乱。

git pull --all

设置别名:(基于顶部答案)

git config --global alias.track-all-branches '!git fetch --all && for remote in `git branch -r`; do git branch --track ${remote#origin/} $remote; done && git fetch --all'

现在跟踪所有分支:

git track-all-branches

|‾‾‾‾‾‾‾‾‾‾‾‾‾fetch/clone‾‾‾‾‾‾‾‾‾‾‾‾↓   |‾‾‾‾‾‾‾‾‾‾‾‾checkout‾‾‾‾‾‾‾‾‾‾↓|‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾pull‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾↓Remote repository (`origin`) <=> Local repository <=> Index <=> Workspace↑_________________push_______________|   ↑____commit____|  ↑____add_____|
# 拉取远程仓库所有分支信息 → 本地仓库# fetch all remote repository branch meta → local repositorygit remote set-branches origin '*'git fetch -v
# 把所有远程分支数据搞到本地# fetch all remote repository branch data → local repositorygit branch -r | grep -v '\->' | while read remote; do git branch "${remote#origin/}" "$remote"; donegit fetch --allgit pull --all

您可以通过这样的一行命令获取所有brach:

git fetch --all && git pull --all && git branch -r | grep -v '\->' | while read remote; do git branch --track "${remote#origin/}" "$remote"; done

TLDR为每个远程跟踪分支创建一个本地分支可能不是一个好主意。这些不同类型的分支服务于不同的目的,本地分支通常是根据它们的需要创建的。git branch显示本地分支git branch -r显示远程跟踪分支。git branch -a显示两者。您可以使用适当的获取命令更新所有远程跟踪分支。这通常应该是您需要的全部。


在浏览了现有的答案后,我看到了两种:一种是简单地回答问题,而不是提出不同的方法。另一种是提出不同的方法,但没有解释原因。这是我试图解释的更多。

通常的git存储库需要处理的分支实际上有三种。这三种分支服务于不同的目的。简而言之:

  • 远程分支:这些是远程存储库中存在的分支。您永远不会直接从远程分支读取。远程分支的所有读取都通过所谓的“远程跟踪分支”的gits进行

  • 远程跟踪分支:git保留远程分支的本地快照,最准确地称为“远程跟踪分支”。当您调用git fetchgit pull(执行获取)时,它们会更新。您通常可以使用远程跟踪分支而无需创建本地分支。

    例如:

    git merge origin/master

    将远程跟踪分支origin/master合并到当前本地分支中,而无需您先创建它的本地副本。这意味着:有一个名为origin/master的远程跟踪分支,它是名为master的分支的快照,因为它存在于名为origin的远程存储库中。此命令将把它合并到当前签出的本地分支中。在执行此类操作之前,您可能需要执行获取。

  • 地方分支机构:这些是手动创建的历史记录中某些点的快照(通常基于远程跟踪分支,至少一开始是这样)。它们比其他类型静态得多,只有在您手动更改它们时才会真的更改。一个接一个。如果您想在工作树(项目目录)中查看其内容或想向其添加提交,您可能需要一个本地分支。

一旦你完成了本地分支(并发布了它的内容),你可以考虑删除它。这样你就不需要让它保持最新。毕竟,获取不会更新当前的本地分支,拉取只会更新当前签出的本地分支。换句话说:你应该只在需要时创建本地分支,当你不再这样做时,你可能应该删除它们。

说“默认隐藏某些分支”可能不准确。相反,创建git branch命令是为了向您显示“本地分支”。您可以使用git branch -r列出远程跟踪分支,使用git branch -a显示本地分支和远程跟踪分支。这两种不同类型的分支有不同的用途,您不太可能为每个远程跟踪分支都需要一个本地分支。

另请注意,创建名称以远程名称开头并后跟斜杠的本地分支通常是个坏主意(例如,创建名为“起源/主”的本地分支往往是个坏主意,因为它的名称与远程跟踪分支的名称冲突)。

在更新分支的上下文中,讨论不同风格的获取命令确实有意义:

  • git fetch:仅更新其远程与当前签出分支的“上游”中使用的远程匹配的远程跟踪分支。如果签出分支没有上游集,则会回退到从名为“原始”的远程获取(如果存在)。此命令最简单,并且大多数时候都足够了。
  • git fetch --all:更新所有远程跟踪分支,无论它们属于哪个远程快照。

我特别喜欢

git fetch -tf --all

它还将始终更新(并在需要时覆盖)所有标签,包括无法从远程分支到达的标签。

玩git时要小心,一步一步来。

$ git remote update  //This will update your local$ git branch -a      //This will list all the branches(After updating you can nowsee the new branch in the list)$ git checkout your_branch_name

这个即用型的麦克答案基于这个(赞成)答案(转换为处理边缘情况的循环,例如主,HEAD和起源/分支):

$ for REMOTE_BRANCH in `git branch -r | grep -v "HEAD\|master"`; do git checkout -b $REMOTE_BRANCH $REMOTE_BRANCH; done

*请注意,我们还从远程分支名称中删除了/origin以避免重复(/origin/origin/$REMOTE_BRANCH)。

我使用这个命令拉取原始分支,git拉取原点