ติดตามสาขา git ระยะไกลทั้งหมดเป็นสาขาท้องถิ่น


175

ติดตามสาขาระยะไกลเดียวเป็นสาขาท้องถิ่นตรงไปตรงมาพอ

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

ผลักสาขาท้องถิ่นทั้งหมดขึ้นสู่รีโมตสร้างสาขารีโมตใหม่ตามต้องการได้อย่างง่ายดาย

$ git push --all origin

ฉันต้องการย้อนกลับ ถ้าฉันมี X remote branch จำนวนมากในแหล่งเดียว:

$ git branch -r 
branch1
branch2
branch3
.
.
.

ฉันสามารถสร้างสาขาการติดตามในท้องถิ่นสำหรับสาขาระยะไกลเหล่านั้นโดยไม่จำเป็นต้องสร้างสาขาด้วยตนเองได้หรือไม่ พูดบางอย่างเช่น:

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

ฉันใช้ Google และ RTM แล้ว แต่ฉันพบปัญหามากขึ้น


3
มีวิธีที่ง่ายยิ่งขึ้นในการติดตามสาขาระยะไกลเดียวในสาขาท้องถิ่น:git checkout --track origin/branchname
Cerran

นี่ไม่ใช่สิ่งที่คุณต้องการ แต่ได้ผลกับฉัน: รับความสำเร็จทาง git: github.com/git/git/blob/master/contrib/completion/… . จากนั้นพิมพ์git pull origin และกดtabเพื่อรับรายการของสาขาระยะไกล returnแล้วดำเนินการต่อในการพิมพ์และการตี
Max Heiber

คำตอบ:


111

ใช้ทุบตี:

หลังคอมไพล์ 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

เครดิต: Val Blant, elias และ Hugo

ก่อนคอมไพล์ 1.9.1

หมายเหตุ:รหัสต่อไปนี้หากใช้ในรุ่นที่ใหม่กว่าของ git (> v1.9.1) เป็นสาเหตุ

  1. (ข้อผิดพลาด) สาขาที่สร้างขึ้นทั้งหมดเพื่อติดตามหลัก
  2. (รำคาญใจ) ทั้งหมดสร้างชื่อสาขาท้องถิ่นที่จะนำหน้าด้วย origin/
for remote in `git branch -r `; do git branch --track $remote; done

อัปเดตสาขาโดยสมมติว่าไม่มีการเปลี่ยนแปลงในสาขาการติดตามในพื้นที่ของคุณ:

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

ไม่สนใจคำเตือน refname ที่คลุมเครือดูเหมือนว่าคอมไพล์จะชอบสาขาในพื้นที่เท่าที่ควร


2
ขอขอบคุณที่หัวขึ้นเกี่ยวกับคำเตือน refname นั่นเป็นประโยชน์
พอล

1
ขอบคุณอ็อตโตฉันสงสัยว่าการเขียนสคริปต์จะเป็นทางออกเดียว คุณได้ให้สิ่งที่เรียบง่าย
Janson

1
@ Jason วันนี้มันยังคงเขียนสคริปต์ทางออกเท่านั้น?
cregox

1
@Cawas: คุณต้องสร้างสาขาการติดตามด้วยตนเอง แต่git pullมี--allสวิตช์ซึ่งจะดึง + รวมสาขาที่ติดตามทั้งหมด
naught101

13
สิ่งนี้ไม่ได้ผลสำหรับฉันใน Git 1.9.1 "git branch --track <banch_name>" สร้างสาขาใหม่ <branch_name> ที่ติดตามต้นแบบสาขาในพื้นที่แทนสาขาระยะไกลที่เราต้องการ ดังนั้นสคริปต์นี้จึงสร้างสาขาท้องถิ่นขึ้นมาทั้งหมดซึ่งชี้ไปที่เจ้านายท้องถิ่น ฉันจะโพสต์โซลูชันด้านล่าง
Val Blant

183

