Как программно определить текущую выделенную ветвь Git

В среде сценариев Unix или GNU (например, дистрибутив Linux, Cygwin, OSX), каков наилучший способ определить, какая ветвь Git в настоящее время проверена в рабочем каталоге?

Одно использование этого метода будет автоматически помечать выпуск (например, svnversion будет делать с Subversion).

Также см. мой родственный вопрос: Как программно определить, является ли проверка Git тегом, и если да, то что такое имя тега?

Ответы

Ответ 1

Правильное решение - заглянуть в contrib/completions/git-completion.bash делает это для приглашения bash в __git_ps1. Удаление всех дополнительных функций, например, выбор способа описания ситуации с отсоединенным HEAD, т.е. Когда мы находимся в неназванной ветки, это:

branch_name="$(git symbolic-ref HEAD 2>/dev/null)" ||
branch_name="(unnamed branch)"     # detached HEAD

branch_name=${branch_name##refs/heads/}

git symbolic-ref используется для полного извлечения имя квалифицированной ветки с символической ссылкой; мы используем его для HEAD, который в настоящее время проверяется.

Альтернативное решение может быть:

branch_name=$(git symbolic-ref -q HEAD)
branch_name=${branch_name##refs/heads/}
branch_name=${branch_name:-HEAD}

где в последней строке мы имеем дело с ситуацией отдельно стоящего HEAD, используя просто "HEAD" для обозначения такой ситуации.


Добавлено 11-06-2013

Junio ​​C. Hamano (git supporter), Проверяя текущую ветвь программно, с 10 июня 2013 года объясняет whys (и hows) более подробно.

Ответ 2

Кто-нибудь видит что-то не так, просто спрашивая Git описать ветку, в которой вы находитесь?

git rev-parse --symbolic-full-name --abbrev-ref HEAD

Это может быть использовано в $() и легко передается в Bash, Powershell, Perl и т.д. Это не обмануто, если у вас есть несколько веток в фиксации, на котором вы находитесь, и если вы в данный момент не находитесь ветвь, она просто отвечает "HEAD".

В качестве альтернативы вы можете использовать

git symbolic-ref --short -q HEAD

Что даст вам тот же результат, но он не вернет ничего вообще, если вы отсоединились. Это полезно, если вы хотите, чтобы ошибка была отсоединена, просто удалите -q.

Ответ 3

вы можете использовать git name-rev --name-only HEAD

Ответ 4

Из этого ответа: fooobar.com/questions/2843/...:

$ git rev-parse --abbrev-ref HEAD
master

Очевидно, работает с Git 1.6.3 или новее.

Ответ 5

Попробуйте:

 git symbolic-ref --short -q HEAD

Или вы пытаетесь с помощью git branch с --no-color принудительно простую строку вывести:

 git branch  --no-color

С grep в режиме регулярного выражения (-E) вы можете проверить, существует ли символ '*':

 git branch  --no-color  | grep -E '^\*' 

Результаты аналогичны:

* currentBranch

Вы можете использовать следующие параметры:

sed 's/\*[^a-z]*//g'
cut -d ' ' -f 2
awk '{print $2}'

например:

 git branch  --no-color  | grep -E '^\*' | sed 's/\*[^a-z]*//g'
 git branch  --no-color  | grep -E '^\*' | sed cut -d ' ' -f 2
 git branch  --no-color  | grep -E '^\*' | awk '{print $2}'

Если существует ошибка, которую вы не можете использовать по умолчанию:

  cmd || echo 'defualt value';

Все в функцию bash:

function get_branch() {
      git branch --no-color | grep -E '^\*' | awk '{print $2}' \
        || echo "default_value"
      # or
      # git symbolic-ref --short -q HEAD || echo "default_value";
}

Использование:

branch_name=`get_branch`;
echo $branch_name;

Ответ 6

адаптация принятого ответа к окнам powershell:

Split-Path -Leaf (git symbolic-ref HEAD)

Ответ 7

Этот файл работал у меня в файле bash.

git branch | grep '^*' | sed 's/* //'  


################bash file###################
#!/bin/bash
BRANCH=$(git branch | grep '^*' | sed 's/* //' )
echo $BRANCH

Ответ 8

Этот работает для меня. Часть --no-color является или может быть важной, если вы хотите, чтобы простая строка вернулась.

git branch --no-color | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/'

Ответ 9

Вот что я делаю:

git branch | sed --quiet 's/* \(.*\)/\1/p'

Результат будет выглядеть так:

$ git branch | sed --quiet 's/* \(.*\)/\1/p'
master
$

Ответ 10

Я пытаюсь найти самый простой и понятный метод:

git status | grep "On branch" | cut -c 11-

Ответ 11

Я нашел два действительно простых способа сделать это:

$ git status | head -1 | cut -d ' ' -f 4

и

$ git branch | grep "*" | cut -d ' ' -f 2

Ответ 12

Кто-то упомянул о том, чтобы сделать это в bash с менее чем тремя присваиваниями... как насчет какого-то беспорядочного потока управления следующим образом:

branch_name="$(b=$(git symbolic-ref -q HEAD); { [ -n "$b" ] && echo ${b##refs/heads/}; } || echo HEAD)"

Ответ 13

Если вы используете старую командную строку NT, вы можете использовать следующее:

@for /f "usebackq" %i in (`git symbolic-ref -q HEAD`) do @echo %~ni

Чтобы использовать в пакетном файле, вам нужно удвоить%:

@for /f "usebackq" %%i in (`git symbolic-ref -q HEAD`) do @echo %%~ni

Ответ 14

Здесь мое решение, подходящее для использования в PS1, или для автоматической маркировки выпуска

Если вы извлечены в ветке, вы получите название ветки.

Если вы находитесь только в проекте init'd git, вы просто получаете '@'

Если вы без головы, вы получите хорошее человеческое имя относительно какой-либо ветки или тега, с именем "@", предшествующим имени.

Если вы без головы и не являетесь предком какой-либо ветки или тега, вы просто получаете короткий SHA1.

function we_are_in_git_work_tree {
    git rev-parse --is-inside-work-tree &> /dev/null
}

function parse_git_branch {
    if we_are_in_git_work_tree
    then
    local BR=$(git rev-parse --symbolic-full-name --abbrev-ref HEAD 2> /dev/null)
    if [ "$BR" == HEAD ]
    then
        local NM=$(git name-rev --name-only HEAD 2> /dev/null)
        if [ "$NM" != undefined ]
        then echo -n "@$NM"
        else git rev-parse --short HEAD 2> /dev/null
        fi
    else
        echo -n $BR
    fi
    fi
}

Вы можете удалить бит if we_are_in_git_work_tree, если хотите; Я просто использую его в другой функции в своем PS1, которую вы можете полностью просмотреть здесь: PS1-строка с git текущей ветвью и цветами

Ответ 15

Использование --porcelain позволяет легко выводить обратно-совместимый вывод:

git status --branch --porcelain | grep '##' | cut -c 4-

Из документации:

Формат фарфора похож на короткий формат, но гарантированно не изменяется в обратном-несовместимом режиме между версиями Git или на основе пользовательской конфигурации. Это делает его идеальным для синтаксического анализа скриптов.

https://git-scm.com/docs/git-status

Ответ 16

Я обнаружил, что вызов git довольно медленный (любой из подкоманд), особенно для обновления подсказки. Время варьируется между 0,1 и 0,2 секунды в корневом каталоге репо и более чем на 2 секунды за пределами репо на верхней метке (рейд 1, 8 ГБ оперативной памяти, 8 аппаратных потоков). Однако он запускает Cygwin.

Поэтому я написал этот script для скорости:

#!/usr/bin/perl

$cwd=$ENV{PWD}; #`pwd`;
chomp $cwd;

while (length $cwd)
{
        -d "$cwd/.git" and do {
                -f "$cwd/.git/HEAD" and do {
                        open IN, "<", "$cwd/.git/HEAD";
                        $_=<IN>;
                        close IN;
                        [email protected]: refs/heads/@@;
                        print $_;
                };
                exit;
        };

        [email protected]/[^/]*[email protected]@;
}

Может потребоваться настройка.

Ответ 17

Это одно решение. Если вы добавите его в свой .bashrc, он отобразит текущую ветку в консоли.

# git branch
parse_git_branch() {
    git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1) /'
}
$PS1="\$(parse_git_branch)$PS1"

Однако он довольно ограничен. Но есть большой проект под названием git sh, который делает именно это (и многое другое).

Ответ 18

Если вы используете gradle,

`` `

def gitHash = new ByteArrayOutputStream()    
project.exec {
                commandLine 'git', 'rev-parse', '--short', 'HEAD'
                standardOutput = gitHash
            }

def gitBranch = new ByteArrayOutputStream()   
project.exec {
                def gitCmd = "git symbolic-ref --short -q HEAD || git branch -rq --contains "+getGitHash()+" | sed -e '2,\$d'  -e 's/\\(.*\\)\\/\\(.*\\)\$/\\2/' || echo 'master'"
                commandLine "bash", "-c", "${gitCmd}"
                standardOutput = gitBranch
            }

`` `

Ответ 19

Если вы находитесь на отдельной голове (то есть вы проверили выпуск) и имеете выход из состояния git, например

HEAD detached at v1.7.3.1

И вы хотите версию выпуска, мы используем следующую команду...

git status --branch | head -n1 | tr -d 'A-Za-z: '

Это возвращает 1.7.3.1, который мы заменяем в наших параметрах .yml(Symfony) с

# RevNum=`svn status -u | grep revision | tr -d 'A-Za-z: '`  # the old SVN version
RevNum=`git status --branch | head -n1 | tr -d 'A-Za-z: '` # Git (obvs)

sed -i "/^    app_version:/c\    app_version:$RevNum" app/config/parameters.yml

Надеюсь, что это поможет:) Очевидно, что если у вас есть нечисловые числа в имени вашей ветки, вам нужно будет изменить аргументы команды tr.