Как получить информацию о каждой ветке моего git локального репозитория - PullRequest
4 голосов
/ 09 апреля 2020

Это то, что git branch -v производит в одном из моих локальных каталогов

* develop e229f7a Merge branch 'develop' of https://github.com/me/myremote-repo.git into develop Some diffs
  master  3343dea [behind 2] Added git-log, same as git_log without colorization

Я пытаюсь go через набор ветвей и вывод этой команды, и если вывод содержит [впереди n] или [позади m], я хочу выпустить выражение вроде:

[behind 2] --> bin [master] 3343dea
[ahead 1]  --> bin [develop] 99345b

для каждой ветви, если она содержит впереди или сзади.

В настоящее время в моем коде есть следующее :

MOD=`git branch -v | perl -wlne '/^..(\S+)\s+([a-f0-9]+)\s+(\[ahead\s+\d+\]|\[behind\s+\d+\])/ or next; print  "$3 --> $ENV{reponame} [$1] $2"; '`;

    [ ! -z "$MOD" ] &&  MOD="$MOD" | ok=false
    if $ok; then
        echo " OK --> $reponame [$br]"
    else
       # a series of UGLY HACKs to get pretty-printing
       MOD=`echo "$MOD" | tr -d '\011\012\015' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//'` | sed -e 's/]#/]\
 #/'
       if [ ! -z "$MOD" ]; then
          echo -e " $MOD" && continue
       fi
    fi


 bin [develop] --> Out of sync with origin/HEAD at /Users/me/bin
 bin [develop] --> Changes to be staged/committed at /Users/me/bin
 [behind 2] --> bin [master] 3343dea
 OK --> patti [develop]
 OK --> notes [master]
 OK --> indecks [develop]
 OK --> queue [develop]
 OK --> frameworks [develop]
 OK --> nodejs [master]
 OK --> perl-forth [develop]
 OK --> patti [master]
 OK --> blog [develop]

Проблема в том, что я получаю только первое. Если есть две ветви с опережением или отставанием, я получу только первую. Я пробовал несколько способов получить вывод из git branch -v в массив, а затем перебрать массив и, если он соответствует шаблону, выполнить печать. Проблема в том, что я не могу найти способ получить вывод в массив таким образом, который работает. Когда я перебираю массив, я получаю список всех файлов.

Я использую:

branches={`git branch -v`)
for i in "${branches[@]}"
do
    echo "$i"
done

Я получаю список всех файлов в каталоге!

Почему и что мне делать?

Ответы [ 2 ]

4 голосов
/ 09 апреля 2020

Используйте read в while l oop, чтобы получить строки из perl в MOD по одной.

git branch -v |
perl -wlne'
   print "$3 --> $ENV{reponame} [$1] $2"
      if /^..(\S+)\s+([a-f0-9]+)\s+(\[(?:ahead|behind)\s+\d+\])/
' |
while IFS= read -r MOD; do
   printf '{%s}\n' "$MOD"  # Replace with code that uses $MOD
done
3 голосов
/ 09 апреля 2020

Я думаю, что вы можете пройти большую часть пути без perl или awk, указав формат для git вывода ветви . Обратите внимание, что $REPONAME интерполируется оболочкой, потому что я использую строку в двойных кавычках. Материал в %(...) является частью git форматирования:

$ export REPONAME=bin
$ git branch --format "%(upstream:track) --> $REPONAME [%(refname:short)] %(objectname:short=6)" | grep '^\['
[behind 15] --> bin [master] 5b1e08

Я не очень много работал над этим, чтобы избавиться от строк, где ветка актуальна, поэтому я наказывается до grep.

$ git branch --format "%(upstream:track) --> $REPONAME [%(refname:short)] %(objectname:short=6)"
  --> bin [a] 5b1e08
  --> bin [briandfoy/how-to-install-perl] 1d7456
[behind 15] --> bin [master] 5b1e08

Вы можете добавить логи c, но я не дошел до того, что не выводил пустые строки:

$ git branch --format "%(if)%(upstream:track)%(then)%(upstream:track) --> $REPONAME [%(refname:short)] %(objectname:short=6)%(else)%(end)"


[behind 15] --> bin [master] 5b1e08

Но, думаю, в вашем комментарий к ikegami Вы хотели, чтобы в современных ветках было "ОК". Измените if-then-else, чтобы он охватывал только первый столбец, и всегда выводите остальные:

$ git branch --format "%(if)%(upstream:track)%(then)%(upstream:track)%(else)OK%(end) --> $REPONAME [%(refname:short)] %(objectname:short=6)"
OK --> bin [a] 5b1e08
OK --> bin [briandfoy/some_feature] 1d7456
[behind 15] --> bin [master] 5b1e08

Если вам нужна какая-то другая строка для несинхронных ветвей c, просто измените эту ветвь if-then-else:

$ git branch --format "%(if)%(upstream:track)%(then)Out of sync%(else)OK%(end) --> $REPONAME [%(refname:short)] %(objectname:short=6)"
OK --> bin [a] 5b1e08
OK --> bin [briandfoy/some_feature] 1d7456
Out of sync --> bin [master] 5b1e08

Вы можете поместить весь формат в его собственную переменную, но вы должны быть осторожны с этим, потому что он интерполирует $REPONAME. Вам придется установить $FORMAT на репо. Я думаю, что это немного легче переварить:

$ export FORMAT="%(if)%(upstream:track)%(then)%(upstream:track)%(else)OK%(end) --> $REPONAME [%(refname:short)] %(objectname:short=6)"
$ git branch --format "$FORMAT"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...