Как программно определить текущую извлеченную ветку Git
В среде сценариев Unix или GNU (например, дистрибутив Linux, Cygwin, OSX), каков наилучший способ определить, какая ветвь Git в настоящее время извлекается в рабочем каталоге?
Одним из применений этой техники будет автоматическая маркировка релиза (например, svnversion
будет делать с Subversion).
Пожалуйста, посмотрите также мой связанный вопрос: Как программно определить, является ли Git checkout тегом, и если да, то каково имя тега?
20 ответов
Правильное решение состоит в том, чтобы взглянуть на contrib / завершении или git-extension.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" для обозначения такой ситуации.
Добавлено 06.11.2013
В блоге Junio C. Hamano (git keeper), посвященном программной проверке текущей ветки от 10 июня 2013 года, объясняется, почему (и как) более подробно.
Кто-нибудь видит что-то не так, просто попросив Git описать ветку, в которой вы находитесь?
git rev-parse --symbolic-full-name --abbrev-ref HEAD
Это можно использовать в $() и легко передавать в Bash, Powershell, Perl и т. Д. Это не обманывает, если у вас есть несколько веток на коммите, на котором вы находитесь, и если вы в данный момент не находитесь на ветке, это просто отвечает "ГОЛОВА".
Кроме того, вы можете использовать
git symbolic-ref --short -q HEAD
Который даст вам тот же результат, но он ничего не вернет, если вы отстранены. Это полезно, если вы хотите, чтобы при отсоединении возникла ошибка, просто удалите -q.
Из этого ответа: /questions/36505409/pokazat-tolko-tekuschuyu-vetku-v-git/36505433#36505433:
$ git rev-parse --abbrev-ref HEAD
master
Видимо работает с Git 1.6.3 или новее.
Попробуйте с:
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;
Этот работал для меня в файле Bash.
git branch | grep '^*' | sed 's/* //'
################bash file###################
#!/bin/bash
BRANCH=$(git branch | grep '^*' | sed 's/* //' )
echo $BRANCH
Адаптация принятого ответа к Windows PowerShell:
Split-Path -Leaf (git symbolic-ref HEAD)
Вот что я делаю:
git branch | sed --quiet 's/* \(.*\)/\1/p'
Вывод будет выглядеть так:
$ git branch | sed --quiet 's/* \(.*\)/\1/p'
master
$
Этот работает для меня. --no-color
part важен или может быть важен, если вы хотите вернуть простую строку.
git branch --no-color | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/'
Я пытаюсь найти самый простой и понятный способ:
git status | grep "On branch" | cut -c 11-
Использование --porcelain позволяет легко анализировать обратно-совместимые выходные данные:
git status --branch --porcelain | grep '##' | cut -c 4-
Из документации:
Фарфоровый формат подобен короткому формату, но гарантированно не изменится обратно-несовместимым способом между версиями Git или в зависимости от конфигурации пользователя. Это делает его идеальным для анализа скриптами.
Я нашел два действительно простых способа сделать это:
$ git status | head -1 | cut -d ' ' -f 4
а также
$ git branch | grep "*" | cut -d ' ' -f 2
Те же результаты, что и принятый ответ в однострочном присвоении переменной:
branch_name=$((git symbolic-ref HEAD 2>/dev/null || echo "(unnamed branch)")|cut -d/ -f3-)
Вот мое решение, подходящее для использования в PS1 или для автоматической маркировки релиза
Если вы проверены в филиале, вы получите название филиала.
Если вы находитесь в проекте initit 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 и цветами
Если вы используете старую командную строку 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
Кто-то упоминал, что делает это в bash менее чем с тремя назначениями... как насчет некоторого грязного потока управления, подобного этому:
branch_name="$(b=$(git symbolic-ref -q HEAD); { [ -n "$b" ] && echo ${b##refs/heads/}; } || echo HEAD)"
Если вы используете 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
}
`` `
Я обнаружил, что вызов git довольно медленный (любая из подкоманд), особенно для обновления приглашения. Время варьируется от 0,1 до 0,2 секунды в корневом каталоге репо и более 0,2 секунды вне репо на высококлассном компьютере (рейд 1, оперативная память 8 Гб, 8 аппаратных потоков). Тем не менее, он запускает Cygwin.
Поэтому я написал этот скрипт для скорости:
#!/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;
s@ref: refs/heads/@@;
print $_;
};
exit;
};
$cwd=~s@/[^/]*$@@;
}
Может понадобиться немного подправить.
Это одно решение. Если вы добавите его в ваш.bashrc, он отобразит текущую ветку в консоли.
# git branch
parse_git_branch() {
git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1) /'
}
$PS1="\$(parse_git_branch)$PS1"
Однако это довольно ограничено. Но есть отличный проект под названием git sh, который делает именно это (и многое другое).
Если у вас отдельная голова (то есть вы вынули релиз) и у вас есть выход из состояния git, например:
HEAD detached at v1.7.3.1
И вы хотите версию выпуска, мы используем следующую команду...
git status --branch | head -n1 | tr -d 'A-Za-z: '
Это возвращает 1.7.3.1, который мы заменим в нашем parameters.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.