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



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



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



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

661   24  

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

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

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 for-each-ref -- sort= - committerdate refs / heads/ --формат='%(authordate:краткий) %(цвет:красный)%(имя_объекта:краткий) %(цвет:желтый)%(название_ссылки:краткий)%(цвет:сбросить) (%(цвет:зеленый)%(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)$|$"

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

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

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

Make'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 Karthik Nayak (KarthikNayak).
Помог-by:Junio C Hamano (gitster).
(слитый Junio C Hamano--gitster-- на commit 415095f, 03 ноября 2015)

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

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

$ git branch --sort=objectsize

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

С Git 2.19, порядок сортировки может быть установлен по умолчанию.
git branch поддерживает конфигурации branch.sort, как git tag, который уже был конфиг tag.sort.
Смотрите commit 560ae1c (16 Авг 2018) by Сэмюэль Мафтул (`).
(слитый Junio C Hamano--gitster-- на commit 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

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

к вашему сведению, если вы хотите получить список недавно проверил филиалы (в отличие от недавно совершенных) можно использовать в 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 repo, и он покажет вам последние 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 качается, но если вы хотите что-то более красивое, например GUI, и ваше происхождение === "github".

вы можете нажать кнопку "ветви" в репо. или нажмите на url прямой: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

Comments

    Ничего не найдено.