Как узнать, какие ветки git отслеживают, какая ветка удаленной / восходящей?

Я знаю, что могу сделать git branch --all и это показывает мне как локальные, так и удаленные ветви, но это не так полезно, чтобы показать мне отношения между ними.

Как мне перечислить ветви таким образом, чтобы показать, какая локальная ветвь отслеживает, какая удаленная?

10 ответов

Решение

Очень много фарфоровых команд, не очень хорошо, если вы хотите это для сценариев:

git branch -vv   # doubly verbose!

Обратите внимание, что в git 1.8.3 эта ветка вверх по течению отображается синим цветом (см. " Что такое отслеживание ветвей (если вообще что-то) в git?")


Если вы хотите получить чистый вывод, посмотрите ответ arcresu - он использует фарфоровую команду, которая, как мне кажется, не существовала в то время, когда я изначально писал этот ответ, поэтому он немного более лаконичен и работает с ветвями, настроенными для rebase, а не просто для слияния.

git remote show origin

Замените "origin" на имя вашего пульта.

Если вы посмотрите на справочную страницу для git-rev-parse вы увидите следующий синтаксис:

<branchname>@{upstream} например, master@{upstream} , @{u}

Суффикс @{upstream} ответвлению (краткая форма <branchname>@{u}) относится к ветви, над которой ветка, указанная в 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
# ...

Это чище, чем разбор ссылок и настроек вручную.

Альтернатива ответу Куби - взглянуть на .git/config файл, который показывает конфигурацию локального репозитория:

cat .git/config

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

покажет линию для каждого местного филиала. Отслеживающая ветка будет выглядеть так:

master <- origin/master

Не отслеживающий будет выглядеть так:

test <- 

Для текущей ветви есть два хороших варианта:

% 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

Этот ответ также здесь, на немного другой вопрос, который был (ошибочно) отмечен как дубликат.

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

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

Вот аккуратный и простой. Могу проверить git remote -v, который показывает вам все происхождение и восходящий поток текущей ветви.

Я использую этот псевдоним

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

На основании ответа Оливье Рефало

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

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 config. Я просто использую 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"
Другие вопросы по тегам