Як я можу побачити, які гілки Git відстежують, яку віддалену / висхідну гілку?


824

Я знаю, що можу зробити git branch --all, і це показує мені як місцеві, так і віддалені гілки, але це не так корисно, щоб показувати мені відносини між ними.

Як перелічити гілки таким чином, що показує, яка локальна гілка відстежує, яку віддалену?

Відповіді:


1143

Дуже сильно порцелянова команда, непогано, якщо ви хочете це для сценаріїв:

git branch -vv   # doubly verbose!

Зауважте, що з git 1.8.3 ця гілка вгору за течією відображається синім кольором (див. " Що це за відстеження гілки (якщо щось таке) в git? "


Якщо ви хочете чистого результату, дивіться відповідь arcresu - він використовує фарфорову команду, на яку я не вірю, що існувала в той час, коли я спочатку писав цю відповідь, тому це трохи більш стисло і працює з гілками, налаштованими на ребазацію, а не просто злиття.


3
Перший метод, що описаний вище, не дає мені потрібної інформації. Друга ... здається непосильною, оскільки відповідь Кубі працює. Я щось пропускаю?
garyp

3
@garyp Ви не той, хто задав питання. Перший забезпечував те, що потрібно ОП, а другий - саме те , що йому потрібно, на випадок, якщо він хотів це в чистому вигляді для сценаріїв, або хотів просто зберегти його як псевдонім. ("Overkill" добре, якщо він отримує те, що ви хочете, і вам не доведеться повторювати це.) З точки зору цього питання, відповідь кубі дає деяку сторонні відомості, і якщо є більше ніж один віддалений, він не Не показуйте все, але якщо воно відповідає вашим потребам, будь-ласка, використовуйте його.
Каскабель

2
Я завдячую вибаченням. Коли я спочатку використовував перший метод, я не отримав жодної інформації про те, що відслідковує, і я повинен був це чітко заявити. Але тепер я бачу інформацію про відстеження, тож, мабуть, у мене щось не так. Так що я був що - то НЕ вистачає.
garyp

2
FWIW я був розгублений, тому що -v та -vv показують подібний вихід. Відстежена гілка відображається у квадратних дужках після хешу та перед останньою фіксацією (у моєму встановленні домашньої програми OSX за замовчуванням).
jerclarke

3
Все це для мене - це роздрукувати останній хеш комітів та коментарі для кожної гілки.
capybaralet

263

git remote show origin

Замініть "походження" будь-якою назвою вашого пульта.


11
Навіть незважаючи на те, що ця порцелянова команда ніби працює для людини (не стільки для сценарію, скільки би довелося розбирати вихід порцеляни), що мені не подобається в цьому підході, це те, що git remote showкоманда насправді підключається до віддаленого репо ... а значить, це не вдасться, якщо ви трапляєтесь в режимі офлайн або не можете підключитися до репо з будь-якої причини ...
pvandenberk

17
@pvandenberk Ви можете використовувати git remote show -n originдля отримання інформації навіть у режимі офлайн. З документації на git remote : "З опцією -n віддалені голови спочатку не запитуються за допомогою git ls-remote <ім'я>; використовується кешована інформація."
Серран

5
Про цю команду є одна дивна річ: вона відображає віддалені гілки як "відслідковані", навіть якщо немає локальної гілки, налаштованої для "pull / push". Я завжди вважаю це заплутаним. Мені фактично не зрозуміло, що має означати "відслідковане" у цьому висновку. Документи Git з цього приводу дозволяють здатися, що віддалене відділення "відслідковується" лише тоді, коли воно пов'язане / прив'язане до локальної гілки для push / pull ...
Hawkeye Parker

Проблема полягає в тому, що мені потрібно називати це для всіх віддалених імен, поки я не побачу, що насправді шукаю.
jolvi

2
@jolvi Ви можете бігти, git remote show | xargs git remote show -nщоб переглянути комбіновану інформацію відстеження для всіх віддалених.
Синолі

107

Якщо ви подивитеся на сторінку чоловіка для git-rev-parse, ви побачите, як описаний наступний синтаксис:

<branchname>@{upstream}, наприклад master@{upstream},@{u}

Суфікс @{upstream}до назви гілки (коротка форма <branchname>@{u}) відноситься до гілки, яку гілка, визначена іменем гілки, встановлюється на вершині. Відсутнє ім'я гілки за замовчуванням до поточного.

Отже, щоб знайти верхню частину гілки 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
# ...

Це чистіше, ніж розбір посилань та налаштування вручну.


Я не міг зрозуміти цей біт у rev-розборі, незважаючи на те, що знайшов його, тому дякую за чітке пояснення!
Еліс Перселл

3
Для тих із нас, хто використовує git-flow, із гілками, названими "особливість / blahblah", заключне висловлювання циклу while має бути таким: " done < <(git for-each-ref --format='%(refname:short)' refs/heads/**)Зверніть увагу на дві зірочки в кінці шаблону глобуса.
markeissler

2
git rev-parse --abbrev-ref HEAD@{upstream}здається, добре працює для поточної галузі. Це також робить гарний псевдонім git.
Digikata

whileСинтаксис циклу виглядає трохи дивно для мене. Ви можете просто використовувати те, git for-each-ref ... | while read branch; do ...що не потребує FIFO, і працює в тому ж порядку, як і написані команди.
Даніель Бьомер

Принаймні, з 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
Тамір Даніелі

6
Або, точніше, 'git config --get-regexp branch. * Merge'
yoyo

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

покаже рядок для кожної місцевої гілки. Гілка відстеження виглядатиме так:

master <- origin/master

Недосліджуючий виглядатиме так:

test <- 

Ніцца, щоб додати деяке впорядкування і вихід TAB-ліжко: мерзотник для-кожного-вих --sort перед --format = '% (refname: короткі)% 09 <-% (вгору по течії: коротка)' REFS / головок
Dimir

Красиво стисло і результат насправді набагато читає, ніж прийнятий git branch -vv. 🙏
жокі

Єдина проблема полягає в тому, що я не можу цього згадати, тому я скористався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.
Даніель Джеймс

15

Для поточної гілки ви також можете сказати git checkout(без будь-якої гілки). Це неоперативний варіант із побічними ефектами для показу інформації відстеження, якщо вона існує, для поточної гілки.

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

Досить справедливо, але ви можете випадково набрати git checkout ., що не є опціоном.
Томаш

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
Думаю, варто відзначити, що з двома параметрами ваша команда налаштовує гілку треку.
Альффан

3

На основі відповіді Олів'є Рефало

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

Наступний міні-сценарій поєднує в собі ці речі. Вставте його у файл з назвою 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, що показує вам усе походження та вище поточного відділення.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.