Git'i kullanarak, * yalnızca * belirli bir dalda var olan ve * başka * dallarda olmayan tüm işlemleri gösterin


87

Bir şube verildiğinde, yalnızca o şubede bulunan taahhütlerin bir listesini görmek isterim . Gelen bu soruya biz bir dal üzerinde ama daha başka dalları belirtilmemiş bir veya hangi kaydedilmesini bkz yollarını tartışmak.

Bu biraz farklı. Bir dalda ancak üzerinde hangi kaydedilmesini görmek istiyorum herhangi diğer dalları.

Kullanım durumu, bazı dalların yalnızca birleştirilmesi ve hiçbir zaman doğrudan taahhüt edilmesi gereken bir dallanma stratejisindedir. Bu, herhangi bir işlemin doğrudan "yalnızca birleştirme" dalında yapılıp yapılmadığını kontrol etmek için kullanılır.

DÜZENLEME: Test etmek için sahte bir git deposu kurma adımları aşağıdadır:

git init
echo foo1 >> foo.txt
git add foo.txt
git commit -am "initial valid commit"
git checkout -b merge-only
echo bar >> bar.txt
git add bar.txt
git commit -am "bad commit directly on merge-only"
git checkout master
echo foo2 >> foo.txt 
git commit -am "2nd valid commit on master"
git checkout merge-only 
git merge master

Yalnızca doğrudan yalnızca birleştirme dalında yapılan "yalnızca yalnızca birleştirmede doğrudan hatalı işleme" mesajını içeren kaydetme görünmelidir.


1
Bu soru, birleştirilmiş tüm şubelerin şu anda repoda mevcut olduğunu, tamamen birleştirildikten sonra asla silinmediğini ve belki de hızlı ileri sarma ile asla birleştirilmediğini varsayar. Bir şeyi kaçırırsam bana haber verin, ama bana öyle geliyor ki, bu sadece nispeten küçük bir izin verilen birleştirme dalları için uygulanabilir, öyleyse neden sadece git log ^branch1 ^branch2 merge-only-branchsözdizimini kullanmıyorsunuz ?
Karl Bielefeldt

1
git log ^branch1 ^branch2 merge-only-branchHer dalı dışarı listeleme gerektirir. Bu, bash / grep'in akıllıca kullanılmasıyla önlenebilir (aşağıdaki cevabıma bakın), ancak umarım git'in bunun için bazı yerleşik desteği vardır. Haklısınız, tüm birleştirme şubelerinin uzak olduğunu varsayıyor (yerel yalnızca diğer geliştiriciler için varolmayan kadar iyidir). --no-mergesAtlama işlemlerinin kullanılması , birleştirilen ve daha sonra orijinal birleştirme şubesinin silinmesine neden olur, bu nedenle, bu, yalnızca birleştirme olmayan bir şubeyle (yani ana) birleştirilene kadar birleştirme alanlarının burada tutulacağını varsayar.
jimmyorr

Yanıtlar:


76

Bu zarif çözümü yeni bulduk

git log --first-parent --no-merges

Örneğinizde elbette ilk yürütme hala ortaya çıkıyor.

bu cevap soruyu tam olarak cevaplamıyor çünkü ilk commit hala ortaya çıkıyor. Öte yandan, buraya gelen birçok insan aradıkları yanıtı buluyor gibi görünüyor.


1
Master'daki ilk commit hala göründüğünden, bu soruya cevap vermiyor.
jimmyorr

6
Bu yalnız tatmin etmiyor “sadece o dalda mevcut hareketin” gösterir şartlanma initial valid commithem bir parçası olan merge-onlyve masterdalları. Ancak, mevcut şubenin adını sonuna koyma çabası ve ardından mevcut şubenin kaynaklandığını bildiği ^ önekli şube ad (lar) ı gelirse, sorunların yarısını çözer (birleştirilmiş şeyler hariç). Ör:git log --first-parent --no-merges merge-only ^master
Slipp D. Thompson

