Мне нужно удалить старые и неподдерживаемые ветки из нашего удаленного репозитория. Я пытаюсь найти способ перечислить удаленные ветки по дате их последнего изменения, но не могу.
Есть ли простой способ перечислить удаленные ветки таким образом?
Мне нужно удалить старые и неподдерживаемые ветки из нашего удаленного репозитория. Я пытаюсь найти способ перечислить удаленные ветки по дате их последнего изменения, но не могу.
Есть ли простой способ перечислить удаленные ветки таким образом?
commandlinefu У a> есть 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
or:
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
kontinuity добавляет в комментариях:
Если вы хотите добавить его в свой 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'
Примечание: ответ от n8tr"> n8tr"> n8tr">, основанный на git for-each-ref refs/heads
, чище. И быстрее.
См. также " Параметр" Только имя "для git branch --list
?"
В более общем плане tripleee напоминает нам в комментариях:
- Предпочитайте современный синтаксис
$(command substitution)
устаревшему синтаксису обратных ссылок.
(Я проиллюстрировал этот момент в 2014 году с помощью «В чем разница между $(command)
и `command`
в программировании оболочки?»)
- Не читайте строки с
for
.- Возможно, переключитесь на
git for-each-ref refs/remote
, чтобы получить имена удаленных веток в машиночитаемом формате
/json
в конец любого URL-адреса commandlinefu.com, и вы получите все команды как JSON.
- person Noah Sussman; 06.04.2013
zsh: no matches found: s/^..//
при запуске?
- person Michael Forrest; 19.09.2013
git branch | perl -pe s\/\^\.\.\/\/
; сделать echo -e _2 _ \\ t $ k; сделано | sort -r
- person Michael Forrest; 19.09.2013
sed -e s/^..// -e 's/(detached from \(.*\))/\1/'
. Затем я отвлекся, пытаясь включить тему коммита, похожую на git branch -v, что легко, но разумное ее разбиение потребует, как мне кажется, освежить свой awk. Столбцы, содержащие пробелы, - это сложно, не так ли?
- person benkc; 06.11.2014
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'
- person kontinuity; 23.08.2016
$(command substitution)
синтаксис устаревшему синтаксису обратных ссылок. Не читайте строки с for
. Вероятно, переключитесь на _ 3_, чтобы получить имена удаленных веток в машиночитаемом формате.
- person tripleee; 13.02.2020
Вот что я использую:
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
Основываясь на ответе n8tr , если вас также интересует последний автор в ветке, и если у вас есть инструмент «столбец», вы можете использовать:
git for-each-ref --sort='-committerdate:iso8601' --format='%(committerdate:relative)|%(refname:short)|%(committername)' refs/remotes/ | column -s '|' -t
Что даст вам:
21 minutes ago refs/remotes/a John Doe
6 hours ago refs/remotes/b Jane Doe
6 days ago refs/remotes/master John Doe
Вы можете вызвать "git fetch --prune" перед тем, как получить самую свежую информацию.
authordate
(что, похоже, было при первом создании ветки?). Если вы измените authordate
на committerdate
, вы увидите даты самого последнего коммита в каждой ветке. Вот так: git for-each-ref --sort='-committerdate:iso8601' --format=' %(committerdate:iso8601)%09%(refname)' refs/heads
- person Logan Besecker; 09.02.2017
Создание Olivier Croquette, Мне нравится использовать относительную дату и сокращать имя ветки следующим образом:
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
Просто чтобы добавить к комментарию @VonC, выберите желаемое решение и для удобства добавьте его в список псевдонимов ~ / .gitconfig:
[alias]
branchdate = !git for-each-ref --sort='-authordate' --format='%(refname)%09%(authordate)' refs/heads | sed -e 's-refs/heads/--'
Затем простой "git branchdate" распечатает список для вас ...
--format='%(authordate)%09%(objectname:short)%09%(refname)'
, который также получает короткий хеш каждой ветки.
- person Noah Sussman; 04.04.2013
| tac
, просто --sort='authordate'
вместо -authordate
- person Kristján; 01.12.2015
Вот что я придумал, просмотрев также это.
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/git-branchvisible
Отсортированные удаленные ветки и дата последней фиксации для каждой ветки.
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
Я сделал два варианта на основе 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 "|"
Это превращает *
, который отмечает текущую ветвь, в ключевое слово, и когда тело цикла видит это ключевое слово, оно вместо этого устанавливает флаг и ничего не выводит. Флаг используется, чтобы указать, что для следующей строки следует использовать альтернативное форматирование. Как я уже сказал, это полностью взломано, но это работает! (В основном. По какой-то причине мой последний столбец выходит за пределы текущей ветки.)
git for-each-ref
- это удобный для скриптов способ обработки ветвей. Вам нужно будет запустить symbolic-ref один раз, чтобы получить текущую ветку.
- person Andrew C; 06.11.2014
В PowerShell ниже показаны ветки на удаленном компьютере, которые уже объединены и имеют возраст не менее двух недель (формат author:relative
начинает отображать недели вместо дней через две недели):
$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}
Я сделал простой псевдоним, не уверен, что это именно то, что просили, но это просто
Я сделал это, так как хотел перечислить все ветки, а не только мои локальные ветки, которые вышеупомянутые команды выполняют только
alias git_brs="git fetch && git branch -av --format='\''%(authordate)%09%(authordate:relative)%09%(refname)'\'"
Вы можете перенаправить выше на grep origin
, чтобы получить только происхождение
В нем перечислены все ветки вместе с последней измененной датой, что помогает мне решить, какую из них мне выбрать для последней версии.
Это приводит к отображению нижеуказанного типа.
Wed Feb 4 23:21:56 2019 +0230 8 days ago refs/heads/foo
Tue Feb 3 12:18:04 2019 +0230 10 days ago refs/heads/master
Mon Feb 9 12:19:33 2019 +0230 4 days ago refs/heads/bar
Wed Feb 11 16:34:00 2019 +0230 2 days ago refs/heads/xyz
Tue Feb 3 12:18:04 2019 +0230 10 days ago refs/remotes/origin/HEAD
Mon Feb 9 12:19:33 2019 +0230 4 days ago refs/remotes/origin/foo
Tue Feb 3 12:18:04 2019 +0230 10 days ago refs/remotes/origin/master
Tue Feb 3 12:18:04 2019 +0230 10 days ago refs/remotes/origin/bar
Tue Feb 3 12:18:04 2019 +0230 10 days ago refs/remotes/origin/xyz
Попробуйте и дайте мне знать, помогло ли это, счастливый gitting
Или вы можете использовать мой сценарий 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++;
}
?>
Вот функцию, которую вы можете добавить в свой 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
}