Как я могу получить список ветвей git, упорядоченных по последней фиксации?

Я хочу получить список всех ветвей в репозитории Git с" самыми свежими " ветвями вверху, где "самая свежая" ветвь-это та, которая была совершена совсем недавно (и поэтому, скорее всего, будет той, на которую я хочу обратить внимание).

есть ли способ использовать Git для (a) сортировки списка ветвей по последней фиксации или (b) получения списка ветвей вместе с датой последней фиксации каждого из них в каком-то машиночитаемом формат?

в худшем случае, я всегда мог бежать git branch чтобы получить список всех ветвей, проанализируйте его вывод, а затем git log -n 1 branchname --format=format:%ci для каждого из них, чтобы получить дату фиксации каждой ветви. Но это будет работать в окне Windows, где вращение нового процесса относительно дорого, поэтому запуск исполняемого файла git один раз на ветку может замедлиться, если есть много ветвей. Есть ли способ сделать все это с помощью одной команды?

24 ответов


использовать --sort=-committerdate на git for-each-ref;
также доступен С Git 2.7.0 на git branch:

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

git for-each-ref --sort=-committerdate refs/heads/

# or using git branch (since version 2.7.0)
git branch --sort=-committerdate  # DESC
git branch --sort=committerdate  # ASC

результат:

result

Дополнительные Функции:

git for-each-ref --sort=committerdate refs/heads/ --format='%(HEAD) %(color:yellow)%(refname:short)%(color:reset) - %(color:red)%(objectname:short)%(color:reset) - %(contents:subject) - %(authorname) (%(color:green)%(committerdate:relative)%(color:reset))'

результат:

result


список имен ветвей git, упорядоченных по последней фиксации...

расширяя ответ Якуба и подсказку Джо, следующее вычеркнет " refs / heads/", поэтому на выходе отображаются только имена ветвей:


:
git for-each-ref --count=30 --sort=-committerdate refs/heads/ --format='%(refname:short)'

результат:

recent git branches


вот оптимальный код, который объединяет два других ответа:

git for-each-ref --sort=-committerdate refs/heads/ --format='%(committerdate:short) %(authorname) %(refname:short)'

вот простая команда, которая перечисляет все ветви с последними изменениями:

git branch -v

чтобы заказать последнюю фиксацию, используйте

git branch -v --sort=committerdate

источник:http://git-scm.com/book/en/Git-Branching-Branch-Management


Я использую следующий псевдоним:

recent = "!r(){git for-each-ref --sort=-committerdate refs/heads --format='%(HEAD)%(color:yellow)%(refname:short)|%(color:bold green)%(committerdate:relative)|%(color:blue)%(subject)|%(color:magenta)%(authorname)%(color:reset)'|column -ts'|'}; r"

что производит: result

Edit: используйте '|' для разделения, благодаря @Björn Lindqvist

Update: добавлено * перед текущей веткой, благодаря @elhadi
Edit: исправлен случай, когда текущая ветвь была подстрокой другой ветви

Edit: используйте более простой синтаксис для текущей ветви, благодаря @Joshua Skrzypek


мне также нужны цвета, теги и удаленные ссылки без каких-либо дубликатов:

for ref in $(git for-each-ref --sort=-committerdate --format="%(refname)" refs/heads/ refs/remotes ); do git log -n1 $ref --pretty=format:"%Cgreen%cr%Creset %C(yellow)%d%Creset %C(bold blue)<%an>%Creset%n" | cat ; done | awk '! a[]++'

поскольку цитирование может быть трудным, здесь псевдоним для bash:

alias glist='for ref in $(git for-each-ref --sort=-committerdate --format="%(refname)" refs/heads/ refs/remotes ); do git log -n1 $ref --pretty=format:"%Cgreen%cr%Creset %C(yellow)%d%Creset %C(bold blue)<%an>%Creset%n" | cat ; done | awk '"'! a["''"]++'"

другие ответы, похоже, не позволяют пройти -vv чтобы получить подробный вывод.

Итак, вот один лайнер, который сортирует git branch -vv по дате фиксации, сохраняя цвет и т. д.:

git branch -vv --color=always | while read; do echo -e $(git log -1 --format=%ct $(echo "_$REPLY" | awk '{print }' | perl -pe 's/\e\[?.*?[\@-~]//g') 2> /dev/null || git log -1 --format=%ct)"\t$REPLY"; done | sort -r | cut -f 2