14
Bunun neden bu kadar çok oy verildiğinden emin değilim, soruyla hiç alakalı görünmüyor. Posterin aradığı bilgiyi kesinlikle sağlamaz.
Chris Rasys

2
Bu cevap mükemmel olmayabilir. Ancak basit ve kesinlikle bir dereceye kadar işe yarıyor. Şube adını eklemeyi faydalı buluyorum - yani, belirli bir şubeye ait olan tüm taahhütleri filtreleyin:git log --first-parent --no-merges | grep <branch_name>
artm

1
Teşekkür ederim. En iyi çözüm imo.
Jakub Keller

29

Sevgili arkadaşım Redmumba'nın izniyle :

git log --no-merges origin/merge-only \
    --not $(git for-each-ref --format="%(refname)" refs/remotes/origin |
    grep -Fv refs/remotes/origin/merge-only)

... origin/merge-onlyyalnızca uzaktan birleştirme dal adınız nerede . Yerel bir salt git repo, yerine üzerinde çalışıyor Eğer refs/remotes/originbirlikte refs/headsve yedek uzaktan şube adı origin/merge-only, yerel şube adı ile merge-only, yani:

git log --no-merges merge-only \
    --not $(git for-each-ref --format="%(refname)" refs/heads |
    grep -Fv refs/heads/merge-only)

2
Bir başkasının yalnızca git kullanarak grepsiz bir çözüm sağlayabileceğini umuyorum, ancak değilse, bu oldukça zarif hissettiriyor.
jimmyorr

1
Evet, zarif. Kullanım git for-each-refkökenli her ref name listelemek için, ve grep -vbirleştirme salt dalı ortadan kalkmasını sağlar. tüm referanslar listemizi ilettiğimiz git logbir --notseçeneği alır (yalnızca birleştirme dalı hariç). Soruna daha zarif bir cevabınız varsa, duyalım.
jimmyorr

2
Eminim en zarif cevap budur. Sadece gerçek zarafet için biraz "sözlü / karmaşık" olduğunu iddia ediyorum. :-) Yaklaşımınızı kötülemek istemedim efendim!
Chris K

