Git'te her bir dalı ve son revizyon tarihini listeleme


138

Eski ve bakımsız şubeleri uzak depomuzdan silmem gerekiyor. Uzak dalları son değiştirilme tarihlerine göre listelemek için bir yol bulmaya çalışıyorum ve yapamam.

Uzak dalları bu şekilde listelemenin kolay bir yolu var mı?



3
Cevapları: stackoverflow.com/questions/5188320/… burada verilen yanıtlardan daha iyidir
Yazılım Mühendisi

Yanıtlar:


172

commandlinefu'nun 2 ilginç önermesi vardır:

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

veya:

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

Bu, Unix sözdiziminde yerel şubeler içindir. Kullanarak git branch -r, benzer şekilde uzak dalları gösterebilirsiniz:

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

Michael Forrest , açıklamalarda zsh'ın sedifade için kaçış gerektirdiğinden bahsediyor :

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 ekler yorumlarda :

Eğer zshrc'nizi eklemek istiyorsanız, aşağıdaki kaçış gereklidir.

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'

Birden çok satırda:

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'

Not: n8tr 'ın cevabı dayalı git for-each-ref refs/headstemizleyicidir. Ve daha hızlı .
Ayrıca bkz. " Yalnızca ad seçeneği git branch --list? "

Daha genel olarak, üçlü bize yorumlarda hatırlatır :

  • $(command substitution)Eskimiş backtick sözdizimine göre modern sözdizimini tercih edin .

