Uzaktan kumanda olmadan tüm yerel şubeleri listeleyin


91

Sorun: Uzaktan kumandası olmayan tüm yerel şubelerimi silmenin bir yolunu istiyorum. Dalların adlarını a şeklinde aktarmak yeterince kolaydır git branch -D {branch_name}, ancak bu listeyi ilk etapta nasıl edinebilirim?

Örneğin:

Uzaktan kumanda olmadan yeni bir şube oluşturuyorum:

$ git co -b no_upstream

Tüm şubelerimi listeliyorum ve uzaktan kumandalı sadece bir tane var

$ git branch -a
master
* no_upstream
remotes/origin/HEAD -> origin/master
remotes/origin/master

no_upstreamCevap almak için hangi komutu çalıştırabilirim ?

Koşabilirim git rev-parse --abbrev-ref --symbolic-full-name @{u}ve bu onun uzaktan kumandası olmadığını gösterecek:

$ git rev-parse --abbrev-ref --symbolic-full-name @{u}
error: No upstream configured for branch 'no_upstream'
error: No upstream configured for branch 'no_upstream'
fatal: ambiguous argument '@{u}': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'

Ancak bu bir hata olduğu için kullanmama veya başka komutlara aktarmama izin vermiyor. Bunu ya bir kabuk betiği takma adı olarak kullanmayı git-delete-unbranchedya da belki de süper basit bir Gem yapmak niyetindeyim.git-branch-delete-orphans



Yanıtlar:


103

Geçenlerde komutun git branch -vv"çok ayrıntılı" versiyonu olduğunu keşfettim git branch.

Dalları, varsa uzak dallarla birlikte aşağıdaki biçimde verir:

  25-timeout-error-with-many-targets    206a5fa WIP: batch insert
  31-target-suggestions                 f5bdce6 [origin/31-target-suggestions] Create target suggestion for team and list on save
* 54-feedback-link                      b98e97c [origin/54-feedback-link] WIP: Feedback link in mail
  65-digest-double-publish              2de4150 WIP: publishing-state

Bu güzel biçimlendirilmiş çıktıya sahip olduğunuzda, onu kanalize etmek cutve awklistenizi almak kadar kolaydır :

git branch -vv | cut -c 3- | awk '$3 !~/\[/ { print $1 }'

Aşağıdaki çıktıda sonuçlar:

25-timeout-error-with-many-targets
65-digest-double-publish

Bu cutkısım, veriyi *aktarmadan önce çıktıdan ilk iki karakteri (dahil ) kaldırarak normalleştirir awk.

awkÜçüncü sütundaki bir köşeli parantez varsa kısmı, birinci sütun basar.

Bonus: Bir takma ad oluşturun

Genel .gitconfigdosyanızda (veya herhangi bir yerde) bir takma ad oluşturarak çalıştırmayı kolaylaştırın :

[alias]
  local-branches = !git branch -vv | cut -c 3- | awk '$3 !~/\\[/ { print $1 }'

Önemli: Ters eğik çizginin diğer adda öncelenmesi gerekir, aksi takdirde geçersiz bir gitconfig dosyanız olur.

Bonus: Uzaktan Filtreleme

Herhangi bir nedenle farklı şubeler için birden fazla izleme uzaktan kumandanız varsa, hangi uzaktan kumandayı kontrol etmek istediğinizi belirlemek yeterince kolaydır. Sadece uzak ismi awk kalıbına ekleyin. Benim durumumda, bunu originyapabilmem için:

git branch -vv | cut -c 3- | awk '$3 !~/\[origin/ { print $1 }'

WIP:neyse bu ne ..? zula komutunun yarattığı şey bu değil mi ..?
igrek

@igrek Bu sadece commit mesajında ​​kullandığım bir önek. Git'e özgü bir şey yok.
Jeremy Baker

bunu yaptığımda git branch -vv, uzak bir şube olsa ve yerel şubemle eşleşse bile [origin/branch-name], sonucun yanında görmem . diffNeyin yerel olduğunu gerçekten anlamak için iki şube listesine ihtiyacım vardı .
ryantuck

git branch -vv | grep -v origin/benim için yeterli
panik yapma

