簡體   English   中英

將所有遠程 git 分支作為本地分支進行跟蹤

[英]Track all remote git branches as local branches

將單個遠程分支作為本地分支進行跟蹤非常簡單。

$ git checkout --track -b ${branch_name} origin/${branch_name}

將所有本地分支推送到遠程,根據需要創建新的遠程分支也很容易。

$ git push --all origin

我想做相反的事情。 如果我在一個來源有 X 個遠程分支:

$ git branch -r 
branch1
branch2
branch3
.
.
.

我可以為所有這些遠程分支創建本地跟蹤分支而無需手動創建每個分支嗎? 像這樣說:

$ git checkout --track -b --all origin

我已經用谷歌搜索過和 RTM,但到目前為止還沒有找到。

Otto 給出的答案很好,但是所有創建的分支都將以“origin/”作為名稱的開頭。 如果您只想將最后一部分(最后一個 / 之后)作為結果分支名稱,請使用以下命令:

for remote in `git branch -r | grep -v /HEAD`; do git checkout --track $remote ; done

它還具有不給您任何關於不明確引用的警告的好處。

使用 bash:

git 1.9.1 之后
for i in `git branch -a | grep remote | grep -v HEAD | grep -v master`; do git branch --track ${i#remotes/origin/} $i; done

學分:瓦爾布蘭特、埃利亞斯和雨果

在 git 1.9.1 之前

注意:以下代碼如果在更高版本的 git (>v1.9.1) 中使用會導致

  1. (錯誤)所有創建的分支來跟蹤主
  2. (煩惱)所有創建的本地分支名稱都以origin/為前綴
for remote in `git branch -r `; do git checkout $remote ; git pull; done

更新分支,假設您的本地跟蹤分支沒有變化:

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

忽略模棱兩可的 refname 警告,git 似乎更喜歡本地分支,因為它應該。

這里的大多數答案都使git branch -r的輸出解析過於復雜。 您可以使用以下for循環針對遠程上的所有分支創建跟蹤分支,如下所示。

示例

假設我有這些遠程分支。

$ git branch -r
  origin/HEAD -> origin/master
  origin/development
  origin/integration
  origin/master
  origin/production
  origin/staging

確認我們沒有在本地跟蹤除 master 以外的任何內容:

$ git branch -l    # or using just git branch
* master

您可以使用這個襯墊來創建跟蹤分支:

$ for i in $(git branch -r | grep -vE "HEAD|master"); do 
    git branch --track ${i#*/} $i; done
Branch development set up to track remote branch development from origin.
Branch integration set up to track remote branch integration from origin.
Branch production set up to track remote branch production from origin.
Branch staging set up to track remote branch staging from origin.

現在確認:

$ git branch
  development
  integration
* master
  production
  staging

要刪除它們:

$ git br -D production development integration staging 
Deleted branch production (was xxxxx).
Deleted branch development (was xxxxx).
Deleted branch integration (was xxxxx).
Deleted branch staging (was xxxxx).

如果您使用-vv切換到git branch您可以確認:

$ git br -vv
  development xxxxx [origin/development] commit log msg ....
  integration xxxxx [origin/integration] commit log msg ....
* master      xxxxx [origin/master] commit log msg ....
  production  xxxxx [origin/production] commit log msg ....
  staging     xxxxx [origin/staging] commit log msg ....

for循環分解

該循環基本上調用命令git branch -r ,使用grep -vE "HEAD|master"過濾掉輸出中的任何 HEAD 或 master 分支。 為了僅獲取分支的名稱減去origin/子字符串,我們使用 Bash 的字符串操作${var#stringtoremove} 這將從變量$var刪除字符串“stringtoremove”。 在我們的例子中,我們從變量$i刪除了字符串origin/

注意:或者,您也可以使用git checkout --track ...來執行此操作:

$ for i in $(git branch -r | grep -vE "HEAD|master" | sed 's/^[ ]\+//'); do 
    git checkout --track $i; done

但我並不特別關心這種方法,因為它在執行結賬時會在分支之間切換。 完成后,它會將您留在它創建的最后一個分支上。

參考文獻

2020 年第一季度更新: Mohsen Abasi 在評論中提出,基於 2014 slm回答,更簡單的替代方案:

for i in $(git branch -r | grep -vE "HEAD|master" | sed 's/^[ ]\+//'); 

它使用$()而不是過時的反引號

正如我在另一個舊答案中提到的,使用git for-each-ref可能更快
我會使用新的 (Git 2.23+) git switch command ,它取代了令人困惑的git checkout

for i in $(git for-each-ref --format=%(refname:short) \
  --no-merged=origin/HEAD refs/remotes/origin); do \
    git switch --track $i; \
done

這樣,就不需要grep


舊(2011)原始答案:

這是我使用的單行(在 bash shell 中,使用 msysgit1.7.4 測試):

對於復制粘貼:

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

為了提高可讀性:

remote=origin ; // put here the name of the remote you want
for brname in `
    git branch -r | grep $remote | grep -v master | grep -v HEAD 
    | awk '{gsub(/^[^\/]+\//,"",$1); print $1}'
`; do 
    git branch --set-upstream-to $remote/$brname $brname; 
done
  • 它只會從您在remote變量中指定的remote選擇上游分支(它可以是“ origin ”或您為當前 Git 存儲庫的遠程之一設置的任何名稱)。
  • 它將通過awk表達式提取分支的名稱: origin/a/Branch/Name => a/Branch/Name
  • 它將通過--set-upstream-to (或-u而不是--track設置上游分支:
    好處是,如果分支已經存在,它不會失敗,也不會改變那個分支原點,它只會配置branch.xxx.(remote|merge)設置。

     branch.aBranchName.remote=origin branch.aBranchName.merge=refs/heads/a/Branch/Name

該命令將為所有遠程上游分支創建本地分支,並將其遠程和合並設置設置為該遠程分支。

你可以很容易地編寫腳本,但我不知道它什么時候有價值。 這些分支很快就會落后,你必須一直更新它們。

遠程分支會自動保持最新狀態,因此最簡單的方法是在您真正想要處理的地方創建本地分支。

沒有任何腳本(在一個空目錄中):

$ git clone --bare repo_url .git
$ git config core.bare false
$ git checkout

之后,所有遠程分支都將被視為本地分支。


原文(俄文)

for i in `git branch -a | grep remote`; do git branch --track ${i#remotes/origin/} $i; done

如果您想使用 powershell 並且您的遙控器稱為 origin。 然后這有效。

git fetch    
git branch -r  | %{$_ -replace "  origin/"} | %{git branch --track $_ "origin/$_"}
for branch in `git branch -a | grep remotes | grep -v HEAD | grep -v master`; do  git branch --track ${branch##*/} $branch; done

使用這個,你不會有這樣的警告: refname 'origin/dev' is ambiguous

這是@tjmcewan引用的BASH命令的解決方案:

for remote in `git branch -r | grep -v /HEAD `; do git branch --track ${remote/"origin/"/""}; done

我的目標是解決所有創建的分支將以“origin/”作為名稱開頭的問題,因為我測試了$remote變量仍然包含“origin/”:

for remote in `git branch -r | grep -v /HEAD`; do echo $remote ; done

要執行與tjmcewan 的回答相同但在 Windows 上的操作,請從批處理文件中調用:

for /f "delims=" %%r in ('git branch -r ^| grep -v master') do git checkout --track %%r

或者來自命令行

for /f "delims=" %r in ('git branch -r ^| grep -v master') do git checkout --track %r

從 git 2.23 開始:

for branch in `git branch -r | grep origin/`; do git switch -t -C ${branch#origin/} $branch; git pull; done

git switch-C標志創建或重置,如果它已經存在。

git 開關文檔

VonC 的解決方案可以通過更改 sed 進一步簡化(我沒有直接評論他的帖子的代表點):

for branch in $(git branch -r | sed 's,[^/]*/,,g'); do git switch $branch; done

通過將不是斜線的所有內容替換到最后的斜線,剩余的分支名稱適合本地使用; 重復切換到同一個分支不是錯誤(它可能效率低下,但它可能比在管道中使用 grep 更有效:->)。

switch 命令足夠智能,可以根據需要跟蹤每個遠程分支。

如果您已經簽出一些分支並想要

  • 從遠程檢查所有剩余的分支
  • 確保所有本地分支都跟蹤遠程分支

您可以使用以下與 bash 和 zsh 兼容的腳本:

git branch -r | while read b; do if git branch | grep -q " ${b##*/}$"; then git branch --set-upstream ${b##*/} $b; else git branch --track ${b##*/} $b; fi; done
for rembranch in `git remote update 2>&1 > /dev/null ; git branch -r|egrep -wv "HEAD|master"`
do 
    git checkout --track -b `echo $rembranch|awk -F\/ '{print $2}'` $rembranch; 
done

說明:

第 1 行:'git branch -r'(后跟 'git remote update' 以更新有關遠程更改的信息)列出所有遠程分支; 'egrep -vw' 用於敲除結果中包含 HEAD 和 master 的條目。

第 3 行:在本地簽出時跟蹤指定的遠程分支。 一個簡單的 awk 用於避免“origin/”成為本地分支的后綴。

使用 bash,如果要結帳所有分支:

for remote in `git branch -r`; do git checkout $(echo $remote | cut -d'/' -f 2); done

重要的是要注意,當您執行導致新遠程跟蹤分支關閉的提取時,您不會自動擁有它們的本地、可編輯副本。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM