Git remote prune, git prune, git fetch --prune, etc arasındaki farklar nelerdir?


360

Benim durumum bu ... aynı repo üzerinde çalışan biri yerel ve uzak repo bir şube sildi ...

Stack Overflow veya diğer sitelerdeki bu tür bir sorun hakkında soru soran çoğu insan git branch -a, alt kısımdaki uzaktan izleme şube listelerinde hala gösterilen şube sorununa sahiptir :

* master
  develop
  feature_blah
  remotes/origin/master
  remotes/origin/develop
  remotes/origin/feature_blah
  remotes/origin/random_branch_I_want_deleted

Ancak, MY durumumda orada olmaması gereken şube yereldir:

* master
  develop
  feature_blah
  random_branch_I_want_deleted
  remotes/origin/master
  remotes/origin/develop
  remotes/origin/feature_blah

Aşağıdakilerden herhangi birini yaptığımda, yerel olarak kaldırılmaz:

$ git prune

Ayrıca denedim:

$ git remote prune origin
$ git fetch --prune

Daha yararlı bilgiler: Ne zaman kontrol git remote show originbu görünüyor:

* remote origin
Fetch URL: utilities:homeconnections_ui.git
Push  URL: utilities:homeconnections_ui.git
HEAD branch: master
Remote branches:
 master                        tracked
 develop                       tracked
 feature_blah                  tracked
 other123                      tracked
 other444                      tracked
 other999                      tracked
Local branches configured for 'git pull':
 develop                      merges with remote develop
 feature_blah                 merges with remote other999
 master                       merges with remote master
 random_branch_I_want_deleted merges with remote random_branch_I_want_deleted
Local refs configured for 'git push':
 develop         pushes to develop     (local out of date)
 master          pushes to master      (up to date)
 feature_blah    pushes to feature_blah(up to date)

Sadece başlıklı bölümde olduğuna dikkat edin Local branches configured for 'git pull':

Neden?


git branch -d the_local_branch
krsteeve

1
Teşekkürler, ama neden ortaya çıktığını merak ediyorum.
gogogadgetinternet

