我克隆了一个包含许多分支的 Git 存储库。但是,git branch
只显示一个:
$ git branch
* master
我将如何在本地拉动所有分支,以便当我执行git branch
时,它显示以下内容?
$ git branch
* master
* staging
* etc...
TL;DR 答案
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 从所有远程获取所有分支,但我总是先获取以确保。
仅当服务器上存在未被本地分支跟踪的远程分支时,才运行第一个命令。
完整答案
您可以从所有远程获取所有分支,如下所示:
git fetch --all
这基本上是一种权力举措。
fetch
更新远程分支的本地副本,因此这对本地分支始终是安全的,但是:
fetch
不会更新本地分支(跟踪远程分支);如果要更新本地分支,仍然需要拉取每个分支。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
附言AFAIK git fetch --all
和git remote update
是等价的。
Kamil Szot的评论,人们发现它很有用。
我不得不使用:
for remote in `git branch -r`; do git branch --track ${remote#origin/} $remote; done
因为代码创建了名为
origin/branchname
和每当我收到"refname 'origin/branchname'是模棱两可的提到它。
列出远程分支:
git branch -r
要将远程分支签出为本地分支,请执行以下操作:
git checkout -b local_branch_name origin/remote_branch_name
您需要创建跟踪远程分支的本地分支。
假设您只有一个名为 origin
的远程,此代码段将为所有远程跟踪分支创建本地分支:
for b in `git branch -r | grep -v -- '->'`; do git branch --track ${b##origin/} $b; done
之后,git fetch --all
将更新远程分支的所有本地副本。
此外,git pull --all
将更新您的本地跟踪分支,但根据您的本地提交以及"合并"配置选项的设置方式,它可能会创建合并提交、快进或失败。
如果你这样做:
git fetch origin
然后他们都会在当地。 如果随后执行以下操作:
git branch -a
您将看到它们被列为远程/源/分支名称。 由于他们在本地,您可以对他们做任何您喜欢的事情。 例如:
git diff origin/branch-name
或
git merge origin/branch-name
或
git checkout -b some-branch origin/branch-name
$ git remote update
$ git pull --all
这假设跟踪了所有分支。
如果不是,你可以在 Bash 中触发它:
for remote in `git branch -r `; do git branch --track $remote; done
然后运行该命令。
注意:请阅读下面的警告评论。
Bash for
循环对我不起作用,但这完全符合我的需求。我原籍的所有分支在本地镜像为同名。
git checkout --detach
git fetch origin '+refs/heads/*:refs/heads/*'
请参阅下面的迈克杜邦的评论。我想我试图在 Jenkins 服务器上执行此操作,这使它处于分离的头部模式。
使用 git fetch && git checkout RemoteBranchName
.
它对我来说效果很好...
克隆存储库时,分支的所有信息实际上都会被下载,但分支是隐藏的。使用命令
$ git branch -a
您可以显示存储库的所有分支,并使用命令
$ git checkout -b branchname origin/branchname
然后,您可以一次手动"下载"它们。
但是,有一种更干净,更快捷的方法,尽管它有点复杂。您需要三个步骤来完成此操作:
第一步
在计算机上创建一个新的空文件夹,并从存储库克隆 .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 存储库的快速方法,但这不是您希望以这种方式为每个项目执行的操作。
您可以通过以下方式获取所有分支:
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 中克隆所有远程分支?
要将所有分支推送到远程,请使用:
git push --all
最终--mirror
镜像所有参考。
如果您的目标是复制存储库,请参阅:在 GitHub 上复制存储库一文。
我通常只使用这样的命令:
git fetch origin
git checkout --track origin/remote-branch
更短一点的版本:
git fetch origin
git checkout -t origin/remote-branch
您看不到远程分支,因为您没有跟踪它们。
- 确保您正在跟踪所有远程分支(或您要跟踪的任何分支)。
- 更新本地分支以反映远程分支。
跟踪所有远程分支机构:
跟踪远程存储库中存在的所有分支。
手动执行此操作:
您可以将<branch>
替换为从 git branch -r
的输出中显示的分支。
git branch -r
git branch --track <branch>
使用 bash 脚本执行此操作:
for i in $(git branch -r | grep -vE "HEAD|master"); do git branch --track ${i#*/} $i; done
懒惰的方式(这可能会由于合并冲突而造成混乱,请注意):
git checkout master
git pull
更新有关本地计算机上远程分支的信息:
这会从在本地存储库中跟踪的远程存储库中提取分支上的更新。这不会更改您的本地分支。本地 git 存储库现在可以知道远程存储库分支上发生的情况。例如,一个新的提交已被推送到远程主服务器,执行获取现在将提醒您本地主服务器落后 1 个提交。
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 --track
git fetch --all --prune --tags
git pull --all
git remote set-url origin <NEW_ORIGIN>
git pull
<resolve_any_merge_conflicts>
git push --all
git push --tags
<check_NEW_ORIGIN_to_ensure_it_matches_ORIGINAL_ORIGIN>
您已经通过以下方式克隆了存储库:
git clone https://github.com/pathOfrepository
现在使用 cd 转到该文件夹:
cd pathOfrepository
如果您键入git status
则可以看到所有内容:
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean
要查看所有隐藏的分支类型,请执行以下操作:
git branch -a
它将列出所有远程分支。
现在,如果您想在任何特定分支上结帐,只需键入:
git checkout -b localBranchName origin/RemteBranchName
确保所有远程分支都可以在.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
等...
克隆主资料库后,只需执行
git fetch && git checkout <branchname>
只有这三个命令将获取所有分支:
git clone --mirror repo.git .git (gets just .git - bare repository)
git config --bool core.bare false
git reset --hard
如何获取跟踪单个遥控器的所有 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 ' -> '
从遥控器中删除分支名称。
cut -d"/" -f2
查看跟踪单个遥控器的所有分支机构。
git checkout $branch
提取签出的分支。
git fetch
从技术上讲,新的本地分支不需要提取。
这可用于fetch
或pull
既是新的分支,又在远程中发生了更改。
只要确保只有在准备好合并时才拉动。
测试设置
签出带有 SSH URL 的存储库。
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 branch
cicd
master
* preprod
似乎对我不起作用,我想忽略原点/主。这是对我有用的方法。
git branch -r | grep -v HEAD | awk -F'/' '{print $2 " " $1"/"$2}' | xargs -L 1 git branch -f --track
然后:
git fetch --all
git pull --all
对于使用PowerShell的Windows用户:
git branch -r | ForEach-Object {
# Skip default branch, this script assumes
# you already checked-out that branch when cloned the repo
if (-not ($_ -match " -> ")) {
$localBranch = ($_ -replace "^.*?/", "")
$remoteBranch = $_.Trim()
git branch --track "$localBranch" "$remoteBranch"
}
}; git fetch --all; git pull --all
以下是我认为强大的东西:
- 不更新现有分支的远程跟踪
- 不尝试更新
HEAD
以跟踪origin/HEAD
- 允许以
origin
以外的方式命名的遥控器 - 正确引用外壳
for b in $(git branch -r --format='%(refname:short)'); do
[[ "${b#*/}" = HEAD ]] && continue
git show-ref -q --heads "${b#*/}" || git branch --track "${b#*/}" "$b";
done
git pull --all
没有必要git fetch --all
因为将-all
传递给git pull
会将此选项传递给内部fetch
。
感谢这个答案。
玩 git 时要小心,一步一步来。
$ git remote update //This will update your local
$ git branch -a //This will list all the branches(After updating you can now
see the new branch in the list)
$ git checkout your_branch_name
设置别名:(基于顶部答案)
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 repository
git remote set-branches origin '*'
git fetch -v
# 把所有远程分支数据搞到本地
# fetch all remote repository branch data → local repository
git branch -r | grep -v '->' | while read remote; do git branch "${remote#origin/}" "$remote"; done
git fetch --all
git pull --all
您可以通过以下一行命令获取所有 braches,如下所示:
git fetch --all && git pull --all && git branch -r | grep -v '->' | while read remote; do git branch --track "${remote#origin/}" "$remote"; done
我写了一个小脚本来管理克隆新存储库并为所有远程分支创建本地分支。
您可以在此处找到最新版本:
#!/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_output
if [[ $retval != 0 ]] ; then
exit 1
fi
pushd $(echo $clone_output | head -1 | sed 's/Cloning into .(.*)..../1/') > /dev/null 2>&1
this_branch=$(git branch | sed 's/^..//')
for i in $(git branch -r | grep -v HEAD); do
branch=$(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" ]]; then
git branch -t $branch $remote/$branch
fi
done
popd > /dev/null 2>&1
要使用它,只需将其复制到您的 git bin 目录中(对我来说,这C:Program Files (x86)Gitbingit-cloneall
),然后在命令行上:
git cloneall [standard-clone-options] <url>
它像往常一样克隆,但为所有远程分支创建本地跟踪分支。
如果您在使用fetch --all
时遇到问题,请跟踪您的远程分支:
git checkout --track origin/%branchname%
我们可以将所有分支或标签名称放在一个临时文件中,然后为每个名称/标签执行 git pull :
git branch -r | grep origin | grep -v HEAD| awk -F/ '{print $NF}' > /tmp/all.txt
git tag -l >> /tmp/all.txt
for tag_or_branch in `cat /tmp/all.txt`; do git checkout $tag_or_branch; git pull origin $tag_or_branch; done
尝试了很多方法,只有这种方法很简单并且对我有用。
for branch in $(git ls-remote -h git@<your_repository>.git | awk '{print $2}' | sed 's:refs/heads/::')
do
git checkout "$branch"
git pull
done
TLDR为每个远程跟踪分支创建一个本地分支可能是一个坏主意。这些不同类型的分支机构服务于不同的目的,通常根据需要创建本地分支机构。 git branch
显示本地分支git branch -r
显示远程跟踪分支。 git branch -a
显示了两者。您可以使用适当的 fetch 命令更新所有远程跟踪分支。这通常应该是您所需要的。
在滚动浏览现有答案后,我看到两种:一种只是回答提出的问题,而不是建议不同的方法。以及那些建议不同方法而不解释原因的人。这是我试图解释更多一点的尝试。
通常的 git 存储库实际上需要处理三种分支。这三种分支有不同的用途。总之:
- 远程分支
:这些是远程仓库中存在的分支。您永远不会直接从远程分支读取。远程分支的所有读取都通过所谓的"远程跟踪分支"的 gits 进行
远程跟踪分支:Git 保留远程分支的本地快照,最准确地称为"远程跟踪分支"。当您调用
git fetch
或git pull
(执行提取)时,它们会更新。您通常可以使用远程跟踪分支,而无需从中创建本地分支。例如:
git merge origin/master
将远程跟踪分支
origin/master
合并到当前本地分支中,而无需您先创建它的本地副本。这意味着:有一个名为origin/master
的远程跟踪分支,它是名为master
的分支的快照,因为它存在于名为origin
的远程存储库中。此命令会将其合并到当前签出的本地分支中。您可能需要在执行此类操作之前执行提取。本地分支:这些是手动创建的历史记录中某些点的快照(通常基于远程跟踪分支,至少一开始是这样)。它们比其他种类的静态要静态得多,并且只有在您手动更改它们时才会真正更改。一个接一个。如果要在工作树(项目目录)中查看其内容,或者要向其添加提交,则可能需要本地分支。
完成本地分支(并发布其内容)后,您可以考虑将其删除。这样,您就不需要使其保持最新状态。毕竟,提取不会更新当前本地分支,拉取只会更新当前签出的本地分支。换句话说:您应该只在需要时创建本地分支,并且当您不再需要时,您可能应该删除它们。
说"某些分支默认隐藏"可能不准确。相反,创建git branch
命令是为了向您显示"本地分支"。您可以使用git branch -r
列出远程跟踪分支,git branch -a
显示本地分支和远程跟踪分支。这两种不同类型的分支有不同的用途,您不太可能为每个远程跟踪分支使用本地分支。
以远程名称开头后跟斜杠的本地分支通常是一个坏主意(例如,创建名为"origin/master"的本地分支往往是一个坏主意,因为它的名称与远程跟踪分支的名称冲突)。
在更新分支的上下文中,讨论不同风格的 fetch 命令确实是有意义的:
-
git fetch
:仅更新远程跟踪分支,其远程与当前签出分支的"上游"中使用的分支匹配。如果签出的分支没有上游集,则回退到从名为"origin"的远程(如果存在)获取。此命令是最简单的,并且在大多数情况下就足够了。 -
git fetch --all
:更新所有远程跟踪分支,无论它们属于哪个远程快照。
我特别喜欢
git fetch -tf --all
这也将始终更新(并在需要时覆盖)所有标签,包括无法从远程分支访问的标签。
以下是接受答案中提供的单行代码的Perl版本:
git branch -r | perl -e 'while(<>) {chop; my $remote = $_; my ($local) = ($remote =~ /origin/(.*)/); print "git branch --track $local $remoten";}' > some-output-file
如果需要,可以将输出文件作为 Shell 脚本运行。
我们意外删除了我们的 Stash 项目存储库。幸运的是,有人在意外丢失之前创建了一个分叉。我将分叉克隆到我的本地(将省略我如何做到这一点的细节)。一旦我把叉子完全放在我的本地,我就跑了一个单行。我修改了远程的 URL(在我的情况下是源)以指向我们正在恢复的目标存储库:
git remote set-url origin <remote-url>
最后像这样将所有分支推到原点:
git push --all origin
我们又开始营业了。