Перечисление каждой ветви и даты ее последней редакции в git - PullRequest
123 голосов
/ 25 марта 2010

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

Кто-нибудь знает простой способ составления списка удаленных веток таким образом?

Ответы [ 10 ]

156 голосов
/ 25 марта 2010

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/^..(.*?)( ->.*)?$/\1/'`; 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 

континуиты добавляет в комментарии :

Если вы хотите добавить его в zshrc, вам потребуется следующий escape.

alias gbage='for k in `git branch -r | perl -pe '\''s/^..(.*?)( ->.*)?$/\1/'\''`; 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/^..(.*?)( ->.*)?$/\1/'\''`; \
  do echo -e `git show --pretty=format:"%Cgreen%ci %Cblue%cr%Creset" $k -- | \
     head -n 1`\\t$k; done | sort -r'
100 голосов
/ 23 января 2014

Вот что я использую:

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

Для удаленных филиалов, просто используйте «refs / remotes» вместо «refs /head»:

git for-each-ref --sort='-committerdate:iso8601' --format=' %(committerdate:iso8601)%09%(refname)' refs/remotes

Возможно, вы захотите вызвать "git fetch --prune", чтобы получить самую свежую информацию.

20 голосов
/ 30 мая 2014

Построение из Оливье Крокетт , мне нравится использовать относительную дату и сокращать название филиала следующим образом:

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
19 голосов
/ 27 февраля 2013

Просто добавьте к комментарию @VonC, выберите предпочитаемое решение и добавьте его в свой список псевдонимов ~ / .gitconfig:

[alias]  
    branchdate = !git for-each-ref --sort='-authordate' --format='%(refname)%09%(authordate)' refs/heads | sed -e 's-refs/heads/--'

Затем простая «git branchdate» распечатывает список для вас ...

4 голосов
/ 18 июня 2015

Вот то, что я придумал после того, как также рассмотрел this .

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

Проверка PREV_REF предназначена для удаления дубликатов, если более одного ветвления указывают на один и тот же коммит. (Как и в локальном филиале, также существующем в удаленном.)

Обратите внимание, что в соответствии с запросом OP git branch --merged и git branch --no-merged полезны для определения того, какие ветви можно легко удалить. [https://git -scm.com / Docs / ГИТ-ветви]

3 голосов
/ 01 июня 2015

Сортировка удаленные ветви и дата последнего принятия для каждой ветви.

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
1 голос
/ 06 ноября 2014

Я сделал два варианта, основываясь на ответе 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 "|". (Вы можете использовать что угодно в качестве разделителя, если это не то, что вы ожидаете в остальной части вывода.)

Мой второй вариант довольно хакерский, но я действительно хотел что-то, что все еще имеет индикатор «это ветвь, в которой вы сейчас находитесь», как это делает команда ветвления.

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 "|"

Это превращает *, отмечающий текущую ветвь, в ключевое слово, и когда тело цикла видит ключевое слово, оно вместо этого устанавливает флаг и ничего не выводит. Флаг используется для указания того, что для следующей строки следует использовать альтернативное форматирование. Как я уже сказал, совершенно взломан, но это работает! (В основном. По какой-то причине мой последний столбец устарел на текущей ветке. Но я действительно должен вернуться к выполнению реальной работы, а не настраивать это больше.)

0 голосов
/ 24 января 2017

В 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}
0 голосов
/ 14 марта 2016

Вот функция, которую вы можете добавить в свой bash_profile, чтобы сделать это проще.

Использование в git-хранилище:

  • branch печатает все местные филиалы
  • branch -r печатает все удаленные ветви

Функция:

branch() {
   local pattern="s/^..//"
   local arg=""
   if [[ $@ == "-r" ]]; then
      pattern="s/^..(.*?)( ->.*)?$/\1/"
      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
}
0 голосов
/ 24 мая 2012

Или вы можете использовать мой php скрипт https://gist.github.com/2780984

#!/usr/bin/env php
<?php
$local = exec("git branch | xargs $1");
$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++;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...