Jak mogę zobaczyć, które gałęzie Git śledzą, która gałąź zdalna / nadrzędna?


824

Wiem, że potrafię git branch --alli pokazuje mi to zarówno oddziały lokalne, jak i zdalne, ale nie jest to przydatne do pokazywania mi relacji między nimi.

Jak wyświetlić listę oddziałów w sposób pokazujący, który oddział lokalny śledzi, który jest zdalny?

Odpowiedzi:


1142

Bardzo porcelanowe polecenie, niezbyt dobre, jeśli chcesz tego do skryptu:

git branch -vv   # doubly verbose!

Zauważ, że w git 1.8.3 ta gałąź nadrzędna jest wyświetlana na niebiesko (patrz „ Co to jest śledzenie tej gałęzi (jeśli w ogóle) w git? ”)


Jeśli chcesz uzyskać czysty wynik, zobacz odpowiedź arcresu - używa polecenia porcelany, które, jak sądzę, nie istniało w momencie, gdy pisałem tę odpowiedź, więc jest nieco bardziej zwięzłe i działa z gałęziami skonfigurowanymi do rebase, a nie tylko scalania.


3
Pierwsza powyższa metoda nie zapewnia mi pożądanych informacji. Drugi ... wydaje się przesadny, zwłaszcza, że ​​odpowiedź Kubi działa. Czy coś brakuje?
— garyp

3
@garyp Nie jesteś tym, który zadał pytanie. Pierwszy zapewnił to, czego potrzebował OP, a drugi dokładnie to , czego potrzebował, na wypadek, gdyby chciał to w czystej postaci do skryptu lub po prostu zapisać jako alias. („Overkill” jest w porządku, jeśli dostaniesz to, czego chcesz i nie musisz go powtarzać.) Z punktu widzenia tego pytania odpowiedź kubi zawiera pewne obce informacje, a jeśli jest więcej niż jeden pilot, to nie pokaż wszystko, ale jeśli spełnia twoje potrzeby, skorzystaj z niego.
— Cascabel,

2
Jestem winien przeprosiny. Kiedy pierwotnie uruchomiłem pierwszą metodę, nie otrzymałem żadnych informacji o tym, co śledzi, co powinienem wyraźnie powiedzieć. Ale teraz widzę informacje o śledzeniu, więc musiałem mieć coś nie tak z moją konfiguracją. Więc było czegoś brakuje.
— garyp

2
FWIW Byłem zdezorientowany, ponieważ -v i -vv pokazują podobne wyniki. Śledzona gałąź jest wyświetlana w nawiasach kwadratowych po skrócie i przed ostatnim zatwierdzeniem (w mojej domyślnej instalacji homebrew OSX).
— jerclarke

3
Dla mnie to wszystko polega na wydrukowaniu ostatniego skrótu zatwierdzenia i komentarza dla każdej gałęzi.
— capybaralet

263

git remote show origin

Zamień „origin” na dowolną nazwę pilota.


11
Mimo że to polecenie porcelany działa na człowieka (nie tyle na skrypt, co musiałoby parsować dane wyjściowe z porcelany), w tym podejściu nie podoba mi się to, że git remote showpolecenie faktycznie łączy się ze zdalnym repozytorium ... i dlatego zawiedzie, jeśli zdarzy się, że jesteś offline lub nie możesz połączyć się z repozytorium z jakiegokolwiek powodu ...
— pvandenberk

17
@pvandenberk Możesz użyć, git remote show -n originaby uzyskać pewne informacje, nawet w trybie offline. Z dokumentacji zdalnej git : „Przy opcji -n zdalne głowy nie są najpierw pytane o git ls-remote <nazwa>; zamiast tego używane są informacje buforowane.”
— Cerran,

5
Jedna dziwna rzecz w tym poleceniu: wyświetla zdalne gałęzie jako „śledzone”, nawet jeśli nie ma skonfigurowanej gałęzi lokalnej dla pull / push. Zawsze uważam to za mylące. Właściwie nie jestem pewien, co w tym wydaniu ma oznaczać „śledzony”. Dokumenty git na ten temat sprawiają, że brzmi to tak, jakby zdalna gałąź jest „śledzona” tylko wtedy, gdy jest połączona / powiązana z lokalną gałęzią w celu push / pull ...
— Hawkeye Parker

Problem polega na tym, że muszę zadzwonić do wszystkich zdalnych nazw, dopóki nie zobaczę, czego tak naprawdę szukam.
— jolvi

2
@jolvi Możesz uruchomić, git remote show | xargs git remote show -naby wyświetlić połączone informacje o śledzeniu dla wszystkich pilotów.
— Synoli

107

Jeśli spojrzysz na stronę podręcznika git-rev-parse, zobaczysz następującą składnię:

<branchname>@{upstream}Np master@{upstream},@{u}

Sufiks @{upstream}do nazwy gałęzi (skrócona forma <branchname>@{u}) odnosi się do gałęzi, na której odgałęzienie określone przez nazwę gałęzi jest ustawione. Brakująca nazwa gałęzi jest domyślnie ustawiona na bieżącą.

