ฉันจะดูว่าสาขา Git ใดกำลังติดตามสาขาระยะไกล / ต้นน้ำ


824

ฉันรู้ว่าฉันสามารถทำได้git branch --allและนั่นแสดงให้ฉันเห็นทั้งในและนอกเมือง แต่มันก็ไม่มีประโยชน์ที่จะแสดงความสัมพันธ์ระหว่างพวกเขา

ฉันจะแสดงรายการกิ่งไม้ในวิธีที่แสดงว่าสาขาท้องถิ่นกำลังติดตามรีโมตใด

คำตอบ:


1144

คำสั่งเครื่องเคลือบดินเผามากไม่ดีถ้าคุณต้องการสิ่งนี้สำหรับการเขียนสคริปต์:

git branch -vv   # doubly verbose!

โปรดทราบว่าด้วย git 1.8.3 สาขาต้นน้ำจะปรากฏเป็นสีน้ำเงิน (ดู " การติดตามสาขานี้คืออะไร (ถ้ามี) ในคอมไพล์ ")


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


3
วิธีแรกข้างต้นไม่ได้ให้ข้อมูลที่ต้องการสำหรับฉัน ที่สอง ... ดูเหมือน overkill โดยเฉพาะตั้งแต่คำตอบของ Kubi ทำงาน ฉันพลาดอะไรไปรึเปล่า?
แกรี่

3
@garyp คุณไม่ใช่คนที่ถามคำถาม ครั้งแรกที่จัดให้มีสิ่ง OP ที่จำเป็นและครั้งที่สองที่ให้ไว้ว่าสิ่งที่เขาจำเป็นต้องใช้ในกรณีที่เขาอยากให้มันในรูปแบบที่สะอาดสำหรับการเขียนสคริปต์หรืออยากจะเพียงแค่บันทึกเป็นนามแฝง ("Overkill" นั้นใช้ได้ถ้าคุณต้องการในสิ่งที่คุณต้องการและคุณไม่จำเป็นต้องทำซ้ำ) จากมุมมองของคำถามนี้คำตอบของ kubi จะให้ข้อมูลที่ไม่เกี่ยวข้องและถ้ามีรีโมตมากกว่าหนึ่งตัว ไม่แสดงทุกอย่าง แต่ถ้าตรงตามความต้องการของคุณให้ใช้ทุกอย่าง
Cascabel

2
ฉันเป็นหนี้ขอโทษ เมื่อฉันแรกเริ่มวิธีแรกฉันไม่ได้รับข้อมูลเกี่ยวกับสิ่งที่ติดตามและฉันควรจะระบุว่าอย่างชัดเจน แต่ตอนนี้ฉันเห็นข้อมูลการติดตามดังนั้นฉันต้องมีบางอย่างผิดปกติกับการตั้งค่าของฉัน ดังนั้นฉันจึงขาดอะไรไป
แกรี่

2
FWIW ฉันสับสนเพราะ -v และ -vv แสดงผลลัพธ์ที่คล้ายกันนี้ สาขาที่ถูกติดตามจะแสดงในวงเล็บเหลี่ยมหลังแฮชและก่อนหน้าคอมมิชชันล่าสุด (ในการติดตั้งโฮมเพเริ่มต้นของ OSX ของฉัน)
jerclarke

3
ทั้งหมดนี้สำหรับฉันคือพิมพ์แฮชคอมมิทล่าสุดและคอมเม้นท์สำหรับแต่ละสาขา
capybaralet

263

git remote show origin

แทนที่ 'ต้นกำเนิด' ด้วยชื่อใด ๆ ของรีโมทของคุณ


11
แม้ว่าคำสั่งเครื่องเคลือบนี้จะใช้ได้กับมนุษย์ (ไม่มากสำหรับสคริปต์เนื่องจากมันจะต้องแยกเอาท์พุทพอร์ซเลน) สิ่งที่ฉันไม่ชอบเกี่ยวกับวิธีการนี้เป็นgit remote showคำสั่งที่จริง ๆ แล้วเชื่อมต่อกับ repo ระยะไกล ... และด้วยเหตุนี้มันจึงล้มเหลวถ้าคุณบังเอิญออนไลน์หรือไม่สามารถเชื่อมต่อกับ repo ได้ไม่ว่าด้วยเหตุผลอะไรก็ตาม ...
pvandenberk

17
@pvandenberk คุณสามารถใช้git remote show -n originเพื่อรับข้อมูลบางอย่างแม้ในขณะออฟไลน์ จากเอกสารรีโมต git : "ด้วยตัวเลือก -n หัวรีโมตจะไม่ถูกสอบถามก่อนด้วย git ls-remote <name> ข้อมูลแคชจะถูกนำมาใช้แทน"
Cerran