Şube hiyerarşisi ( x/y) ile ilgili küçük bir fark vardı : düzeltildi ( aşağıdaki
cevabıma

Yanıtlar:


665

Bu konuda sinirli olduğunuz için sizi suçlamıyorum. Bakmanın en iyi yolu şudur. Her uzak dalın potansiyel olarak üç sürümü vardır:

  1. Uzak depodaki gerçek şube
    (ör. Https://example.com/repo.git adresindeki uzaktan repo , refs/heads/master)
  2. Bu şubenin anlık görüntüsü (altında depolanır refs/remotes/...)
    (ör. Yerel repo, refs/remotes/origin/master)
  3. Ve uzak dalı izleyebilecek bir yerel şube
    (ör. Yerel repo, refs/heads/master)

İle başlayalım git prune. Bu , artık başvurulmayan nesneleri kaldırır , başvuruları kaldırmaz. Sizin durumunuzda yerel bir şubeniz var. Bu random_branch_I_want_deleted, o dalın geçmişini temsil eden bazı nesnelere karşılık gelen bir ref var demektir . Yani, tanımı gereği, git prunekaldırmayacak random_branch_I_want_deleted. Gerçekten, git pruneGit'te biriken ancak hiçbir şey tarafından referans alınmayan verileri silmenin bir yoludur. Genel olarak, herhangi bir dal hakkındaki görüşünüzü etkilemez.

git remote prune originve git fetch --pruneher ikisi de aşağıdaki referanslar üzerinde çalışır refs/remotes/...(bunlara uzak referanslar olarak değineceğim). Yerel şubeleri etkilemez. git remoteYalnızca belirli bir uzaktan altında uzak başvuruları kaldırmak istiyorsanız sürüm faydalıdır. Aksi takdirde, ikisi de aynı şeyi yapar. Yani, kısacası git remote pruneve git fetch --pruneyukarıdaki 2 numara üzerinde çalışın. Örneğin, git web GUI'sini kullanarak bir dalı sildiyseniz ve artık yerel şube listenizde görünmesini istemiyorsanız ( git branch -r), bu durumda kullanmanız gereken komut budur.

Yerel bir dalı kaldırmak için git branch -d(veya -Dhiçbir yerde birleştirilmemişse) kullanmanız gerekir . FWIW, uzak bir dal kaybolursa yerel izleme dallarını otomatik olarak kaldırmak için git komutu yoktur.


22
Bu, ilgili farklılıkları açıklayarak genel soruyu ele almada daha iyi bir iş çıkarır. Ayrıca, yukarıdaki soruya ilişkin ek sorularıma cevap veriyor.
gogogadgetinternet

14
Bu komut, karşılık gelen bir uzak dalı olmayan tüm yerel dalların bir listesini gösterir. Sen olabilir boru Buna xargs git branch -Dancak not oluşturmuş ancak sunucusuna aktarılır hiç herhangi bir yeni şube silinmiş olacağını, böylece taban dikkatle: git branch -r | awk '{print $1}' | egrep -v -f /dev/fd/0 <(git branch -vv | grep origin) | awk '{print $1}'
Jason Walton

4
@ Tohum Hayır hayır. :-( Sadece yerel uzaktan izleme referanslarını siler. Bunu 2.7.0 sürümü ile tekrar kontrol ettim.
John Szakmeister

1
@ BlueRaja-DannyPflughoeft Bu yaklaşıma dikkat edin. Örneğin, kararlı dallarınızı nasıl yaptığınıza bağlı olarak, bunlar ana dalda birleştirilmiş gibi görünebilir ve sonunda bunları kaldırabilirsiniz. Bunları sunucudan kaldırmamanız nedeniyle büyük bir kayıp değil, ancak bunun için ayarladığınız herhangi bir özel yapılandırmanız varsa, şube silindiğinde bu kaybolacaktır.
John Szakmeister

1
@Cloud Tamamen doğru değil. Referanslar paketlenebilir (bölgedeki packed-refsdosyaya bakın .git), bu yüzden onları dosya gezgini ile silmek basit bir mesele değildir. Her ikisinin de doğru şekilde yapıldığından emin olmak için komutları kullanmak daha iyidir.
John Szakmeister

55

git remote pruneve git fetch --pruneaynı şeyi yapın: Dediğin gibi, uzaktan kumandada bulunmayan dallara yapılan başvuruları silmek. İkinci komut uzaktan kumandaya bağlanır ve budamadan önce mevcut dallarını getirir.

Ancak, kontrol ettiğiniz yerel şubelere dokunmaz, yalnızca silebilirsiniz.

git branch -d  random_branch_I_want_deleted

Değiştir -dtarafından -Dşube başka yerde birleşti değilse

git prune farklı bir şey yaparsa, ulaşılamayan nesneleri, herhangi bir dalda veya etikette ulaşılamayan ve bu nedenle artık gerekmeyenleri temizler.


1
Açıkça göründüğünü biliyorum, ancak git prunesadece dallar ve etiketler için değil, diğer tüm referanslar için de görünüyor.

Peki benim durumumda, neden kuru erik işe yaramasın ki? Yerel şubeleri değil, uzak referansları önemsediğinden mi? Kısa bilgi için teşekkürler.
gogogadgetinternet

@hvd Şubeler ve etiketler dışında ne tür referanslar var?
CharlesB

@gogogadgetinternet evet aynen. (demek istediğini varsayalım git remote prune)
CharlesB

4
IMO nesne koleksiyonu ikisi için "eriği" kullanmakla adlandırma kuralı git ve referans-temizleme olduğu karışıklık içinde. Setleri Ama bu GIT'de, sadece bir kullanıcı arayüzünde birçok puzzlements yüzünden. :-)
torek

14

Herkesin ilgilenmesi durumunda. Uzaktan izlenmeyen tüm yerel şubeleri kaldıracak hızlı bir kabuk betiği. Dikkatli bir kelime: Bu, birleştirilip birleştirilmediğine bakılmaksızın uzaktan izlenmeyen herhangi bir daldan kurtulacaktır.

Bununla ilgili herhangi bir sorun görürseniz lütfen bana bildirin, düzeltirim (vb.)

Açık adlı bir dosyaya kaydedin git-rm-ntb(ne olursa olsun çağırın) PATHve çalıştırın:

git-rm-ntb <remote1:optional> <remote2:optional> ...

clean()
{
  REMOTES="$@";
  if [ -z "$REMOTES" ]; then
    REMOTES=$(git remote);
  fi
  REMOTES=$(echo "$REMOTES" | xargs -n1 echo)
  RBRANCHES=()
  while read REMOTE; do
    CURRBRANCHES=($(git ls-remote $REMOTE | awk '{print $2}' | grep 'refs/heads/' | sed 's:refs/heads/::'))
    RBRANCHES=("${CURRBRANCHES[@]}" "${RBRANCHES[@]}")
  done < <(echo "$REMOTES" )
  [[ $RBRANCHES ]] || exit
  LBRANCHES=($(git branch | sed 's:\*::' | awk '{print $1}'))
  for i in "${LBRANCHES[@]}"; do
    skip=
    for j in "${RBRANCHES[@]}"; do
      [[ $i == $j ]] && { skip=1; echo -e "\033[32m Keeping $i \033[0m"; break; }
    done
    [[ -n $skip ]] || { echo -e "\033[31m $(git branch -D $i) \033[0m"; }
  done
}

clean $@

Teşekkürler! Renkli çıktı ile hoş bir dokunuş ;-)
BVengerov

2
$ (Git branch -d $ i) yalnızca birleştirilmiş şubeleri silmek için daha güvenli olmaz mıydı?
user2012677


13

Tom Miller ( ) tarafından 10a6cc8 taahhüdü ile arasındaki git remote --pruneve arasındaki farkın git fetch --prunegiderildiğine dikkat edin (git 1.9 / 2.0, 1. Çeyrek 2014 için):tmiller

frotz/nitfolÖnceki bir getirme işleminden "" adında bir uzaktan izleme şubemiz olduğunda ve akış yukarı şimdi "** frotz " ** adında bir şubeye sahip olduğunda, akış yukarıdanfetch " frotz/nitfol" ile " " kaldırılamaz git fetch --prune.
git git remote prune, sorunu " " kullanması için kullanıcıyı " " bilgilendirir .

Dolayısıyla: yukarı akış bir repo , şube hiyerarşisiyle aynı ada sahip bir dalı ("frotz") (olası bir şube adlandırma kuralı olan "frotz / xxx" ) git remote --prunebaşarılı olduğunda (repodan uzak izleme dalını temizlerken) , ama git fetch --prunebaşarısız oldu.

Artık değil:

fetch --pruneGetirme işleminden önce budama işlemini hareket ettirerek " " çalışma şeklini değiştirin .
Bu şekilde, kullanıcıyı bir çakışma konusunda uyarmak yerine otomatik olarak düzeltir.

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.