Làm cách nào tôi có thể thấy các nhánh Git đang theo dõi nhánh từ xa / ngược dòng nào?


825

Tôi biết tôi có thể làm được git branch --all, và điều đó cho tôi thấy cả các chi nhánh địa phương và từ xa, nhưng nó không hữu ích trong việc chỉ cho tôi các mối quan hệ giữa chúng.

Làm cách nào để liệt kê các nhánh theo cách hiển thị nhánh cục bộ nào đang theo dõi từ xa nào?

Câu trả lời:


1146

Rất nhiều lệnh sứ, không tốt nếu bạn muốn điều này cho kịch bản:

git branch -vv   # doubly verbose!

Lưu ý rằng với git 1.8.3, nhánh ngược dòng đó được hiển thị màu xanh lam (xem " Theo dõi nhánh này (nếu có gì) trong git? ")


Nếu bạn muốn đầu ra sạch, hãy xem câu trả lời của arcresu - nó sử dụng lệnh sứ mà tôi không tin là đã tồn tại vào thời điểm ban đầu tôi viết câu trả lời này, vì vậy nó ngắn gọn hơn một chút và hoạt động với các nhánh được cấu hình để rebase, không chỉ hợp nhất.


3
Phương pháp đầu tiên ở trên không cung cấp thông tin mong muốn cho tôi. Thứ hai ... có vẻ quá mức, đặc biệt là khi câu trả lời của Kubi hoạt động. Tui bỏ lỡ điều gì vậy?
garyp

3
@ÿp Bạn không phải là người đặt câu hỏi. Cái đầu tiên cung cấp những gì OP cần, và cái thứ hai cung cấp chính xác những gì anh ta cần, trong trường hợp anh ta muốn nó ở dạng sạch để viết kịch bản, hoặc muốn chỉ lưu nó dưới dạng bí danh. ("Quá mức" là tốt nếu nó mang lại cho bạn những gì bạn muốn và bạn không phải lặp lại nó.) Từ quan điểm của câu hỏi này, câu trả lời của kubi cung cấp một số thông tin không liên quan, và nếu có nhiều hơn một điều khiển từ xa Không thể hiện tất cả mọi thứ, nhưng nếu nó đáp ứng nhu cầu của bạn, bằng mọi cách hãy sử dụng nó.
Cascabel

2
Tôi nợ lời xin lỗi. Khi tôi ban đầu chạy phương thức đầu tiên, tôi không có thông tin về những gì theo dõi những gì, và tôi nên đã nói rõ điều đó. Nhưng bây giờ tôi thấy thông tin theo dõi, vì vậy tôi phải có vấn đề gì đó với thiết lập của mình. Vì vậy, tôi đã bỏ lỡ một cái gì đó.
garyp

2
FWIW Tôi đã nhầm lẫn vì -v và -vv hiển thị đầu ra tương tự như vậy. Nhánh được theo dõi được hiển thị trong ngoặc vuông sau hàm băm và trước lần xác nhận gần đây nhất (trên bản cài đặt homebrew mặc định OSX của tôi).
jerclarke

3
Tất cả điều này đối với tôi là in ra hàm băm cam kết cuối cùng và nhận xét cho mỗi chi nhánh.
capybaralet

263

git remote show origin

Thay thế 'nguồn gốc' bằng bất cứ tên nào của điều khiển từ xa của bạn.


11
Mặc dù lệnh sứ này có tác dụng với con người (không nhiều cho kịch bản, vì nó sẽ phải phân tích đầu ra sứ), nhưng điều tôi không thích về cách tiếp cận này là git remote showlệnh đó thực sự kết nối với repo từ xa ... và do đó không thành công nếu bạn
tình cờ ngoại

17
@pvandenberk Bạn có thể sử dụng git remote show -n originđể lấy một số thông tin ngay cả khi ngoại tuyến. Từ tài liệu từ xa git : "Với tùy chọn -n, đầu từ xa không được truy vấn trước bằng git ls-remote <name>; thông tin được lưu trong bộ nhớ cache được sử dụng thay thế."
Cerran

5
Một điều kỳ lạ về lệnh này: nó liệt kê các nhánh từ xa là "được theo dõi", ngay cả khi không có nhánh cục bộ nào được cấu hình để kéo / đẩy. Tôi luôn thấy khó hiểu. Tôi thực sự không rõ ràng về "theo dõi" nghĩa là gì trong đầu ra này. Các tài liệu git về chủ đề này làm cho âm thanh giống như một nhánh từ xa chỉ được "theo dõi" khi nó được liên kết / liên kết với một nhánh cục bộ để đẩy / kéo ...
Hawkeye Parker

Vấn đề là tôi cần gọi nó cho tất cả các tên từ xa cho đến khi tôi thấy những gì tôi thực sự đang tìm kiếm.
jolvi

2
@jolvi Bạn có thể chạy git remote show | xargs git remote show -nđể xem thông tin theo dõi kết hợp cho tất cả các điều khiển từ xa.
Synoli

107

Nếu bạn nhìn vào trang man git-rev-parse, bạn sẽ thấy cú pháp sau được mô tả:

<branchname>@{upstream}, Ví dụ master@{upstream},@{u}

Hậu tố @{upstream}cho một <branchname>@{u}tên nhánh (dạng ngắn ) đề cập đến nhánh mà nhánh được chỉ định bởi tên nhánh được đặt để xây dựng trên đầu trang. Một tên nhánh bị thiếu mặc định cho tên hiện tại.