если вы дополнительно хотите распечатать дату фиксации, вы можете использовать эту версию:

git branch -vv --color=always | while read; do echo -e $(git log -1 --format=%ci $(echo "_$REPLY" | awk '{print }' | perl -pe 's/\e\[?.*?[\@-~]//g') 2> /dev/null || git log -1 --format=%ci)" $REPLY"; done | sort -r | cut -d ' ' -f -1,4-

пример вывода:

2013-09-15   master                  da39a3e [origin/master: behind 7] Some patch
2013-09-11 * (detached from 3eba4b8) 3eba4b8 Some other patch
2013-09-09   my-feature              e5e6b4b [master: ahead 2, behind 25] WIP

это, вероятно, более читаемый разбит на несколько строк:

git branch -vv --color=always | while read; do
    # The underscore is because the active branch is preceded by a '*', and
    # for awk I need the columns to line up. The perl call is to strip out
    # ansi colors; if you don't pass --color=always above you can skip this
    local branch=$(echo "_$REPLY" | awk '{print }' | perl -pe 's/\e\[?.*?[\@-~]//g')
    # git log fails when you pass a detached head as a branch name.
    # Hide the error and get the date of the current head.
    local branch_modified=$(git log -1 --format=%ci "$branch" 2> /dev/null || git log -1 --format=%ci)
    echo -e "$branch_modified $REPLY"
# cut strips the time and timezone columns, leaving only the date
done | sort -r | cut -d ' ' -f -1,4-

это также должно работать с другими аргументами для git branch, например,-vvr в списке удаленные ветки, или -vva чтобы перечислить как удаленное отслеживание, так и локальные ветви.


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

git для-each-ref --sort= - committerdate refs / heads/ -- format= ' %(authordate: short) %(color: red)%(objectname: short) %(color: yellow)%(refname: short)%(color: reset) (%(цвет:зеленый)%(committerdate: относительный)%(цвет: сброс))'

Screenshot of Output


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

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

обновление: Сделай это, если хочешь. окраска:

#!/bin/sh
#
(echo ' ------------------------------------------------------------‌​' && git for-each-ref --sort='-authordate:iso8601' --format=' %(authordate:relative)%09%(refname:short)' refs/heads && echo ' ------------------------------------------------------------‌​') | grep --color -E "$(git rev-parse --abbrev-ref HEAD)$|$"

git 2.7 (Q4 2015) представит сортировку ветвей, используя непосредственно git branch:
См.совершить aa3bc55, совершить aedcb7d, совершить 1511b22, совершить f65f139, ... (23 Sep 2015),совершить aedcb7d, совершить 1511b22, совершить ca41799 (24 сентября 2015), и совершить f65f139, ... (23 Sep 2015) by Картик Наяк (KarthikNayak).
(сливаются Junio C Hamano -- gitster -- на совершить 7f11b48, 15 окт 2015)

в частности, совершить aedcb7d:

branch.c: используйте 'ref-filter' APIs

сделатьbranch.c 'use'ref-filter' API для итерации через сортировку ссылок. Это удаляет большую часть кода, используемого в 'branch.c' заменив его с призывами к ''.

это добавлена возможность --sort=<key>:

Сортировка на основе данного ключа.
Префикс - сортировка в порядке убывания значения.

можно использовать --sort=<key> опция несколько раз, в этом случае Последний ключ становится первичным ключом.

поддерживаемые ключи то же, что и в git for-each-ref.
Сортировать по умолчанию порядок сортировки на основе полного имени (в том числе refs/... префикс). Это список отсоединенной головы (если present) сначала, затем локальные ветви и, наконец, ветви удаленного отслеживания.

здесь:

git branch --sort=-committerdate 

см. также совершить 9e46833 (30 окт 2015) by Картик Наяк (KarthikNayak).
Помог-by:Junio C Hamano (gitster).
(слитый Junio C Hamano -- gitster -- на совершить 415095f, 03 ноя 2015)

при сортировке как на числовые значения (например,--sort=objectsize) нет резервного сравнения, когда оба refs имеют одинаковое значение. Это может привести к неожиданным результатам (т. е. порядок перечисления refs с равными значениями не может быть заранее определен), как указывает Johannes Sixt ($gmane/280117).