5
สิ่งหนึ่งที่แปลกเกี่ยวกับคำสั่งนี้: มันแสดงรายการสาขาระยะไกลเป็น "ติดตาม" แม้ว่าจะไม่มีการกำหนดค่าสาขาภายในสำหรับดึง / ดัน ฉันมักจะพบความสับสนนี้ จริงๆแล้วฉันไม่ชัดเจนว่า "ติดตาม" ควรจะหมายถึงอะไรในผลลัพธ์นี้ เอกสารคอมไพล์ในเรื่องที่ทำให้มันเสียงเหมือนสาขาที่ห่างไกลคือ "ติดตาม" เท่านั้นเมื่อมันเชื่อมโยง / ผูกไว้กับสาขาในประเทศสำหรับการผลัก / ดึง ...
ฮ็อคปาร์กเกอร์

ปัญหาคือฉันต้องเรียกชื่อนี้จากชื่อระยะไกลทั้งหมดจนกว่าฉันจะเห็นสิ่งที่ฉันกำลังมองหา
jolvi

2
@jolvi คุณสามารถเรียกใช้git remote show | xargs git remote show -nเพื่อดูข้อมูลการติดตามแบบรวมสำหรับรีโมททั้งหมด
Synoli

107

หากคุณดูที่หน้า man สำหรับgit-rev-parseคุณจะเห็นคำอธิบายไวยากรณ์ต่อไปนี้:

<branchname>@{upstream}เช่นmaster@{upstream},@{u}

คำต่อท้าย@{upstream}ไปยัง branchname (รูปแบบสั้น <branchname>@{u}) หมายถึงสาขาที่สาขาที่ระบุโดย branchname ถูกตั้งค่าให้สร้างบน branchname ที่ขาดหายไปมีค่าเริ่มต้นเป็นค่าปัจจุบัน

ดังนั้นเพื่อค้นหาต้นน้ำของสาขาmasterคุณจะทำ:

git rev-parse --abbrev-ref master@{upstream}
# => origin/master

หากต้องการพิมพ์ข้อมูลสำหรับแต่ละสาขาคุณสามารถทำสิ่งต่อไปนี้

while read branch; do
  upstream=$(git rev-parse --abbrev-ref $branch@{upstream} 2>/dev/null)
  if [[ $? == 0 ]]; then
    echo $branch tracks $upstream
  else
    echo $branch has no upstream configured
  fi
done < <(git for-each-ref --format='%(refname:short)' refs/heads/*)

# Output:
# master tracks origin/master
# ...

นี่คือสะอาดกว่าการแยกอ้างอิงและกำหนดค่าด้วยตนเอง


ฉันไม่สามารถเข้าใจบิตในการแยกวิเคราะห์แม้จะพบมันดังนั้นขอบคุณสำหรับคำอธิบายที่ชัดเจน!
อลิซเพอร์เซลล์

3
สำหรับพวกเราที่ใช้ git-flow โดยมีกิ่งก้านที่ชื่อว่า "feature / blahblah" คำสั่งปิดของ while loop ควรอ่านได้: done < <(git for-each-ref --format='%(refname:short)' refs/heads/**)สังเกตเครื่องหมายดอกจันสองตัวที่ส่วนท้ายของรูปแบบ glob
markeissler

2
git rev-parse --abbrev-ref HEAD@{upstream}ดูเหมือนว่าจะทำงานได้ดีสำหรับสาขาปัจจุบัน นอกจากนี้ยังทำให้นามแฝงคอมไพล์ดี
Digikata

whileไวยากรณ์ห่วงลักษณะบิตแปลกกับผม คุณสามารถใช้git for-each-ref ... | while read branch; do ...ซึ่งไม่ต้องการ FIFO และทำงานในลำดับเดียวกันเช่นคำสั่งที่เขียน
Daniel Böhmer

อย่างน้อยตั้งแต่ git 2.5.1 คุณมีสายการบินหนึ่งgit for-each-ref --format='%(refname:short) tracks %(upstream:short)' refs/heads/*
Mat M

81

ทางเลือกอื่นสำหรับคำตอบของ kubi คือดู.git/configไฟล์ที่แสดงการกำหนดค่าที่เก็บในเครื่อง:

cat .git/config


6
นอกจากนี้ git config --get-regex branch
Tamir Daniely

6
หรือโดยเฉพาะอย่างยิ่ง 'git config - get-regexp Branch. * รวม'
yoyo

41
git for-each-ref --format='%(refname:short) <- %(upstream:short)' refs/heads

จะแสดงบรรทัดสำหรับแต่ละสาขาท้องถิ่น สาขาการติดตามจะมีลักษณะดังนี้:

master <- origin/master

คนที่ไม่ได้ติดตามจะมีลักษณะดังนี้:

test <- 

ดีเพื่อเพิ่มการสั่งซื้อและส่งออกเตียง TAB: คอมไพล์สำหรับแต่ละอ้างอิง - จัดเรียงต้นน้ำ - รูปแบบ = '% (refname: สั้น)% 09 <-% (ต้นน้ำ: สั้น)' อ้างอิง / หัว
ขนาด

git branch -vvสวยงามกระชับและการส่งออกที่เป็นจริงอ่านได้มากขึ้นกว่าที่ยอมรับ 🙏
joki

ปัญหาเดียวคือฉันจำไม่ได้ดังนั้นฉันจึงใช้git config --global alias.track 'for-each-ref --format='\''%(refname:short) <- %(upstream:short)'\'' refs/heads'
joki

38

สำหรับสาขาปัจจุบันที่นี่มีสองทางเลือกที่ดี:

% git rev-parse --abbrev-ref --symbolic-full-name @{u}
origin/mainline

หรือ

% git for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD)
origin/mainline

คำตอบนั้นก็อยู่ที่นี่เช่นกันสำหรับคำถามที่แตกต่างกันเล็กน้อยซึ่งทำเครื่องหมาย (ผิด) ซ้ำซ้อน


5
git for-each-ref --shell --format='%(refname:short) %(upstream:short)' refs/headsขึ้นอยู่กับว่าทุกสาขาสามารถแสดงในแฟชั่นมิตรสคริปต์:
Daniel James

15

สำหรับสาขาปัจจุบันคุณสามารถพูดได้git checkout(ไม่มีสาขาใด ๆ ) นี่คือไม่มีการ op ด้วยผลข้างเคียงเพื่อแสดงข้อมูลการติดตามถ้ามีสำหรับสาขาปัจจุบัน

$ git checkout 
Your branch is up-to-date with 'origin/master'.

ยุติธรรมเพียงพอ แต่คุณสามารถพิมพ์ได้โดยไม่ตั้งใจgit checkout .ซึ่งไม่ใช่แบบไม่มี op
Tomasz Gandor

6

ฉันใช้นามแฝงนี้

git config --global alias.track '!f() { ([ $# -eq 2 ] && ( echo "Setting tracking for branch " $1 " -> " $2;git branch --set-upstream $1 $2; ) || ( git for-each-ref --format="local: %(refname:short) <--sync--> remote: %(upstream:short)" refs/heads && echo --Remotes && git remote -v)); }; f'

แล้วก็

git track

5
ฉันคิดว่าน่าสังเกตว่ามีสองพารามิเตอร์ที่คำสั่งของคุณกำหนดค่าสาขาติดตาม
albfan

3

ตามคำตอบของ Olivier Refalo

if [ $# -eq 2 ] 
then
    echo "Setting tracking for branch " $1 " -> " $2
    git branch --set-upstream $1 $2
else
    echo "-- Local --" 
    git for-each-ref --shell --format="[ %(upstream:short) != '' ] && echo -e '\t%(refname:short) <--> %(upstream:short)'" refs/heads | sh
    echo "-- Remote --" 
    REMOTES=$(git remote -v) 
    if [ "$REMOTES" != '' ]
    then
        echo $REMOTES
    fi  
fi

มันจะแสดงเฉพาะในท้องถิ่นที่มีการกำหนดค่าการติดตาม

เขียนบนสคริปต์ที่เรียกว่าgit-trackบนเส้นทางของคุณคุณจะได้รับคำสั่งgit track

รุ่นที่มีเนื้อหาเพิ่มเติมที่https://github.com/albfan/git-showupstream


1

git config --get-regexp "branch\.$current_branch\.remote"

จะให้ชื่อของรีโมตที่ถูกติดตาม

git config --get-regexp "branch\.$current_branch\.merge"

จะให้ชื่อสาขาระยะไกลที่ถูกติดตาม

คุณจะต้องแทนที่ $ current_branch ด้วยชื่อสาขาปัจจุบันของคุณ คุณสามารถรับมันแบบไดนามิกด้วยgit rev-parse --abbrev-ref HEAD

mini-script ต่อไปนี้รวมสิ่งเหล่านั้นเข้าด้วยกัน ติดไว้ในไฟล์ที่ชื่อว่าgit-trackingทำให้มันสามารถเรียกใช้ได้และทำให้แน่ใจว่ามันอยู่ในพา ธ ของคุณ

จากนั้นคุณสามารถพูดได้

$ git  tracking
<current_branch_name>-><remote_repo_name>/<remote_branch_name>

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

$git tracking 
xxx_xls_xslx_thing -> origin/totally_bogus

อย่างที่คุณเห็นในรหัสกุญแจของสิ่งนี้คือการดึงข้อมูลจากการตั้งค่า git ฉันแค่ใช้ sed เพื่อล้างข้อมูลภายนอก

#!/bin/sh

current_branch=$(git rev-parse --abbrev-ref HEAD)
remote=$(git config --get-regexp "branch\.$current_branch\.remote" | sed -e "s/^.* //")
remote_branch=$(git config --get-regexp "branch\.$current_branch\.merge" | \
  sed -e "s/^.* //" -e "s/refs\/.*\///")

echo "$current_branch -> $remote/$remote_branch"

1

นี่คือหนึ่งที่เป็นระเบียบและเรียบง่าย สามารถตรวจสอบgit remote -vซึ่งจะแสดงที่มาและต้นน้ำทั้งหมดของสาขาปัจจุบัน

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