Как я могу получить список веток Git, упорядоченный по последнему коммиту? - PullRequest
1098 голосов
/ 04 марта 2011

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

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

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

Ответы [ 27 ]

1559 голосов
/ 04 марта 2011

Используйте --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

115 голосов
/ 12 мая 2011

Список имен веток git, упорядоченных по последнему коммиту…

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


Команда:

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

Результат:

recent git branches

81 голосов
/ 22 мая 2012

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

git for-each-ref --sort=-committerdate refs/heads/ --format='%(committerdate:short) %(authorname) %(refname:short)'
74 голосов
/ 13 марта 2013

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

git branch -v

Чтобы упорядочить по последнему коммиту, используйте

git branch -v --sort=committerdate

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

48 голосов
/ 06 мая 2015

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

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

Редактировать: использовать '|'отделить, благодаря @ Björn Lindqvist

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

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

36 голосов
/ 19 августа 2013

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

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[$0]++'

Поскольку цитирование может быть сложным, здесь псевдоним для 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["'$0'"]++'"
30 голосов
/ 13 июня 2017

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

git for-each-ref --sort = -committerdate refs /heads / --format = '% (authordate: short)% (цвет: красный)% (имя объекта: короткий)% (цвет: желтый)% (refname: short)% (цвет: сброс) (% (цвет: зеленый)% (committerdate: относительный)%(цвет: сброс)) '

Screenshot of Output

24 голосов
/ 12 сентября 2013

Другие ответы, по-видимому, не позволяют пропускать -vv для получения подробного вывода.

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

git branch -vv --color=always | while read; do echo -e $(git log -1 --format=%ct $(echo "_$REPLY" | awk '{print $2}' | 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 $2}' | 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

Вероятно, более читабельно разбито на несколькоlines:

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 $2}' | 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 для отображения как удаленных, так и локальных ветвей.

22 голосов
/ 16 октября 2015

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

В частности, commit aedcb7d :

branch.c: использовать API ref-filter 1039 *

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

Это добавляет опцию --sort=<key>:

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

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

Поддерживаемые клавиши такие же, как и в git for-each-ref.
Порядок сортировки по умолчанию сортируется по полному имени (включая префикс refs/...). В этом списке сначала отображается отсоединенный HEAD (если имеется), затем локальные ветви и, наконец, ветви с удаленным отслеживанием.

Здесь:

git branch --sort=-committerdate 

Или (см. Ниже с Git 2.19)

# if you are sure to /always/ want to see branches ordered by commits:
git config --global branch.sort -committerdate
git branch

См. Также коммит 9e46833 (30 октября 2015 г.) от Картик Наяк (KarthikNayak) .
Помощник: Джунио С Хамано (gitster) .
(Объединено с Junio ​​C Hamano - gitster - в коммит 415095f , 03 ноября 2015 г.)

При сортировке по числовым значениям (например, --sort=objectsize) нет запасного сравнения, когда обе ссылки содержат одно и то же значение. Это может привести к неожиданным результатам (т. Е. Порядок перечисления ссылок с одинаковыми значениями не может быть заранее определен), как указал Йоханнес Сикст ( $ 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, в которой уже была конфигурация tag.sort.
См. коммит 560ae1c (16 августа 2018 г.) Самуэль Мафтул (``) .
(Объединено с Junio ​​C Hamano - gitster - в commit d89db6f , 27 августа 2018 г.)

branch.sort:

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


Для отображения удаленных веток используйте git branch -r --sort=objectsize. Флаг -r заставляет его перечислять удаленные ветви вместо локальных.

19 голосов
/ 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

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

#!/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)$|$"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...