คำตอบที่ได้รับจาก Otto นั้นดี แต่สาขาที่สร้างขึ้นทั้งหมดจะมี "ต้นกำเนิด /" เป็นจุดเริ่มต้นของชื่อ หากคุณต้องการให้ส่วนสุดท้าย (หลังจากส่วนสุดท้าย /) เป็นชื่อสาขาของคุณให้ใช้สิ่งนี้:

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

นอกจากนี้ยังมีประโยชน์ที่จะไม่ให้คำเตือนใด ๆ เกี่ยวกับการอ้างอิงที่ไม่ชัดเจน


Git จะไม่เพิ่ม "ที่มา" ในชื่อสาขาติดตามท้องถิ่น
Adam Dymitruk

14
@adymitruk: จริง ๆ แล้วมันทำงานเหมือนที่ฉันบอกฉันใน OSX 10.6.4 โดยใช้ git 1.7.2.2 (ความเสถียรล่าสุดตามความคิดเห็นนี้) อ็อตโตยังกล่าวถึงคำเตือน refname ที่คลุมเครือ - คำเตือนไม่จำเป็นต้องมีอยู่หาก "ต้นทาง /" ไม่ได้เป็นส่วนหนึ่งของชื่อสาขาในแต่ละท้องถิ่น นี่คือเอาต์พุต 'git branch' หลังจากเรียกใช้คำสั่งของ Otto: [master, origin / HEAD, Origin / charts, origin / master, origin / production, origin / staging] และคำสั่งของฉัน: [แผนภูมิ, ต้นแบบ, การผลิต, การจัดเตรียม]
tjmcewan

1
+ แก้ไข: พบarticle.gmane.org/gmane.comp.version-control.git/112575อธิบายว่าทำไม
Philip Oakley

8
ฉันเห็นด้วย - นี่เป็นทางออกที่ดีกว่าคำตอบ "ยอมรับ" ในขณะนี้
tobias.mcnulty

2
แทนgrep -v masterวิธีการเกี่ยวกับgrep -v /HEAD? ดูเหมือนว่าจะกรองสาขาเริ่มต้นโดยไม่จำเป็นต้องปรับแต่ง
dashrb

22

git branch -rส่วนใหญ่คำตอบที่นี่มีมากกว่าแทรกซ้อนแยกของการส่งออกของ คุณสามารถใช้forวงต่อไปนี้เพื่อสร้างสาขาการติดตามกับทุกสาขาในระยะไกลเช่นนี้

ตัวอย่าง

บอกว่าฉันมีสาขาระยะไกลเหล่านี้

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

ยืนยันว่าเราไม่ได้ติดตามสิ่งอื่นนอกจากต้นแบบแล้วภายในเครื่อง:

$ 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 ....

พังทลายของวง

