Перечисление каждой ветви и даты ее последней редакции в git
Мне нужно удалить старые и неподдерживаемые ветви из нашего удаленного РЕПО. Я пытаюсь найти способ, с помощью которого можно перечислить удаленные ветви по их последней измененной дате, и я не могу.
кто-нибудь знает простой способ перечислить удаленные ветви таким образом?
10 ответов:
commandlinefu есть 2 интересных предложения:
for k in `git branch | perl -pe s/^..//`; do echo -e `git show --pretty=format:"%Cgreen%ci %Cblue%cr%Creset" $k -- | head -n 1`\t$k; done | sort -r
или:
for k in `git branch | sed s/^..//`; do echo -e `git log -1 --pretty=format:"%Cgreen%ci %Cblue%cr%Creset" $k --`\t"$k";done | sort
то есть для локальных ветвей, в синтаксисе Unix. Используя
git branch -r
, вы можете также показать удаленные ветви:for k in `git branch -r | perl -pe 's/^..(.*?)( ->.*)?$//'`; do echo -e `git show --pretty=format:"%Cgreen%ci %Cblue%cr%Creset" $k -- | head -n 1`\t$k; done | sort -r
Майкл Форрест упоминает в комментариях что zsh требует побегов для
sed
выражение:for k in git branch | perl -pe s\/\^\.\.\/\/; do echo -e git show --pretty=format:"%Cgreen%ci %Cblue%cr%Creset" $k -- | head -n 1\t$k; done | sort -r
kontinuity добавляет в комментарии:
если вы хотите добавить его в свой zshrc, необходим следующий побег.
alias gbage='for k in `git branch -r | perl -pe '\''s/^..(.*?)( ->.*)?$//'\''`; do echo -e `git show --pretty=format:"%Cgreen%ci %Cblue%cr%Creset" $k -- | head -n 1`\t$k; done | sort -r'
в несколько строк:
alias gbage='for k in `git branch -r | \ perl -pe '\''s/^..(.*?)( ->.*)?$//'\''`; \ do echo -e `git show --pretty=format:"%Cgreen%ci %Cblue%cr%Creset" $k -- | \ head -n 1`\t$k; done | sort -r'
вот что я использую:
git for-each-ref --sort='-committerdate:iso8601' --format=' %(committerdate:iso8601)%09%(refname)' refs/heads
это выход:
2014-01-22 11:43:18 +0100 refs/heads/master 2014-01-22 11:43:18 +0100 refs/heads/a 2014-01-17 12:34:01 +0100 refs/heads/b 2014-01-14 15:58:33 +0100 refs/heads/maint 2013-12-11 14:20:06 +0100 refs/heads/d/e 2013-12-09 12:48:04 +0100 refs/heads/f
для работы с удаленными филиалами, просто использовать "РЭС/пульты" вместо "РЭС/руководители":
git for-each-ref --sort='-committerdate:iso8601' --format=' %(committerdate:iso8601)%09%(refname)' refs/remotes
вы можете позвонить "git fetch --prune", прежде чем получить последнюю информацию.
просто добавьте к комментарию @VonC, возьмите предпочтительное решение и добавьте его в свой ~/.список псевдонимов gitconfig для удобства:
[alias] branchdate = !git for-each-ref --sort='-authordate' --format='%(refname)%09%(authordate)' refs/heads | sed -e 's-refs/heads/--'
затем простой "git branchdate" печатает список для вас...
строительство Оливье Крокеты, мне нравится использовать относительную дату и сокращать имя ветви следующим образом:
git for-each-ref --sort='-authordate:iso8601' --format=' %(authordate:relative)%09%(refname:short)' refs/heads
что дает вам выход:
21 minutes ago nathan/a_recent_branch 6 hours ago master 27 hours ago nathan/some_other_branch 29 hours ago branch_c 6 days ago branch_d
Я рекомендую сделать файл bash для добавления всех ваших любимых псевдонимов, а затем поделиться сценарием с вашей командой. Вот пример, чтобы добавить только этот:
#!/bin/sh git config --global alias.branches "!echo ' ------------------------------------------------------------' && git for-each-ref --sort='-authordate:iso8601' --format=' %(authordate:relative)%09%(refname:short)' refs/heads && echo ' ------------------------------------------------------------'"
затем вы можете просто сделать это, чтобы получить красиво отформатированный и отсортированный список местного отделения:
git branches
отсортированный remote ветви и последняя дата фиксации для каждой ветви.
for branch in `git branch -r | grep -v HEAD`;do echo -e `git show --format="%ci %cr" $branch | head -n 1` \t$branch; done | sort -r
вот что я придумал после того, как также рассмотрел этой.
for REF in $(git for-each-ref --sort=-committerdate --format="%(objectname)" \ refs/remotes refs/heads) do if [ "$PREV_REF" != "$REF" ]; then PREV_REF=$REF git log -n1 $REF --date=short \ --pretty=format:"%C(auto)%ad %h%d %s %C(yellow)[%an]%C(reset)" fi done
The
PREV_REF
проверка заключается в удалении дубликатов, если несколько ветвей указывают на одну и ту же фиксацию. (Как и в локальной ветке, которая существует и в удаленной.)обратите внимание, что по запросу OP,
git branch --merged
иgit branch --no-merged
полезны в определении того, какие ветви могут быть легко удалены. [https://git-scm.com/docs/git-branch]
Я сделал два варианта, основываясь на ответе VonC.
первый вариант:
for k in `git branch -a | sed -e s/^..// -e 's/(detached from .*)/HEAD/'`; do echo -e `git log -1 --pretty=format:"%Cgreen%ci |%Cblue%cr |%Creset$k |%s" $k --`;done | sort | column -t -s "|"
Это обрабатывает локальные и удаленные ветви (- a), обрабатывает состояние отсоединенной головки (более длинная команда sed, хотя решение является грубым-она просто заменяет информацию о отсоединенной ветви ключевым словом HEAD), добавляет в тему фиксации (%s) и помещает вещи в столбцы через литеральные символы канала в строке формата и передает конечный результат в
column -t -s "|"
. (Вы могли бы использовать все, как разделитель, пока это то, что вы не ожидаете в остальной части вывода.)мой второй вариант довольно хаки, но я действительно хотел что-то, что все еще имеет индикатор "это ветка, в которой вы сейчас находитесь", как это делает команда branch.
CURRENT_BRANCH=0 for k in `git branch -a | sed -e 's/\*/CURRENT_BRANCH_MARKER/' -e 's/(detached from .*)/HEAD/'` do if [ "$k" == 'CURRENT_BRANCH_MARKER' ]; then # Set flag, skip output CURRENT_BRANCH=1 elif [ $CURRENT_BRANCH == 0 ]; then echo -e `git log -1 --pretty=format:"%Cgreen%ci |%Cblue%cr |%Creset$k |%s" $k --` else echo -e `git log -1 --pretty=format:"%Cgreen%ci |%Cblue%cr |%Creset* %Cgreen$k%Creset |%s" $k --` CURRENT_BRANCH=0 fi done | sort | column -t -s "|"
это превращает*, который отмечает текущую ветвь в Ключевое слово, и когда тело цикла видит ключевое слово, оно вместо этого устанавливает флаг и ничего не выводит. Флаг используется для обозначения того, что альтернативный форматирование должно использоваться для следующей строки. Как я уже сказал, полностью хаки, но это работает! (По большей части. По какой-то причине моя последняя колонка становится устаревшей на текущей ветке. Но я действительно должен вернуться к реальной работе, а не настраивать это больше.)
вот функция, которую вы можете добавить в свой bash_profile, чтобы сделать это проще.
использование в репозитории git:
:
branch
выводит все локальные ветвиbranch -r
печатает все удаленные веткиbranch() { local pattern="s/^..//" local arg="" if [[ $@ == "-r" ]]; then pattern="s/^..(.*?)( ->.*)?$//" arg=" -r " echo '-r provided' fi for k in $(git branch $arg | perl -pe "$pattern"); do echo -e $(git show --pretty=format:"%Cgreen%ci %Cblue%cr%Creset" $k -- | head -n 1)\t$k done | sort -r }
в Powershell отображаются ветви на удаленном устройстве, которые уже объединены и которым не менее двух недель. (автор:относительный формат начинает отображать недели вместо дней в две недели)
$safeBranchRegex = "origin/(HEAD|master|develop)$"; $remoteMergedBranches = git branch --remote --merged | %{$_.trim()}; git for-each-ref --sort='authordate:iso8601' --format=' %(authordate:relative)%09%(refname:short)' refs/remotes | ?{$_ -match "(weeks|months|years) ago" -and $_ -notmatch "origin/(HEAD|master|qa/)"} | %{$_.substring($_.indexof("origin/"))} | ?{$_ -in $remoteMergedBranches}
или вы можете использовать мой PHP скрипт https://gist.github.com/2780984
#!/usr/bin/env php <?php $local = exec("git branch | xargs "); $lines = explode(" ", $local); $limit = strtotime("-2 week"); $exclude = array("*", "master"); foreach ($exclude as $i) { $k = array_search($i, $lines); unset($lines[$k]); } $k = 0; foreach ($lines as $line) { $output[$k]['name'] = $line; $output[$k]['time'] = exec('git log '.$line.' --pretty=format:"%at" -1'); if ($limit>$output[$k]['time']) { echo "This branch should be deleted $line\n"; exec("git branch -d $line"); } $k++; }