(2014'te bu noktayı " Kabuk programlama arasındaki $(command)ve `command`kabuk programlama arasındaki fark nedir ? "

  • İle satır okumafor .
  • Muhtemelen git for-each-ref refs/remoteuzak şube adlarını makine tarafından okunabilir biçimde almak için geçiş yapın

1
@hansen j: ilginç, değil mi? Stack Overflow'un ( codeinthehole.com/archives/… ) kamuya açıklanmasından birkaç ay sonra başlatıldı ve SO'dan biraz ilham aldı. Daha fazla git commandlinefu için commandlinefu.com/commands/tagged/67/git
VonC


@SebastianG emin değilim: bu kendi başına iyi bir soru olurdu.
VonC

+1 /jsonHerhangi bir commandlinefu.com URL'sinin sonuna nasıl ekleyebileceğiniz oldukça harika ve tüm komutları JSON olarak alacaksınız.
Noah Sussman

1
@tripleee Teşekkür ederim. Cevabı düzenledim ve daha fazla görünürlük için yorumlarınızı ekledim.
VonC

121

İşte ne kullanıyorum:

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

Bu çıktı:

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

Uzak dallar için, "refs / heads" yerine "refs / remotes" kullanın:

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

Şube üzerindeki son yazarla da ilgileniyorsanız ve "sütun" aracını kullanıyorsanız , n8tr cevabını temel alarak şunları kullanabilirsiniz:

git for-each-ref --sort='-committerdate:iso8601' --format='%(committerdate:relative)|%(refname:short)|%(committername)' refs/remotes/ | column -s '|' -t

Hangi size verecek:

21 minutes ago  refs/remotes/a        John Doe
6 hours ago     refs/remotes/b        Jane Doe
6 days ago      refs/remotes/master   John Doe

En son bilgilere sahip olmak için daha önce "git fetch --prune" u aramak isteyebilirsiniz.


5
For-each-ref ve format seçeneklerinin güzel kullanımı. +1. Kendi cevabımda referans verdiğim komutlardan daha kolay geliyor.
VonC

2
biraz tweaking: ------- git for-each-ref --sort = '- authordate: iso8601' --format = '% (authordate: relative)% 09% (refname: kısa)' refs / heads ------- göreceli bir tarih verir ve referansları / kafaları ortadan kaldırır
n8tr

1
Hemen belli olmayanlar için, bunun bilgi gösterdiğini düşünüyorum. kesinlikle yerel şubeler için.
hBrent

@hBrent haklısın, soruyu tam olarak cevaplamadı. Cevabımı buna göre düzenledim.
ocroquette

Bu, dalları sıralar ve listeler authordate(dalın ilk oluşturulduğu zaman olduğu anlaşılıyor mu?). Eğer değiştirirseniz authordateiçin committerdateo zaman en son tarihlerini göreceksiniz her dalında taahhüt. : Böylece gibigit for-each-ref --sort='-committerdate:iso8601' --format=' %(committerdate:iso8601)%09%(refname)' refs/heads
Logan Besecker

23

Olivier Croquette'i inşa etmek , göreceli bir tarih kullanmayı ve şube adını şu şekilde kısaltmayı seviyorum:

git for-each-ref --sort='-authordate:iso8601' --format=' %(authordate:relative)%09%(refname:short)' refs/heads

Hangi çıktı verir:

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

Tüm favori takma adlarınızı eklemek için bir Bash dosyası oluşturmanızı ve komut dosyasını ekibinize paylaşmanızı öneririm. İşte bunu eklemek için bir örnek:

#!/bin/sh

git config --global alias.branches "!echo ' ------------------------------------------------------------' && git for-each-ref --sort='-authordate:iso8601' --format=' %(authordate:relative)%09%(refname:short)' refs/heads && echo ' ------------------------------------------------------------'"

Sonra bunu güzelce biçimlendirilmiş ve sıralanmış bir yerel şube listesi almak için yapabilirsiniz:

git branches

20

@VonC tarafından yoruma eklemek için tercih ettiğiniz çözümü alın ve kolaylık sağlamak için ~ / .gitconfig takma ad listenize ekleyin:

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

Sonra basit bir "git branchdate" listeyi sizin için yazdırır ...


3
.Gitconfig ile nasıl kullanılacağını gösteren +1! Ayrıca fwiw Biçim dizesini şu şekilde değiştirdim: --format='%(authordate)%09%(objectname:short)%09%(refname)'her dalın kısa karmasını da alır.
Noah Sussman

Güzel. Son zamanlarda dokunan dallar hızla görünür böylece ters sırayla sıralamak için sonuna "| tac" eklemek istiyorum.
Ben

1
Sen gerekmez | tac, sadece, --sort='authordate'yerine-authordate
Kristján

4

İşte sonra da gözden ile geldi budur bu .

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Çek aynı birden fazla şube noktaları işlerlerse çiftleri kaldırmaktır. (Uzaktan kumandada bulunan yerel bir dalda olduğu gibi.)

OP isteğine göre git branch --mergedve git branch --no-mergedhangi dalların kolayca silinebileceğini belirlemede yararlı olduğunu unutmayın.

[ https://git-scm.com/docs/git-branch]


3

Sıralama uzak şube ve son her şube için tarih işlemek.

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
Uzaktan kumanda ile ilgili OP sorusunu yanıtladığınız için teşekkür ederiz.
arcseldon

1

VonC'nin cevabına dayanarak iki varyant yaptım .

İlk değişkenim:

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

Bu, yerel ve uzak dalları ( -a) ele alır, ayrılmış kafa durumunu (daha uzun sed komutu, çözüm bir tür kaba olsa da - sadece ayrılmış şube bilgisini HEAD anahtar sözcüğü ile değiştirir), taahhüt konusunu ekler (% s ) ve biçim dizesindeki değişmez boru karakterleri aracılığıyla ve son sonucu geçirerek bir şeyleri sütunlara koyar column -t -s "|". (Çıktının geri kalanında beklemediğiniz bir şey olduğu sürece ayırıcı olarak her şeyi kullanabilirsiniz.)

İkinci varyantım oldukça çirkin, ama dal komutunun yaptığı gibi hala "şu anda bulunduğunuz dal" göstergesi olan bir şey istedim.

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

Bu *, geçerli dalı bir anahtar kelimeye dönüştürür ve döngü gövdesi anahtar kelimeyi gördüğünde bir bayrak ayarlar ve hiçbir şey çıkarmaz. Bayrak, sonraki satır için alternatif bir biçimlendirmenin kullanılması gerektiğini belirtmek için kullanılır. Dediğim gibi, tamamen hileli, ama işe yarıyor! (Çoğunlukla. Bazı nedenlerden dolayı, son sütunum geçerli şube satırında geride kalıyor.)


Ne yazık ki VonCs cevabındaki bilgiler senaryo yazımı için mükemmel bir temel değildir. Buraya bakın git-blame.blogspot.com/2013/06/…
Andrew C

Hmm. Bu, bir adı varsa, geçerli dalın adını almanın bir yolunu gösterir. Makine dostu bir şube listesi almanın [tercih edilen] bir yolu var mı? (Ve şu anki dalı doğrudan ya da bir şekilde git "diye sormak yoluyla mevcut dalı ayırt etmenin bir yolu bu HEAD ile aynı ref?")
benkc

git for-each-refdalları işlemek için komut dosyası dostu bir yöntemdir. Geçerli dalı almak için sembolik ref'yi bir kez çalıştırmanız gerekir.
Andrew C

Çaba için +1, ama bu gerçekten benim eski bir cevaptı. stackoverflow.com/a/16971547/6309 veya (daha eksiksiz) stackoverflow.com/a/19585361/6309 daha az 'sed' içerebilir.
VonC

1

Basit bir takma ad yaptım, tam olarak sorduğumdan emin değilim, ama basit

Bunu yukarıdaki komutların sadece yerel şubelerimi değil tüm şubeleri listelemek istediğim için yaptım

alias git_brs="git fetch && git branch -av --format='\''%(authordate)%09%(authordate:relative)%09%(refname)'\'"

grep originYalnızca orijinleri almak için yukarı yöneltebilirsiniz

Bu, tüm şubeleri değiştirilen son tarihle birlikte listeler, en son sürüm için hangisini çekmem gerektiğine karar vermeme yardımcı olur

Bu, aşağıdaki ekran tipiyle sonuçlanır

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

Yardım edersen bana haber ver, mutlu gitting


Güzel ve basit. Özel sos yok.
MrMas

0

Veya PHP betiğimi kullanabilirsiniz, 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++;
    }
?>

0

İşte bunu kolaylaştırmak için bash_profile'ınıza ekleyebileceğiniz bir işlev.

Git deposundayken kullanım:

  • branch tüm yerel şubeleri yazdırır
  • branch -r tüm uzak dalları yazdırır

İşlev:

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

PowerShell'de, aşağıdakiler uzaktan kumandada birleştirilmiş ve en az iki haftalık dalları gösterir ( author:relativebiçim iki haftadaki günler yerine haftalar görüntülenmeye başlar):

$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}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.