ห่วงโดยทั่วไปเรียกคำสั่งกรองออกหัวหรือปริญญาโททุกสาขาในการส่งออกโดยใช้git branch -r grep -vE "HEAD|master"ที่จะได้รับชื่อเพียงสาขาลบorigin/substring ${var#stringtoremove}เราใช้การจัดการสตริงทุบตีของ นี้จะลบสตริง "stringtoremove" $varจากตัวแปร ในกรณีที่เราจะลบสตริงจากตัวแปรorigin/$i

หมายเหตุ:หรือคุณสามารถใช้git checkout --track ...เพื่อทำสิ่งนี้เช่นกัน:

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

แต่ฉันไม่สนใจวิธีนี้เป็นพิเศษเพราะมันสลับคุณไปมาระหว่างสาขาเพราะมันเช็คเอาท์ เมื่อเสร็จแล้วมันจะทำให้คุณอยู่ในสาขาสุดท้ายที่มันสร้างขึ้น

อ้างอิง


1
ทำงานได้อย่างสมบูรณ์แบบกับ git เวอร์ชั่น 2.3.2 (Apple Git-55)
AndrewD

22

อัพเดท Q1 2020: Mohsen Abasiเสนอความคิดเห็นตามคำตอบของslm 2014 ทางเลือกที่ง่ายกว่า:

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

และจะใช้$()แทน backticks

ที่ผมกล่าวถึงในคำตอบเก่าอีกโดยใช้git for-each-refเป็นอาจจะเร็วขึ้น
และผมจะใช้ใหม่ (Git 2.23+) git switchคำสั่งซึ่งแทนที่ทำให้เกิดความสับสน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 ทดสอบด้วย 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
  • มันจะเลือกเฉพาะ upstream branch จากรีโมตที่คุณระบุในremoteตัวแปร (อาจเป็น ' origin' หรือชื่ออะไรก็ได้ที่คุณตั้งไว้สำหรับรีโมต Git repo ปัจจุบันของคุณ)
  • มันจะแยกชื่อของสาขา: origin/a/Branch/Name => a/Branch/Nameผ่านการawkแสดงออก
  • มันจะตั้งสาขาต้นน้ำผ่าน--set-upstream-to(หรือ-u)ไม่ใช่--track:
    ข้อดีคือถ้ามีสาขาอยู่แล้วมันจะไม่ล้มเหลวและจะไม่เปลี่ยนต้นกำเนิดสาขานั้นมันจะกำหนดค่าการbranch.xxx.(remote|merge)ตั้งค่าเท่านั้น

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

คำสั่งนั้นจะสร้างสาขาท้องถิ่นสำหรับสาขาอัปสตรีมระยะไกลทั้งหมดและตั้งค่ารีโมตและผสานการตั้งค่าเป็นสาขาระยะไกลนั้น


5
สิ่งนี้ทำให้ฉัน "ร้ายแรง: สาขา 'สิ่ง' ไม่มีอยู่" สำหรับทุกสาขาที่มีอยู่เฉพาะในระยะไกลและไม่มีสาขาท้องถิ่นที่สอดคล้องกัน
Chris Dodd

ฉันคิดว่าถ้าชื่อสาขามี / ตัวอย่างเช่น: feature / rc-41-bckend โซลูชันนี้ใช้ไม่ได้
Mohsen Abasi

@VonC ตามคำตอบของ "slm": $ for i ใน $ (git branch -r | grep -vE "HEAD | master" | sed 's / ^ [] \ + //'); ทำ git checkout - ติดตาม $ i; เสร็จแล้ว
Mohsen Abasi

@MohsenAbasi ดูดี ในคำตอบของฉันฉันกล่าวถึงใช้--set-upstream-toแทน--trackแม้ว่า
VonC

@MohsenAbasi ฉันได้รวมทางเลือกของคุณไว้ในคำตอบเพื่อให้มองเห็นได้ชัดเจนขึ้น ฉันได้เพิ่มทางเป็นไปได้อีกครั้งเพื่อให้สาขาระยะไกลรายการและใช้แทนgit switch git checkoutแต่ความคิดของคุณ (ดีมาก) ยังคงอยู่
VonC

14

คุณสามารถเขียนสคริปต์ได้อย่างง่ายดายพอ แต่ฉันไม่รู้ว่ามันจะมีค่าเมื่อไหร่ กิ่งก้านเหล่านั้นจะตกหล่นอย่างรวดเร็วและคุณต้องอัปเดตพวกเขาตลอดเวลา

สาขาระยะไกลจะได้รับการปรับปรุงให้ทันสมัยโดยอัตโนมัติดังนั้นจึงเป็นเรื่องง่ายที่สุดเพียงสร้างสาขาในพื้นที่ ณ จุดที่คุณต้องการทำงานจริง


2
นั่นเป็นจุดที่ดี กรณีใช้งานหลักที่ฉันคิดว่าตั้งค่าสภาพแวดล้อม dev ท้องถิ่นตามพื้นที่เก็บข้อมูล git ระยะไกล ดังนั้นเมื่อฉันทำโคลนครั้งแรกของฉันฉันยังต้องการติดตามกิ่งก้านสาขาที่ห่างไกลทั้งหมดในเวลานั้น
Janson

1
git upอัพเดทสะดวกทุกสาขาในท้องที่
Hugo

สำหรับการรวมสอง repos และลบ remote
endolith


9

ไม่มีสคริปต์ (ในไดเรกทอรีว่าง):

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

หลังจากนั้นสาขาระยะไกลทั้งหมดจะถูกมองว่าเป็นท้องถิ่น


เดิม (รัสเซีย)


นี่เป็นวิธีแก้ปัญหาที่ง่ายที่สุดโดยไกลและทำงานให้ฉันในวันที่ 2.21.0.windows.1
Rotsiser Mho

7

หากคุณต้องการใช้ powershell และรีโมทของคุณเรียกว่าจุดเริ่มต้น จากนั้นใช้งานได้

git fetch    
git branch -r  | %{$_ -replace "  origin/"} | %{git branch --track $_ "origin/$_"}

นี้เป็นประโยชน์ซุปเปอร์ฉันสิ้นสุดการใช้การเปลี่ยนแปลงเล็กน้อยที่จะทำให้มันทำงานกับฉันgit svn clone'drepo:git branch -r | %{$_ -replace " origin/"} | %{git checkout -b $_ "origin/$_"}
เนท

ฉันยังเปลี่ยนแปลงเล็กน้อยเพราะสาขาในพื้นที่ของฉันมีอยู่แล้ว:git branch -r | %{$_ -replace " origin/"} | %{git branch -u "origin/$_" $_}
ch271828n

3
for branch in `git branch -a | grep remotes | grep -v HEAD | grep -v master`; do  git branch --track ${branch##*/} $branch; done

ใช้สิ่งนี้และคุณจะไม่มีคำเตือนเช่น: refname 'origin / dev' ไม่ชัดเจน


3

นี่คือทางออกของคำสั่ง BASH ที่อ้างอิงโดย @tjmcewan:

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

เป้าหมายของฉันคือการแก้ปัญหาที่สาขาที่สร้างขึ้นทั้งหมดจะมี "ต้นกำเนิด /" เป็นจุดเริ่มต้นของชื่อเพราะฉันทดสอบว่าตัวแปร $ แบบรีโมทยังคงมี "กำเนิด /":

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

หลังจากที่ฉันทดสอบ @tjmcewan 's BASH ฉันพบว่าชื่อสาขาที่ถูกติดตามทั้งหมดที่ไม่มี' Origin / 'ในท้องถิ่นฉันไม่รู้ว่าทำไม
Nick Tsai

1
คำสั่งแรกสร้าง brances ที่ติดตาม "ต้นแบบ" นั่นไม่ใช่สิ่งที่คนส่วนใหญ่อาจต้องการ
Alexei Osipov

@AlexeiOsipov ขอบคุณ!
Nick Tsai

2

หากต้องการทำเช่นเดียวกันกับคำตอบของ 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


0

ในกรณีที่คุณมีสาขาที่ชำระเงินแล้วและต้องการ

  • ตรวจสอบสาขาที่เหลือทั้งหมดจากระยะไกล
  • ตรวจสอบให้แน่ใจว่าสาขาในท้องที่ติดตามสาขาระยะไกล

คุณสามารถใช้สคริปต์ที่เข้ากันได้กับ 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

0
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 แบบง่ายถูกใช้เพื่อหลีกเลี่ยง 'ต้นทาง /' การเป็นส่วนต่อท้ายสำหรับสาขาท้องถิ่น


0

ใช้ทุบตีหากคุณต้องการชำระเงินทุกสาขา:

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

สิ่งสำคัญคือให้สังเกตว่าเมื่อคุณดึงข้อมูลที่ทำให้สาขาการติดตามระยะไกลใหม่ลดลงคุณจะไม่มีสำเนาที่สามารถแก้ไขได้ในท้องถิ่นโดยอัตโนมัติ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.