2
Bu işaretlenmiş uzak dalları gözden kaçırmaz mı gone?
Reid

36

git branch (herhangi bir seçenek olmadan) yalnızca yerel şubeleri listeler, ancak uzak bir şubeyi takip edip etmediklerini bilemezsiniz.

Genellikle bu yerel şubeler bir kez birleştirildikten sonra silinmelidir (git-sweep'in bu sayısındamaster görüldüğü gibi ):

git branch --merged master | grep -v master | xargs git branch -d

Bu istediğiniz kadar eksiksiz değil ama bir başlangıç.

İle --merged, yalnızca adlandırılmış commit ile birleştirilen şubeler (yani, bahşiş taahhütlerine adlandırılmış commit'den ulaşılabilir olan şubeler) listelenir.


1
Yerel şubesi olmayan uzak şubeleri de dahil etmek için kullanın git branch -a --merged.
Acumenus

21

Benzer bir sorunum var. Şimdi silinmiş olan uzak dalları izleyen tüm yerel şubeleri kaldırmak istiyorum. git remote prune originGitmesini istediğim dalları çıkarmak için yetersiz buluyorum . Uzaktan kumanda silindikten sonra yerelin de gitmesini istiyorum. İşte benim için işe yarayan şey:

Benim ~/.gitconfig:

[alias]
  prune-branches = !git remote prune origin && git branch -vv | grep ': gone]' | awk '{print $1}' | xargs -r git branch -d

İşte git config --global ...bunu kolayca eklemek için bir komut git prune-branches:

git config --global alias.prune-branches '!git remote prune origin && git branch -vv | grep '"'"': gone]'"'"' | awk '"'"'{print $1}'"'"' | xargs -r git branch -d'

NOT : Değiştim -diçin -Dben Git birleştirilmemiş dalları şikayet duymak istemiyorum, çünkü benim asıl konfigürasyonda. Sen olabilir hem de bu işlevi istiyorum. Eğer öyleyse, o komutun sonunda -Dyerine -dkullanın.

Ayrıca, FWIW, genel yapılandırma dosyanız neredeyse her zaman ~/.gitconfig.

(OS X Düzeltme)

Yazıldığı gibi , xargs -r(teşekkürler, Korny ) kullanımı nedeniyle bu OS X üzerinde çalışmıyor .

-rÖnlemektir xargsçalışmasını git branch -dbir hata mesajı "sonuçlanacak bir şube adı, olmadan fatal: branch name required". Hata mesajına aldırmazsanız, -rargümanını kaldırabilirsiniz ve artık xargshazırsınız.

Bununla birlikte, bir hata mesajı görmek istemiyorsanız (ve gerçekten, sizi kim suçlayabilir), o zaman boş bir boruyu kontrol eden başka bir şeye ihtiyacınız olacak. Kullanmak mümkün olabilir Eğer ifne gelen moreutils . Daha ifneönce eklersiniz xargs, bu da xargsboş verilerle çalışmayı durdurur . NOT : herhangi bir şeyin boş olmadığını ifnedüşünür , buna boş satırlar dahildir, bu nedenle yine de bu hata mesajını görebilirsiniz. Bunu OS X'te test etmedim.

İşte bu git configsatır ifne:

git config --global alias.prune-branches '!git remote prune origin && git branch -vv | grep '"'"': gone]'"'"' | awk '"'"'{print $1}'"'"' | ifne xargs git branch -d'

1
Bunu bir "git config --global ..." komutuna dönüştürmek mümkün mü? Bir talimat / aptallar için nasıl-yapılır bakış açısından, "git yapılandırma dosyalarınızı bulun, düzenlemek için düzenleyiciyi kullanın ve komutları çalıştırın" demek yerine geçmek kolaydır
Kannan Ekanath


Bunu bildiğim iyi oldu. OSX için "boşsa çalıştırma yok" seçeneğinin ne olacağını bilmiyorum.
Karl Wilbur

18

Geç düzenleme:

Daha iyi

git for-each-ref  --format='%(refname:short) %(upstream)'  refs/heads \
| awk '$2 !~/^refs\/remotes/'

GNU'da / herhangi bir şeyde

for b in `git branch|sed s,..,,`; do
    git config --get branch.$b.remote|sed Q1 && echo git branch -D $b
done

Şube daha bir avuç olasılıkla olsaydı, kullanarak daha iyi yolları, orada olacağını comm -23çıkışındaki git branch|sed|sortve git config -l|sed|sort.


1
@nmr s / git. * Q1 / test $ (git config --get branch. $ b.remote | sed q | wc -1) = 1 /
jthill

15

Bu benim için çalışıyor:

git branch -vv | grep -v origin

(eğer uzaktan kumandanız menşe dışında herhangi bir isimlendirildiyse, onu değiştirin).

Bu, aradığınız şeye benzeyen bir uzaktan kumandayı takip etmeyen tüm dalları listeleyecektir.


2
Bu, önceden uzaktan kumandaya sahip olan ancak çalıştırsanız bile artık bulunmayan dalları listeleyecektir git fetch --prune.
RusinaRange

2
IMO, "menşe" yi filtrelemek yerine ": gitti]" yi aramak daha iyi
fiorentinoing

4

origin/***: goneDalları almak için kendi Git komutumu sentezliyorum :

git remote prune origin && git branch -vv | cut -c 3- | grep ': gone]' | awk '{print $1}' | xargs -n1 -r echo git branch -d

git remote prune origin && git branch -vv dalları ayrıntılı modda yazdırır.

cut -c 3- ilk karakterleri kaldıracak.

grep ': gone]'yalnızca giden uzak dalları yazdırır .

awk '{print $1}' şube adını yazdıracaktır.

xargs -n1 -r echo git branch -dgit branch -ddalları kaldırmak için komutu yazdıracaktır (-n1 her seferinde bir komutu yönetecektir, -r dal yoksa komut verilmesini önlemek için).

İPUCU: yalnızca yazdırma yerine komutları çalıştırmak için "echo" komutunu kaldırın, bunu git'e vermeden önce komutları kontrol etmek için komutta bıraktım.

İPUCU 2:git branch -D Yalnızca ve yalnızca birleştirilmemiş dalları kaldırmak istediğinizden eminseniz yayınlayın


Bu benim kişisel yaptım dan git gone
fiorentinoing

1
Bu arayla buldum en temiz çözüm, güzel! Hiç ders çalışarak zaman harcamadım, awkbunu yapabileceğini bilmiyordum.
adamjc

2

İşte ne yaptığını açıklamak için yorumlarla birlikte PowerShell'de kullandığım bir şey. Neler olup bittiğini netleştirmek için kısaltılmış herhangi bir PowerShell komutu (takma adlar) kullanmadım. İstediğiniz şifreleme seviyesine sıkıştırmaktan çekinmeyin :)

$verboseList = @(git branch -vv)
foreach ($line in $verboseList)
{
    # Get the branch name
    $branch = [regex]::Match($line, "\s(\S+)\s").Captures.Groups[1].Value
    # Check if the line contains text to indicate if the remote is deleted
    $remoteGone = $line.Contains(": gone]")
    # Check if the line does not contain text to indicate it is a tracking branch (i.e., it's local)
    $isLocal = !($line.Contains("[origin/"))
    if ($remoteGone -or $isLocal)
    {
        # Print the branch name
        $branch
    }
}

0

Mevcut cevaplardan birkaçını birleştirmek:

[alias]
        branch-local = !git branch -vv | cut -c 3- | egrep '([0-9a-f]{7} [^[])|(: gone\\])' | sed -E 's/(^.+[0-9a-f]{7} (\\[.+\\])?).*$/\\1/'

Örneğin:

$ git branch-local
autogen_autoreconf      fcfb1c6 [github/autogen_autoreconf: gone]
autotools_documentation 72dc477 [github/autotools_documentation: gone]
cray-mpich-messy        2196f4b
epel-sphinx             cfda770
lammps                  07d96a7 [github/lammps: gone]
lark-error              9ab5d6c [github/lark-error: gone]
no-root2                c3894d1
openmpi-cray            69326cf [github/openmpi-cray: gone]
shellcheck-cleanup      40d90ec
travis-python36         cde072e
update_vagrant_default  4f69f47 [github/update_vagrant_default: gone]
web-docs                e73b4a8
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.