1
Sondaki /*olarak git for-each-refskomutları sahip olan bazı mevcut dosya eşleşen ve değil güvenmek failglobveya nullglobgrubu ( deneme seçenekleri, diğer kabuklar değişir). Yıldız işaretlerinden alıntı yapmalı / onlardan kaçmalısınız veya sonları bırakmalısınız /*( git for-each-reförüntüler "baştan bölü çizgisine kadar" eşleşebilir). Hangi referansların eleneceği konusunda daha katı olmak için grep -Fv refs/remotes/origin/foo( refs/heads/foo) kullanabilirsiniz .
Chris Johnsen

3
Yalnızca bir dalda mevcut olan ve başka bir dalda olmayan taahhütleri görmek istiyorsanız basitleştirilebilir: git log --no-merges B1 --not B2burada B1 ilgilendiğiniz daldır ve B2, B1 ile karşılaştırmak istediğiniz daldır. Hem B1 hem de B2 yerel veya uzak dallar olabilir, böylece git log --no-merges master --not origin/masteriki uzak dalı belirtebilir veya hatta belirtebilirsiniz.
mr.b

21
git log origin/dev..HEAD

Bu size şubenizde yapılan tüm taahhütleri gösterecektir.


2
@Prakash origin/branchName, uzak şubenin başına işaret edecek VE HEADbu şubedeki son yerel kesinleştirmenin taahhüdünü gösterecektir. Yani git push'u kullandığınızda bu çalışmayacaktır.
Bharat

Bunu başka bir yerel şubeyi karşılaştırmak için kullanabilirsiniz. --No-merges bayrağı, OP'nin orijinal sorusunu ele almak için de kullanışlı olabilir.
Paul Whipp

15

@Prakash cevap çalışıyor. Sadece açıklık için ...

git checkout feature-branch
git log master..HEAD

özellik dalındaki taahhütleri listeler, ancak yukarı akış dalındaki (tipik olarak ana biriminiz) listelenmez.



7

Bunu dene:

git rev-list --all --not $(git rev-list --all ^branch)

Temelde git rev-list --all ^branchşubede olmayan tüm revizyonları alır ve daha sonra repodaki tüm revizyonları alır ve sadece şubedeki revizyonlar olan önceki listeyi çıkarırsınız .

@ Brian'ın yorumlarından sonra:

Git rev-list belgelerinden:

List commits that are reachable by following the parent links from the given commit(s)

Dolayısıyla git rev-list A, A'nın bir kesinleştirme olduğu gibi bir komut , A dahil A'dan ulaşılabilen işlemleri listeleyecektir.

Bunu akılda tutarak,

git rev-list --all ^A

A'dan ulaşılamayan kayıtları listeleyecek

Böylece git rev-list --all ^branchşube ucundan ulaşılamayan tüm taahhütleri listeleyecektir. Bu, şubedeki tüm commit'leri veya başka bir deyişle sadece diğer branşlarda olan taahhütleri kaldıracaktır.

Şimdi gelelim git rev-list --all --not $(git rev-list --all ^branch)

Bu gibi olacak git rev-list --all --not {commits only in other branches}

Bu yüzden allerişilemeyenleri listelemek istiyoruzall commits only in other branches

Yalnızca aşağıdaki işlemlerin kümesidir : şubede . Basit bir örnek verelim:

             master

             |

A------------B

  \

   \

    C--------D--------E

                      |

                      branch

Burada amaç D ve E almaktır, başka hiçbir dalda taahhütler yoktur.

git rev-list --all ^branch sadece B ver

Şimdi, git rev-list --all --not Başağı indiğimiz şey bu. Aynı zamandagit rev-list -all ^B - tüm işlemlerin B'den erişilememesini istiyoruz. Bizim durumumuzda bu D ve E'dir. Biz de bunu istiyoruz.

Umarım bu, komutun nasıl doğru çalıştığını açıklar.

Yorumdan sonra düzenle:

git init
echo foo1 >> foo.txt
git add foo.txt
git commit -am "initial valid commit"
git checkout -b merge-only
echo bar >> bar.txt
git add bar.txt
git commit -am "bad commit directly on merge-only"
git checkout master
echo foo2 >> foo.txt 
git commit -am "2nd valid commit on master"

Yukarıdaki adımlardan sonra, eğer bir git rev-list --all --not $(git rev-list --all ^merge-only)yaparsanız, aradığınız taahhüdü alırsınız - "bad commit directly on merge-only"olanı.

Ancak adımlarınızdaki son adımı attığınızda git merge masterkomut beklenen çıktıyı vermeyecektir. Çünkü şu andan itibaren birleştirmede olmayan bir kesinleştirme yoktur - yalnızca ana öğedeki fazladan bir kesinleştirme de yalnızca birleştirme için birleştirildiğinden. Böylece git rev-list --all ^branchboş sonuç verir ve bu nedenle tüm taahhütleri yalnızca birleştirme olarak git rev-list -all --not $(git rev-list --all ^branch)verir .


1
Hm ... neden olduğundan emin değilim, ama bu pek işe yaramıyor. Komutunuzun çıktısını xargs -L 1 -t git branch -a --containsçok sayıda yanlış pozitif (aslında diğer dallarda olan taahhütler) göstermek için borulamak . Olsa da olmasa da denedim --no-merges. Yine de yanıtladığınız için teşekkürler!
jimmyorr

Sahte bir git deposunda görebildiğim kadarıyla benim için iyi çalışıyor gibi görünüyor.
manojlds

Sorunu yanıtınızla göstermeye yardımcı olmak için sahte bir git deposu oluşturmak için adımlar ekledim.
jimmyorr

Ah, hop. Ben başından beri düşünmeden önce buna oy verdim. git rev-list --all ^branchsize içinde olmayan tüm taahhütleri verecektir branch. Daha sonra listeden o çıkarırsınız vardır içinde branch; ama tanım gereği, içinde olmayan tüm işlemeler dahil branchdeğildir branch, bu nedenle hiçbir şey çıkarmazsınız. Jimmyorr'un aradığı şey var olan branchama olmayan taahhütler masterya da başka bir dal. İçinde olmayan commit'leri çıkarmak istemezsiniz branch; diğer dallardaki taahhütleri çıkarmak istersiniz.
Brian Campbell

1
@manojlds "(tüm revizyonlar) - (şubede olmayan tüm revizyonlar) = şubede revizyon." Evet, bu tüm revizyonları almak için işe yarıyor branch, ama öyle git rev-list branch. Sadece git rev-list branchdaha karmaşık (ve daha yavaş) bir şekilde yazıyorsunuz . branch Başka hiçbir dalda olmayan tüm taahhütlerin nasıl bulunacağı sorusuna cevap vermek işe yaramıyor .
Brian Campbell

2

Kabul edilen yanıtların başka bir varyasyonu, birlikte kullanmak için master

git log origin/master --not $(git branch -a | grep -Fv master)

Ana dışında herhangi bir dalda gerçekleşen tüm işlemeleri filtreleyin.


1

Bu tam olarak gerçek bir cevap değil, ancak biçimlendirmeye ve çok fazla alana erişmem gerekiyor. En iyi iki cevabın arkasındaki teoriyi açıklamaya çalışacağım: kabul edilen cevap ve (en azından şu anda) en üst sırada yer alan cevap . Ama aslında farklı sorulara cevap veriyorlar .

Git'teki işlemeler genellikle bir seferde birden fazla dalda "üzerindedir". Aslında, sorunun büyük kısmı bu. Verilen:

...--F--G--H   <-- master
         \
          I--J   <-- develop

büyük harfler gerçek Git karma kimlikleri için durmak nerede, biz sık sık aradığınız sadece taahhütH veya sadece taahhütI-J eden de git logçıktı. Aracılığıyla yukarı taahhüt GHangi hem dalları onları dışlamak istiyorum böylece.

(Bu şekilde çizilen grafiklerde yeni işlemlerin sağa doğru olduğuna dikkat edin. Adları tek hakkı-en bu hat üzerinde taahhüt Seçtiklerim kaydedilmesini her biri kendi soluna taahhüt olduğunu taahhüt bir ebeveyne sahip. Üst öğesini HDİR Gve üst Jolduğunu I. ebeveyni Iolan G. yine üst Golduğunu Fve Fsadece burada gösterilmeyen bir ebeveyni: bir 's parçası ...bölümünde).

Bu özellikle basit durum için şunları kullanabiliriz:

git log master..develop    # note: two dots

görüntülemek için I-Jveya:

git log develop..master    # note: two dots

Hsadece görüntülemek için. İki noktanın ardından sağ taraftaki isim Git'e şunu söyler: evet, bu taahhütler . İki noktanın önündeki sol taraftaki isim Git'e şunu söyler: hayır, bu taahhütler değil . Git başlar sonuna taahhüt -en Hveya taahhüt J-ve çalışır geriye . Bununla ilgili (çok) daha fazla bilgi için, bkz. Gibi Düşünün (a) Git .

Orijinal sorunun ifade edilme biçiminde arzu, belirli bir isimden erişilebilen , ancak aynı genel kategorideki başka herhangi bir isimden ulaşılamayan taahhütler bulmaktır . Yani, daha karmaşık bir grafiğimiz varsa:

               O--P   <-- name5
              /
             N   <-- name4
            /
...--F--G--H--I---M   <-- name1
         \       /
          J-----K   <-- name2
           \
            L   <-- name3

name4veya gibi bu isimlerden birini name3seçip sorabiliriz: bu isimle hangi kayıtlar bulunabilir, ancak diğer isimlerin hiçbirinde bulunamaz? Biz seçerseniz name3cevap taahhüt olduğunu L. Seçersek name4, cevap hiç commit değildir: name4adların commit olduğu , Nancak commit 'den Nbaşlayıp name5geriye doğru çalışarak bulunabilir .

Kabul edilen yanıt, şube adlarından ziyade uzaktan izleme adlarıyla çalışır ve hecelenen adlardan birini belirlemenize olanak tanır origin/merge-only ad) seçili ad olarak belirlemenize ve bu ad alanındaki diğer tüm adlara bakmanıza . Ayrıca, birleştirmeleri göstermekten de kaçınır: name1"ilginç ad" olarak seçersek ve bana ulaşılabilen name1ancak başka bir addan olmayan taahhütleri göster dersek , birleştirme işleminin Myanı sıra normal kaydetmeyi de göreceğiz I.

En popüler cevap oldukça farklı. Bu grafik işlemek geçme hakkında var olmayan , aşağıdaki iki bacağı ve bir birleştirme göstermeden kaydedilmesini herhangi olan birleştirir. name1Örneğin ile başlarsak , göstermeyeceğiz M(bu bir birleştirme), ancak birleştirmenin ilk ebeveyninin Mcommit olduğunu varsayarsak, Icommit'leri Jve K. Sonunda commit Ive ayrıca taahhütleri göstereceğizH , G, Fve böylece birleştirme kaydedilmesini ve tüm başlayarak tarafından ulaşılabilir on-hiçbiri bunlardan Mgeriye doğru çalışma, sadece ziyaret ilk her birleştirme taahhüt üst öğesini.

En popüler cevap, örneğin, masterne zaman masteryalnızca birleştirme dalı olması amaçlandığına bakmak için oldukça uygundur . Tüm "gerçek iş" sonradan birleştirilen yan dallarda yapıldıysa master, şöyle bir modelimiz olur:

I---------M---------N   <-- master
 \       / \       /
  o--o--o   o--o--o

tüm un harfli adlı nereye okaydedilmesini normal (-birleştirme) kaydedilmesini ve vardır Mve Nbirleştirme kaydedilmesini bulunmaktadır. Commit I, ilk commitdir: şimdiye kadar yapılan ilk commit ve master üzerinde olması gereken, birleştirme commit'i olmayan tek taahhüt. Eğer git log --first-parent --no-merges mastergösterileri herhangi taahhüt dışındaki I , böyle bir durum var:

I---------M----*----N   <-- master
 \       / \       /
  o--o--o   o--o--o

burada , bazı özellik dallarını birleştirerek değil, *doğrudan üzerinde yapılan kesinliği görmek istiyoruz master.

Kısacası, popüler cevap şuna bakmak için harika master ne zaman masteryalnızca birleştirme olması gerektiğine , ancak diğer durumlar için o kadar da iyi değildir. Kabul edilen cevap bu diğer durumlar için işe yarar.

Uzaktan izleme isimleri şuna benzer: origin/master şube isimleri mi?

Git'in bazı bölümleri olmadıklarını söylüyor:

git checkout master
...
git status

diyor on branch master ama:

git checkout origin/master
...
git status

diyor HEAD detached at origin/master. git checkout/ İle aynı fikirde olmayı tercih ederim git switch:origin/master Bir değil şube adı bunu "açık" alamayan çünkü.

Kabul edilen cevap , uzaktan izleme adlarını kullanıyororigin/* "şube adları" olarak :

git log --no-merges origin/merge-only \
    --not $(git for-each-ref --format="%(refname)" refs/remotes/origin |
    grep -Fv refs/remotes/origin/merge-only)

Çağıran orta çizgi git for-each-ref adlandırılmış uzaktan kumanda için uzaktan izleme adlarını yineler origin.

Bu orijinal probleme iyi bir çözümdür nedeni burada ilgilendiğiniz olmasıdır başkasının yerine, şube isimlerinin bizim şube isimlerinin. Ancak bu, şubeyi , şube isimlerimizden başka bir şey olarak tanımladığımız anlamına gelir . Sorun değil: bunu yaptığınızda, bunu yaptığınızın farkında olun.

git log commit grafiğinin bazı kısımlarını dolaşıyor

Burada gerçekten aradığımız şey, benim daglets adını verdiğim bir dizi: bkz . "Dal" ile tam olarak ne demek istiyoruz? Yani, genel commit grafiğinin bazı alt kümeleri içinde parçalar arıyoruz .

Git ne zaman masterbir etiket adı gibi bir dal adına bakarsak v2.1, ya da uzaktan izleme adı gibi origin/master, Git'in bize bu commit'den ve bu commit'den elde edebileceğimiz her commit'den bahsetmesini isteriz: oradan başlayarak ve geriye doğru çalışmak.

Matematikte buna grafikte yürümek denir . Git'in commit grafiği bir Directed Acyclic Graph veya DAG'dir ve bu tür bir grafik özellikle yürüyüş için uygundur. Böyle bir grafikte yürürken, kullanılan yol üzerinden erişilebilen her bir grafik tepe noktasını ziyaret edecek . Git grafiğindeki köşeler, her bir alt öğeden her bir ebeveyne giden kenarları yaylar (tek yönlü bağlantılar) olan işlemlerdir. (Burası Gibi Düşün (a) Git . Yayların tek yönlü doğası, Git'in çocuktan ebeveyne geriye doğru çalışması gerektiği anlamına gelir.)

Grafik yürüyüşü için iki ana Git komutu git logve git rev-list. Bu komutlar son derece benzerdir - aslında çoğunlukla aynı kaynak dosyalardan oluşturulurlar - ancak çıktıları farklıdır: git loginsanların okuması git rev-listiçin çıktı üretirken, diğer Git programlarının okuması için çıktı üretir. 1 Her iki komut da bu tür bir grafik gezintisi yapar.

Yaptıkları grafik gezintisi özellikle: bazı başlangıç ​​noktası taahhütleri verildiğinde (belki sadece bir işlem, belki bir grup karma kimliği, belki de karma kimliklere dönüşen bir grup isim), grafiği gezdirin, taahhütleri ziyaret edin . --notVeya bir önek gibi belirli yönergeler ^veya --ancestry-pathveya --first-parent, grafik yürüyüşünü değiştir yolunu bir şekilde değiştirir.

Grafik yürüyüşü yaptıkça, her bir işlemi ziyaret ederler. Ancak, yalnızca yürüyen işlemlerin bazı seçilmiş alt kümesini yazdırırlar . Gibi yönergeler veya yazdırmayı taahhüt eden grafik yürüyüş kodu söyler .--no-merges--before <date>

Bu ziyareti yapmak için, her seferinde bir işlem, bu iki komut bir öncelik kuyruğu kullanır . Koşarsınız git logveya git rev-listona bazı başlangıç ​​noktası taahhütleri verirsiniz. Bu taahhütleri öncelik sırasına koyarlar. Örneğin basit:

git log master

adı masterham bir karma kimliğine dönüştürür ve bu karma kimliğini sıraya koyar. Veya:

git log master develop

her iki adı da karma kimliklere dönüştürür ve - bunların iki farklı karma kimliği olduğunu varsayarak - her ikisini de kuyruğa koyar.

Bu kuyruktaki kayıtların önceliği, daha da fazla argüman tarafından belirlenir. Örneğin, argüman --author-date-ordersöyler git logveya git rev-listkullanmak kaydedici zaman damgası yerine yazar zaman damgasını . Varsayılan, kaydedici zaman damgasını kullanmak ve tarihe göre en yeni taahhüdü seçmektir: en yüksek sayısal tarihe sahip olanı. Dolayısıyla master develop, bu kararların iki farklı işleme olduğunu varsayarsak, Git hangisinin daha sonra önce geldiğini gösterecektir , çünkü bu, kuyruğun başında olacaktır.

Her durumda, revizyon yürüme kodu artık bir döngüde çalışır:

  • Kuyrukta kayıtlar varken:
    • İlk kuyruk girişini kaldırın.
    • Bu kaydı yazdırıp yazdırmayacağınıza karar verin. Örneğin,: --no-mergesbir birleştirme işlemiyse hiçbir şey yazdırma; --before: tarihi belirlenen zamandan önce gelmezse hiçbir şey yazdırmayın. Baskı Eğer değil bastırılmış, taahhüt yazdırın: için git log, onun günlüğünü gösterir; içingit rev-list , hash kimliğini yazdırın.
    • Bu commit'in üst kayıtlarının bir kısmını veya tamamını sıraya koyun (şu anda orada olmadığı ve daha önce ziyaret edilmediği sürece 2 ). Normal varsayılan, tüm üst öğeleri koymaktır. Kullanmak , her birleştirmenin ilk ebeveyni dışında --first-parenthepsini bastırır .

(Her ikisi de git logve ebeveyn yeniden yazma ile veya olmadan geçmiş basitleştirmegit rev-list yapabilir de bu noktada, ama biz burada bu aşkın atlarsınız.)

Başlangıçta HEADve birleştirme kaydetmeleri olmadığında geriye doğru çalışma gibi basit bir zincir için, kuyruğun her zaman döngünün en üstünde bir işlemesi vardır. Bir commit vardır, bu yüzden onu çıkarırız ve yazdırırız ve (tek) ebeveynini sıraya koyarız ve tekrar dolaşırız ve ilk kesinliğe ulaşana kadar zinciri geriye doğru takip ederiz veya kullanıcı git logçıktıdan yorulur ve çıkar. program. Bu durumda, sıralama seçeneklerinin hiçbiri önemli değildir: Gösterilecek yalnızca bir işlem vardır.

Birleşmeler olduğunda ve biz her iki ebeveyni de (birleştirmenin her iki "ayağını") takip ettiğimizde git logveya git rev-listbirden fazla başlatma kaydı verdiğinizde veya birden fazla başlatma işlemi yaptığınızda, sıralama seçenekleri önemlidir.

Son olarak, bir kesinleştirme belirticisinin etkisini --notveya ^önündeki etkisini düşünün . Bunları yazmanın birkaç yolu vardır:

git log master --not develop

veya:

git log ^develop master

veya:

git log develop..master

hepsi aynı anlama geliyor. --notÖnek gibidir ^birden fazla isim için geçerli olduğunu hariç:

git log ^branch1 ^branch2 branch3

şube1 değil, branch2 değil, evet branch3 anlamına gelir ; fakat:

git log --not branch1 branch2 branch3

Branch1 değil, branch2 değil, branch3 değil anlamına gelir ve --notkapatmak için bir saniye kullanmanız gerekir:

git log --not branch1 branch2 --not branch3

bu biraz garip. İki "değil" yönergesi XOR aracılığıyla birleştirilir, bu nedenle gerçekten isterseniz yazabilirsiniz:

git log --not branch1 branch2 ^branch3

demek değil branch1 değil Branch2, evet branch3 , eğer istersen obfuscate .

Bunların hepsi grafik yürüyüşünü etkileyerek çalışır. As git logveya git rev-listgrafiği yürür, o emin olur değil herhangi yani herhangi birinden ulaşılabilir taahhüt kuyruk öncelik koymak için olumsuzlanan referanslar. (Aslında, başlangıç ​​kurulumunu da etkilerler: olumsuzlanan taahhütler doğrudan komut satırından öncelik sırasına giremez, bu nedenle git log master ^masterörneğin hiçbir şey göstermez.)

Gitrevisions belgelerinde açıklanan tüm süslü sözdizimi bunu kullanır ve bunu basit bir çağrı ile ifşa edebilirsiniz git rev-parse. Örneğin:

$ git rev-parse origin/pu...origin/master     # note: three dots
b34789c0b0d3b137f0bb516b417bd8d75e0cb306
fc307aa3771ece59e174157510c6db6f0d4b40ec
^b34789c0b0d3b137f0bb516b417bd8d75e0cb306

Üç noktalı sözdizimi, sol veya sağ taraftan ulaşılabilen, ancak her ikisinden de ulaşılabilen taahhütler hariç anlamına gelir . Bu durumda origin/mastercommit, ( ) ' b34789c0bden kendiliğinden erişilebilir olduğundan, hash bir kez olumsuzlamayla iki kez görünür, ancak aslında Git üç nokta sözdizimini iki pozitif referans (olumsuzlanmamış iki hash ID) koyarak elde eder ve önek ile temsil edilen bir negatif .origin/pufc307aa37...origin/master^

Benzer şekilde:

$ git rev-parse master^^@
2c42fb76531f4565b5434e46102e6d85a0861738
2f0a093dd640e0dad0b261dae2427f2541b5426c

^@Sözdizimi araçlarının hepsi verilen anne işlemek ve master^kendisi şube-name tarafından seçilen kesinleştirme ilk ebeveyn masteriki anne vardır, böylece bir birleştirme taahhüt bu mu. Bunlar iki ebeveyn. Ve:

$ git rev-parse master^^!
0b07eecf6ed9334f09d6624732a4af2da03e38eb
^2c42fb76531f4565b5434e46102e6d85a0861738
^2f0a093dd640e0dad0b261dae2427f2541b5426c

Son ^!ek , commit'in kendisi anlamına gelir , ancak ebeveynlerinin hiçbiri anlamına gelmez . Bu durumda, master^bir 0b07eecf6.... Her iki ebeveyni de ^@son ek ile gördük ; işte yine buradalar, ama bu sefer reddedildi.


1 Birçok Git programı kelimenin tam anlamıyla çalışırgit rev-list çeşitli seçeneklerle ve hangi işlemlerin ve / veya diğer Git nesnelerinin kullanılacağını bilmek için çıktılarını okur.

2 Grafik döngüsel olmadığından, hiçbirinin daha önce ziyaret edilmemiş olduğunu garanti etmek mümkündür, eğer kısıtlama eklersek, tüm çocuklarını önceliğe göre göstermeden önce bir ebeveyne gösterme . --date-order, --author-date-orderve --topo-orderbu kısıtlamayı ekleyin. Adı olmayan varsayılan sıralama düzeni yoktur. Kaydetme zaman damgaları çirkinse (örneğin, saati kapalı olan bir bilgisayar tarafından "gelecekte" bazı taahhütler yapılmışsa), bu bazı durumlarda garip görünen çıktılara yol açabilir.


Bu kadar ileri gittiyseniz, şimdi hakkında çok şey biliyorsunuz git log

Özet:

  • git log grafiğin bir kısmını veya tamamını yürürken seçilen bazı taahhütleri göstermekle ilgilidir.
  • --no-mergesHer ikisinin de kabul ve halen-üst sıralarda cevapları bulundu argüman, bazı kaydedilmesini gösteren bastırır vardır yürüdü.
  • --first-parentArgüman, şu anda-üst sıralarda-cevap itibaren, bastırır yürüyüş sırasında, grafiğin bazı bölümlerini kendisi grafikte-yürüyün.
  • --notOlarak kabul edilen cevap kullanılan komut satırı argümanları önek, bastırır hiç ziyaret başından itibaren, hiç grafiğin bazı bölümlerini.

Bu özellikleri kullanarak iki farklı soruya beğendiğimiz yanıtları alıyoruz.

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.