отсюда возврат к алфавитному сравнению на основе refname всякий раз, когда другой критерий равен.

$ git branch --sort=objectsize

*  (HEAD detached from fromtag)
      branch-two
      branch-one
      master

С Git 2.19, порядок сортировки может быть установлен по умолчанию.
git branch поддерживает конфигурации branch.sort, как git tag, который уже имел config tag.sort.
См.совершить 560ae1c (16 Авг 2018) by Самуил Maftoul (`).
(слитый Junio C Hamano -- gitster -- на совершить d89db6f, 27 авг 2018)

branch.sort:

эта переменная управляет порядком сортировки ветвей при отображении git-branch.
Без "--sort=<value>" при условии, значение этой переменной будет использоваться по умолчанию.


добавляет цвет (так как pretty-format не имеется)

[alias]
    branchdate = for-each-ref --sort=-committerdate refs/heads/ --format="%(authordate:short)%09%(objectname:short)%09%1B[0;33m%(refname:short)%1B[m%09"

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

$ twig

                              issue  status       todo            branch
                              -----  ------       ----            ------
2013-01-26 18:00:21 (7m ago)  486    In progress  Rebase          optimize-all-the-things
2013-01-26 16:49:21 (2h ago)  268    In progress  -               whitespace-all-the-things
2013-01-23 18:35:21 (3d ago)  159    Shipped      Test in prod  * refactor-all-the-things
2013-01-22 17:12:09 (4d ago)  -      -            -               development
2013-01-20 19:45:42 (6d ago)  -      -            -               master

Он также позволяет хранить пользовательские свойства для каждой ветви, например, идентификатор билета, статус, задачи и фильтровать список ветвей в соответствии с этими свойствами. Подробнее: http://rondevera.github.io/twig/


Я придумал следующую команду (для Git 2.13 и выше):

git branch -r --sort=creatordate \
    --format "%(creatordate:relative);%(committername);%(refname:lstrip=-1)" \
    | grep -v ";HEAD$" \
    | column -s ";" -t

если у вас нет column вы можете заменить последнюю строку с

    | sed -e "s/;/\t/g"

вывод выглядит как

6 years ago             Tom Preston-Werner  book
4 years, 4 months ago   Parker Moore        0.12.1-release
4 years ago             Matt Rogers         1.0-branch
3 years, 11 months ago  Matt Rogers         1.2_branch
3 years, 1 month ago    Parker Moore        v1-stable
12 months ago           Ben Balter          pages-as-documents
10 months ago           Jordon Bedwell      make-jekyll-parallel
6 months ago            Pat Hawks           to_integer
5 months ago            Parker Moore        3.4-stable-backport-5920
4 months ago            Parker Moore        yajl-ruby-2-4-patch
4 weeks ago             Parker Moore        3.4-stable
3 weeks ago             Parker Moore        rouge-1-and-2
19 hours ago            jekyllbot           master

я писал блоге о том, как различные части работы.


FYI, если вы хотите получить список недавно проверил филиалы (в отличие от недавно совершенных) можно использовать в Git reflog:

$ git reflog | egrep -io "moving from ([^[:space:]]+)" | awk '{ print  }' | head -n5
master
stable
master
some-cool-feature
feature/improve-everything

Читайте также: как я могу получить список ветвей git, которые я недавно проверил?


вот еще один скрипт, который делает то, что делают все остальные скрипты. Фактически, он предоставляет функцию для вашей оболочки.

его вклад заключается в том, что он вытягивает некоторые цвета из вашей конфигурации git (или использует значения по умолчанию).

# Git Branch by Date
# Usage: gbd [ -r ]
gbd() {
    local reset_color=`tput sgr0`
    local subject_color=`tput setaf 4 ; tput bold`
    local author_color=`tput setaf 6`

    local target=refs/heads
    local branch_color=`git config --get-color color.branch.local white`

    if [ "" = -r ]
    then
        target=refs/remotes/origin
        branch_color=`git config --get-color color.branch.remote red`
    fi

    git for-each-ref --sort=committerdate $target --format="${branch_color}%(refname:short)${reset_color} ${subject_color}%(subject)${reset_color} ${author_color}- %(authorname) (%(committerdate:relative))${reset_color}"
}

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

current_branch="$(git symbolic-ref --short -q HEAD)"
git for-each-ref --sort=committerdate refs/heads \
  --format='%(refname:short)|%(committerdate:relative)' \
  | grep -v '\(year\|month\)s\? ago' \
  | while IFS='|' read branch date
    do
      start='  '
      end=''
      if [[ $branch = $current_branch ]]; then
        start='* \e[32m'
        end='\e[0m'
      fi
      printf "$start%-30s %s$end\n" "$branch" "$date"
    done

вот небольшой скрипт, который я использую для переключения между последними ветвями:

#!/bin/bash
# sudo bash

re='^[0-9]+$'

if [[ "" =~ $re ]]; then
    lines=""
else
    lines=10
fi
branchs="$(git recent | tail -n $lines | nl)"
branchs_nf="$(git recent-nf | tail -n $lines | nl)"
echo "$branchs"

# Prompt which server to connect to
max="$(echo "$branchs" | wc -l)"
index=
while [[ ! ( "$index" =~ ^[0-9]+$ && "$index" -gt 0 && "$index" -le "$max" ) ]]; do
    echo -n "Checkout to: " 
    read index
done

branch="$( echo "$branchs_nf" | sed -n "${index}p" | awk '{ print $NF }' )"
git co $branch
clear

используя эти два псевдонима

recent = for-each-ref --sort=committerdate refs/heads/ --format=' %(color:blue) %(authorname) %(color:yellow)%(refname:short)%(color:reset)'
recent-nf = for-each-ref --sort=committerdate refs/heads/ --format=' %(authorname) %(refname:short)'

просто вызовите это в Git-РЕПО, и он покажет вам последние N ветвей (10 по умолчанию) и номер в стороне от каждого. Введите номер ветки, и он проверяет:

enter image description here


с git 2.19 вы можете просто:

git config --global branch.sort -committerdate

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

отказ от ответственности: я автор этой функции в git, я реализовал ее, когда увидел этот вопрос.


мой лучший результат в скрипт:

git for-each-ref --sort=-committerdate refs/heads/ --format='%(refname:short)|%(committerdate:iso)|%(authorname)' |
    sed 's/refs\/heads\///g' |
    grep -v BACKUP  | 
    while IFS='|' read branch date author
    do 
        printf '%-15s %-30s %s\n' "$branch" "$date" "$author"
    done

вот вариация, которую я искал:

git for-each-ref --sort=-committerdate --format='%(committerdate)%09%(refname:short)' refs/heads/ | tail -r

Это tail -r отменяет список, поэтому самый последний commiterdate последний.


опаздывает на вечеринку. Принятый ответ CML rocks, но если вы хотите что-то более красивое, например GUI, и ваш origin === "github".

вы можете нажать "ветви" в репо. или нажмите url direct:https://github.com/ORGANIZATION_NAME/REPO_NAME/branches


Я передаю вывод из принятого ответа в dialog, чтобы дать мне интерактивное список:

#!/bin/bash

TMP_FILE=/tmp/selected-git-branch

eval `resize`
dialog --title "Recent Git Branches" --menu "Choose a branch" $LINES $COLUMNS $(( $LINES - 8 )) $(git for-each-ref --sort=-committerdate refs/heads/ --format='%(refname:short) %(committerdate:short)') 2> $TMP_FILE

if [ $? -eq 0 ]
then
    git checkout $(< $TMP_FILE)
fi

rm -f $TMP_FILE

clear

Сохранить как (например) ~/bin/git_recent_branches.sh и chmod +x его. Тогда git config --global alias.rb '!git_recent_branches.sh' чтобы дать мне новый


git for-each-ref --sort=committerdate refs/heads/ --format='%(HEAD) %(color:yellow)%(refname:short)%(color:reset) - %(color:red)%(objectname:short)%(color:reset) - %(contents:subject) - %(authorname) (%(color:green)%(committerdate:relative)%(color:reset))' Это то, что вам нужно


ГИТ версии v2.19 представляет branch.sort настройка (см. филиала.вроде).

так git branch будет сортировать по дате фиксатора (desc) по умолчанию с

# gitconfig
[branch]
    sort = -committerdate     # desc

сценарий:

$ git config --global branch.sort -committerdate