Do đó để tìm thượng nguồn của chi nhánh master, bạn sẽ làm:

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

Để in thông tin cho từng chi nhánh, bạn có thể làm một cái gì đó như:

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

Điều này là sạch hơn so với phân tích cú pháp refs và cấu hình bằng tay.


Tôi không thể hiểu được bit đó trong phân tích lại mặc dù đã tìm thấy nó, vì vậy cảm ơn vì lời giải thích rõ ràng!
Alice Purcell

3
Đối với những người trong chúng ta sử dụng git-Flow, với các nhánh có tên là "Feature / blahblah", câu lệnh đóng của vòng lặp while sẽ đọc: done < <(git for-each-ref --format='%(refname:short)' refs/heads/**)Lưu ý hai dấu sao ở cuối mẫu toàn cầu.
markeissler

2
git rev-parse --abbrev-ref HEAD@{upstream}dường như làm việc độc đáo cho các chi nhánh hiện tại. Nó cũng làm cho một bí danh git tốt đẹp.
Digikata

Các whilecú pháp vòng lặp trông hơi lạ với tôi. Bạn chỉ có thể sử dụng git for-each-ref ... | while read branch; do ...mà không cần một bộ xếp hình và chạy theo thứ tự giống như các lệnh được viết.
Daniel Böhmer

Ít nhất kể từ git 2.5.1, bạn có một lớp lót vớigit for-each-ref --format='%(refname:short) tracks %(upstream:short)' refs/heads/*
Mat M

81

Một cách khác để trả lời cho câu trả lời của kubi là xem .git/configtập tin hiển thị cấu hình kho lưu trữ cục bộ:

cat .git/config


6
Ngoài ra git config --get-regex branch
Tamir Daniely 1/15

6
Hay cụ thể hơn là 'git config --get-regapi nhánh. * Hợp nhất'
yoyo

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

sẽ hiển thị một dòng cho mỗi chi nhánh địa phương. Một nhánh theo dõi sẽ trông như:

master <- origin/master

Một người không theo dõi sẽ trông giống như:

test <- 

Thật tuyệt, để thêm một số thứ tự và đầu ra TAB-bed: git for-Each-ref --sort upstream --format = '% (refname: short)% 09 <-% (ngược dòng: short)' refs /
Heads

Đẹp súc tích và đầu ra thực sự dễ đọc hơn nhiều so với chấp nhận git branch -vv. 🙏
Joki

Vấn đề duy nhất là tôi không thể nhớ điều này, vì vậy tôi đã sử dụnggit config --global alias.track 'for-each-ref --format='\''%(refname:short) <- %(upstream:short)'\'' refs/heads'
joki

38

Đối với chi nhánh hiện tại , đây là hai lựa chọn tốt:

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

hoặc là

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

Câu trả lời đó cũng ở đây , cho một câu hỏi hơi khác được đánh dấu (sai) là trùng lặp.


5
Dựa vào đó, tất cả các chi nhánh có thể được liệt kê theo kiểu thân thiện với kịch bản : git for-each-ref --shell --format='%(refname:short) %(upstream:short)' refs/heads.
Daniel James

15

Đối với chi nhánh hiện tại, bạn cũng có thể nói git checkout(w / o bất kỳ chi nhánh nào). Đây là một no-op với tác dụng phụ để hiển thị thông tin theo dõi, nếu tồn tại, cho chi nhánh hiện tại.

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

Đủ công bằng, nhưng bạn có thể vô tình gõ git checkout ., mà không phải là không có.
Tomasz Gandor

6

Tôi sử dụng bí danh này

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'

sau đó

git track

5
Tôi nghĩ rằng đáng chú ý rằng với hai tham số, lệnh của bạn cấu hình một nhánh theo dõi.
albfan

3

Dựa trên câu trả lời của 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

Nó chỉ hiển thị cục bộ với theo dõi được cấu hình.

Viết nó vào một kịch bản gọi là git-track trên con đường của bạn một bạn sẽ nhận được một git theo dõi lệnh

Một phiên bản công phu hơn trên https://github.com/albfan/git-showupstream


1

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

sẽ cung cấp cho bạn tên của điều khiển từ xa đang được theo dõi

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

sẽ cung cấp cho bạn tên của chi nhánh từ xa đang được theo dõi.

Bạn sẽ cần thay thế $ current_branch bằng tên của chi nhánh hiện tại của bạn. Bạn có thể có được điều đó một cách linh hoạt vớigit rev-parse --abbrev-ref HEAD

Các kịch bản nhỏ sau đây kết hợp những điều đó. Dán nó vào một tệp có tên git-tracking, làm cho nó có thể thực thi được và đảm bảo rằng nó nằm trong đường dẫn của bạn.

sau đó bạn có thể nói

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

lưu ý rằng tên chi nhánh từ xa có thể khác với tên chi nhánh địa phương của bạn (mặc dù tên này thường không). Ví dụ:

$git tracking 
xxx_xls_xslx_thing -> origin/totally_bogus

như bạn có thể thấy trong mã, chìa khóa cho việc này là trích xuất dữ liệu từ cấu hình git. Tôi chỉ sử dụng sed để xóa dữ liệu không liên quan.

#!/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

Đây là một gọn gàng và đơn giản. Có thể kiểm tra git remote -v, trong đó cho bạn thấy tất cả nguồn gốc và thượng nguồn của chi nhánh hiện tại.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.