Aby znaleźć górę oddziału master, wykonaj następujące czynności:

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

Aby wydrukować informacje dla każdego oddziału, możesz zrobić coś takiego:

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

Jest to czystsze niż ręczne analizowanie referencji i konfiguracji.


Nie mogłem zrozumieć tego fragmentu podczas analizy, mimo że go znalazłem, więc dziękuję za jasne wyjaśnienie!
— Alice Purcell,

3
Dla tych z nas, którzy używają git-flow, z gałęziami o nazwie „feature / blahblah”, instrukcja zamykająca pętli while powinna brzmieć: done < <(git for-each-ref --format='%(refname:short)' refs/heads/**)Zwróć uwagę na dwie gwiazdki na końcu wzorca globu.
— markeissler

2
git rev-parse --abbrev-ref HEAD@{upstream}wydaje się działać dobrze dla obecnego oddziału. To także tworzy miły alias git.
— Digikata,

whileSkładnia pętli wygląda nieco dziwne dla mnie. Możesz po prostu użyć, git for-each-ref ... | while read branch; do ...który nie wymaga FIFO i działa w tej samej kolejności, co napisane polecenia.
— Daniel Böhmer

Przynajmniej od wersji git 2.5.1 masz jedno-liniowy zgit for-each-ref --format='%(refname:short) tracks %(upstream:short)' refs/heads/*
— Mat M

81

Alternatywą dla odpowiedzi kubi jest obejrzenie .git/configpliku, który pokazuje konfigurację lokalnego repozytorium:

cat .git/config


6
Również git config --get-regex branch
— Tamir Daniely

6
Lub dokładniej: „git config --get-regexp branch. * Merge”
— yoyo

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

pokaże wiersz dla każdego oddziału lokalnego. Oddział śledzenia będzie wyglądał następująco:

master <- origin/master

Bez śledzenia będzie wyglądać następująco:

test <- 

Fajnie, aby dodać trochę uporządkowania i danych wyjściowych TAB: git for-each-ref --sort upstream --format = '% (refname: short)% 09 <-% (upstream: short)' refs / heads
— dimir

Pięknie zwięzłe, a wynik jest w rzeczywistości znacznie bardziej czytelny niż zaakceptowany git branch -vv. 🙏
— joki,

Jedynym problemem jest to, że nie pamiętam tego, więc użyłemgit config --global alias.track 'for-each-ref --format='\''%(refname:short) <- %(upstream:short)'\'' refs/heads'
— joki,

38

Dla aktualnej gałęzi, oto dwie dobre opcje:

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

lub

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

Ta odpowiedź znajduje się również tutaj na nieco inne pytanie, które (błędnie) zostało oznaczone jako duplikat.


5
Na tej podstawie wszystkie branże mogą być wymienione w skrypcie przyjazny sposób: git for-each-ref --shell --format='%(refname:short) %(upstream:short)' refs/heads.
— Daniel James

15

W przypadku bieżącego oddziału można również powiedzieć git checkout(bez żadnego oddziału). Jest to brak operacji z efektami ubocznymi, aby wyświetlić informacje o śledzeniu, jeśli istnieją, dla bieżącej gałęzi.

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

W porządku, ale możesz przypadkowo wpisać git checkout ., co nie jest żadną opcją.
— Tomasz Gandor

6

Używam tego aliasu

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'

następnie

git track

5
Myślę, że warto zauważyć, że z dwoma parametrami twoje polecenie konfiguruje gałąź ścieżki.
— albfan,

3

Na podstawie odpowiedzi Oliviera 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

Pokazuje tylko lokalnie ze skonfigurowaną ścieżką.

Napisz go na skrypcie o nazwie git-track na swojej ścieżce, a otrzymasz polecenie git track

Bardziej rozbudowana wersja na https://github.com/albfan/git-showupstream


1

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

poda nazwę śledzonego pilota

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

poda nazwę oddziału, który jest śledzony.

Musisz zastąpić $ current_branch nazwą swojej aktualnej gałęzi. Możesz uzyskać to dynamicznie za pomocągit rev-parse --abbrev-ref HEAD

Poniższy mini-skrypt łączy te rzeczy. Umieść go w pliku o nazwie git-tracking, spraw , by był wykonywalny i upewnij się, że znajduje się na twojej ścieżce.

wtedy możesz powiedzieć

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

zwróć uwagę, że nazwa oddziału zdalnego może różnić się od nazwy oddziału lokalnego (choć zazwyczaj nie jest). Na przykład:

$git tracking 
xxx_xls_xslx_thing -> origin/totally_bogus

jak widać w kodzie, kluczem do tego jest wyodrębnienie danych z konfiguracji git. Po prostu używam sed, aby usunąć zbędne dane.

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

Oto schludny i prosty. Może sprawdzić git remote -v, który pokazuje wszystkie pochodzenie i upstream bieżącego oddziału.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.