我克隆了一个包含许多分支的 Git 存储库。但是,git branch
只显示一个:
$ git branch
* master
我将如何在本地拉出所有分支,所以当我执行 git branch
时,它会显示以下内容?
$ git branch
* master
* staging
* etc...
--single-branch
设置后获取所有分支:stackoverflow.com/questions/17714159/…(如果您只指定了一个分支,git fetch --all
将永远无法工作!)
git clone --bare <repo url> .git
(注意你需要在最后添加“--bare”和“.git”来克隆repo 作为“bare” repo),然后是 git config --bool core.bare false
(将“bare”标志设置为 false),然后是 git reset --hard
(将 HEAD 移动到 repo 上的当前 HEAD)。现在,如果您git branch
,您应该会看到您克隆的 repo 中的所有分支。
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
它基本上是一个 power move。
fetch
更新远程分支的本地副本,因此这对于您的本地分支始终是安全的但是:
fetch 不会更新本地分支(跟踪远程分支);如果你想更新你的本地分支,你仍然需要拉每个分支。 fetch 不会创建本地分支(跟踪远程分支),您必须手动执行此操作。如果要列出所有远程分支: git branch -a
要更新跟踪远程分支的本地分支:
git pull --all
然而,这仍然是不够的。它仅适用于跟踪远程分支的本地分支。要跟踪所有远程分支,请执行此 oneliner BEFORE 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
PS AFAIK git fetch --all
和 git remote update
是等效的。
Kamil Szot 的comment,人们发现它很有用。
我不得不使用: for remote in `git branch -r`;做 git 分支 --track ${remote#origin/} $remote;完成,因为您的代码创建了名为 origin/branchname 的本地分支,并且每当我提到它时,我都会得到“refname 'origin/branchname' 是模棱两可的。
列出远程分支:
git branch -r
要将远程分支检出为本地分支:
git checkout -b local_branch_name origin/remote_branch_name
git checkout remotebranchname
并且它可以工作。你的解决方案有什么区别?
git checkout remotebranchname
仅创建一个名为 remotebranchname 的新 unrelated 分支。
您将需要创建本地分支来跟踪远程分支。
假设您只有一个名为 origin
的远程,此代码段将为所有远程跟踪创建本地分支:
for b in `git branch -r | grep -v -- '->'`; do git branch --track ${b##origin/} $b; done
之后,git fetch --all
将更新远程分支的所有本地副本。
此外,git pull --all
将更新您的本地跟踪分支,但根据您的本地提交以及“合并”配置选项的设置方式,它可能会创建合并提交、快进或失败。
git pull --all
会更新所有本地跟踪分支吗?据我所知,它只更新所有遥控器的当前分支。
origin
?请参阅适用于所有远程名称的 this answer。
如果你这样做:
git fetch origin
然后他们将都在当地。如果您随后执行:
git branch -a
你会看到它们被列为远程/来源/分支名称。由于他们在当地,您可以随心所欲地对待他们。例如:
git diff origin/branch-name
或者
git merge origin/branch-name
或者
git checkout -b some-branch origin/branch-name
--all
)
git fetch -all
获取所有遥控器的所有分支。 git fetch origin
获取远程 origin
的所有分支。后者是OP所要求的。
--all
表示“所有遥控器”,而不是“给定遥控器的所有分支”。从远程获取的任何内容都暗示了后者。
$ git remote update
$ git pull --all
这假设所有分支都被跟踪。
如果不是,您可以在 Bash 中触发:
for remote in `git branch -r `; do git branch --track $remote; done
然后运行命令。
->
创建一个分支,该分支可能会作为 `origin/HEAD -> 存在于 git branch -r
的输出中。原产地/主人`
Branch 'origin/quote-filenames' set up to track local branch 'master'.
所需的输出是:Branch 'quote-filenames' set up to track remote branch 'quote-filenames' from 'origin'.
这是向后,设置原点以跟踪遥控器。有关修复,请参阅 this answer。
git fetch
也无法工作。所以这里的教训是你需要跟踪远程分支。格拉西亚斯!
Bash for
循环对我不起作用,但这正是我想要的。我的所有分支都在本地镜像为同名。
git checkout --detach
git fetch origin '+refs/heads/*:refs/heads/*'
请参阅下面的 Mike DuPont 评论。我想我试图在 Jenkins 服务器上执行此操作,使其处于分离头模式。
fatal: Refusing to fetch into current branch refs/heads/master of non-bare repository
。必须先拆头。我用 git checkout <SHA>
做了这个
git checkout --detach # detach the head
,然后是 git fetch origin \'+refs/heads/*:refs/heads/*
使用 git fetch && git checkout RemoteBranchName
。
它对我来说效果很好......
origin/branch
;只需说 branch
)。
当您克隆存储库时,实际上会下载分支的所有信息,但分支是隐藏的。用命令
$ 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 第三步获取当前文件夹中的所有内容并在本地机器上创建所有分支,因此使它成为一个正常的 repo。 $ 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 上的Duplicating a repository文章。
depth=1
),并且配置还为 fetch
指定了一个特定分支 - depth=1000
参数是帮助我签出特定远程分支的修复程序
pull --all
不会拉所有分支,而是拉所有遥控器
我通常只使用这样的命令:
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 repo 现在知道远程 repo 分支上发生的事情。一个例子是,一个新的提交已经被推送到远程主控,现在做一个提取会提醒你你的本地主控落后了 1 个提交。
git fetch --all
在本地计算机上更新有关远程分支的信息并更新本地分支:
对从远程分支到本地分支的所有分支进行提取,然后合并。一个例子是,一个新的提交已经被推送到远程 master,执行 pull 将更新你的本地 repo 关于远程分支中的更改,然后它将这些更改合并到你的本地分支中。由于合并冲突,这可能会造成相当混乱。
git pull --all
for remoteBranch in $(git branch -r | grep -vE "HEAD|master"); do git branch --track ${remoteBranch#*/} $remoteBranch; done
xargs
而不是 for
循环,您根本不需要任何变量。
git branch -r | grep -vE "HEAD|master" | xargs -I remoteBranch -n 1 echo ...remoteBranch...
之类的东西替换循环,用 git branch
命令替换 echo
但我现在看到删除 remoteBranch 中的远程将需要某种 sed
命令可能会使它更多复杂。
如果您在这里寻求一种解决方案来获取所有分支,然后将所有内容迁移到另一个 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 fetch git pull
stackoverflow.com/a/292359/1114926
pull
确实首先执行了 fetch
,但当 fetch
独立执行时,更容易判断问题是来自 pull
的 fetch
部分还是 pull
的后续 merge
部分。
我相信您已经通过以下方式克隆了存储库:
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 config --get remote.origin.fetch
,然后(破坏性地)设置它:git config remote.origin.fetch '+refs/heads/*:refs/remotes/origin/*'
克隆主存储库后,您只需执行
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
pull --all
。但是如果仍然需要,那么下面的另一个答案,@Johnno Nola,假设所有分支都被跟踪,与这个答案混合,是要走的路。
如何获取跟踪单个远程的所有 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
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 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
我写了一个小脚本来管理克隆一个新的 repo 并为所有远程分支创建本地分支。
您可以找到最新版本 here:
#!/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)\Git\bin\git-cloneall
),然后在命令行上:
git cloneall [standard-clone-options] <url>
它像往常一样克隆,但为所有远程分支创建本地跟踪分支。
这是我认为可靠的东西:
不更新现有分支机构的远程跟踪
不尝试更新 HEAD 以跟踪原点/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
。
归功于 this answer。
${b#*/}
- 有人可以解释一下含义吗?
${STR#*/}
扩展为 STR 的完整路径(即上述代码中的 b)。
git branch -r --format='%(refname:short)'
将输出引号 ('),因此请使用双引号:git branch -r --format="%(refname:short)"
如果您对 fetch --all
有问题,请跟踪您的远程分支:
git checkout --track origin/%branchname%
|‾‾‾‾‾‾‾‾‾‾‾‾‾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
您可以通过这一行命令获取所有分支,如下所示:
git fetch --all && git pull --all && git branch -r | grep -v '\->' | while read remote; do git branch --track "${remote#origin/}" "$remote"; done
我们可以将所有分支或标签名称放在一个临时文件中,然后为每个名称/标签执行 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
这是接受的答案中提供的单行代码的 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
我们又开始营业了。
尝试了很多方法,只有这个简单并且对我有用。
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
为避免错误消息“致命:名为 'origin/master' 的分支已存在。”,您可以尝试我的解决方案:
git branch -r | grep -v '\->' | grep -v `git branch | awk '/\*/ { print $2; }'`| while read remote; do git branch --track "${remote#origin/}" "$remote"; done
根据 Learath2 的回答,这是我在执行 git clone [...]
和 cd
进入创建的目录后所做的:
git branch -r | grep -v master | awk {print\$1} | sed 's/^origin\/\(.*\)$/\1 &/' | xargs -n2 git checkout -b
为我工作,但我不知道它会为你工作。当心。
不定期副业成功案例分享
git checkout -b localname remotename/remotebranch
进行检查for remote in `git branch -r`; do git branch --track ${remote#origin/} $remote; done
,因为您的代码创建了名为 origin/branchname 的本地分支,并且每当我提到它时,我都会得到“refname 'origin/branchname' 是模棱两可的。git pull --all; for remote in `git branch -r | grep -v \>`; do git branch --track ${remote#origin/} $remote; done
。更改去掉了 HEAD。for /F %remote in ('git branch -r') do ( git branch --track %remote) && git fetch --all && git pull --all