Yalnızca belirli bir dal için taahhüt almak için Git günlüğü


214

Yalnızca belirli bir dalın parçası olan tüm taahhütleri listelemek istiyorum.

Aşağıdakilerle, şubedeki tüm taahhütleri değil, aynı zamanda üst öğeden (master)

git log mybranch

Bulduğum diğer seçenek, usta tarafından ulaşılabilen taahhütleri hariç tutmak ve bana istediğimi vermekti, ancak diğer dalların isimlerini bilmekten kaçınmak istiyorum.

git log mybranch --not master

git for-each-refKullanmaya çalışıyordum , ama aynı zamanda mybranch listeliyor, bu yüzden aslında hepsi hariç:

git log mybranch --not $(git for-each-ref --format '^%(refname:short)' refs/heads/)

Güncelleme:

Bir süre önce bulduğum yeni bir seçeneği test ediyorum ve şimdiye kadar aradığım şey bu gibi görünüyor:

git log --walk-reflogs mybranch

Güncelleme (2013-02-13T15: 08):

--Walk-reflogs seçeneği iyi, ancak reflogs (varsayılan 90 gün, gc.reflogExpire ) için bir süre sonu olduğunu kontrol ettim .

Aradığım cevabı bulduğumu düşünüyorum:

git log mybranch --not $(git for-each-ref --format='%(refname)' refs/heads/ | grep -v "refs/heads/mybranch")

Sadece mevcut dalı mevcut şube listesinden kaldırıyorum ve bu listeyi günlükten hariç tutmak için kullanıyorum. Bu şekilde sadece mybranch'ın ulaştığı taahhütleri alıyorum .



Zaten bu soruyu da gördüm, ama aynı değil
dimirc

2
İstediğinden emin misin? Aklında bir hedef bulmayı daha iyi buluyorum: "şubemde yukarı akışta olmayanlar" ya da "dalda usta olmayanlar". Ayrıca, git budama sırasında hızlı olsa da, daha fazla dalınız olduğu için bu daha pahalı hale gelecektir. Ben bzr'ın "kayıp" komutundan sonra "git eksik" dediğim bir komut dosyası var. Burada bulabilirsiniz: github.com/jszakmeister/etc/blob/master/git-addons/git-missing .
John Szakmeister

1
Aslında bir sonrası alma kanca için buna ihtiyacım var, bu yüzden "usta" her zaman dışlamak için şube olmayacak
dimirc

Evet, StarPinkER tarafından belirtilen kopya benim için iyi çalıştı: git log $ (git merge-base HEAD branch) .. branch
charo

Yanıtlar:


165

Kullandığınız gibi göründüğünden cherry:

git cherry -v develop mybranch

Bu, mybranch içinde yer alan ancak geliştirme aşamasında DEĞİL olan tüm taahhütleri gösterecektir . Son seçeneği ( mybranch ) bırakırsanız , bunun yerine geçerli dal karşılaştırılır.

VonC'nin işaret ettiği gibi, DAİMA şubenizi başka bir şubeyle karşılaştırıyorsunuz, bu yüzden şubelerinizi bilin ve hangisiyle karşılaştırılacağını seçin.


4
Bu tam olarak ihtiyacım olan şeydi, ama bunun için daha sezgisel bir komut (evet, Git dünyasında bile) olmalı.
Seth

12
git cherry -v masterMevcut dalınızı ana dalla karşılaştırmak için de yapabilirsiniz .
Pithikos

2
Git cherry kullanmanın tehlikesi, taahhütlerin sadece dosya farklılıkları dallar arasında özdeş olması durumunda eşleşmesidir. Eğer bir dal ile diğer dal arasındaki farkları farklılaştıracak her türlü birleştirme yapılırsa, git cherry onları farklı taahhütler olarak görür.
Ben

Bu sadece bana veriyor fatal: Unknown commit mybranch.
Matt Arnold

1
@MattArnold "geliştirme" ve "mybranch" metnini repoda bulunan şubelere değiştirmeniz gerekiyor
Smilie

40

AMA Diğer dalların isimlerini bilmekten kaçınmak istiyorum.

Bunun mümkün olduğunu düşünmüyorum: Git'teki bir dal, " git diff yeterince göstermiyor " bölümünde açıklandığı gibi her zaman başka birine veya en azından başka bir işleme dayanmaktadır :

resim açıklamasını buraya girin

Günlüğünüzün doğru taahhütleri göstermesi için bir referans noktasına ihtiyacınız var.

" GIT - Nereden dallandım? "

şubeler sadece bir DAG'daki belirli taahhütlere işaret eder

Yani bile git log master..mybranchbir cevap ise, hala çok fazla hareketin gösterecek mybranchdayanmaktadır myotherbranch, kendisi dayalı master.

Bu referansı (şubenizin kökeni) bulmak için, taahhütleri ayrıştırabilir ve aşağıdaki şubelerde görüldüğü gibi hangi branşta olduklarını görebilirsiniz:


26

Sonunda OP'nin istediklerini yapmanın yolunu buldum. Bu kadar basit:

git log --graph [branchname]

Komut, sağlanan daldan erişilebilen tüm taahhütleri grafik biçiminde görüntüler. Ancak, *taahhüt satırındaki ilk karakter olan taahhüt grafiğine bakarak o daldaki tüm taahhütleri kolayca filtreleyebilirsiniz .

Örneğin, git log --graph masteraşağıdaki cakephp GitHub repo'sunun alıntısına bakalım :

D:\Web Folder\cakephp>git log --graph master
*   commit 8314c2ff833280bbc7102cb6d4fcf62240cd3ac4
|\  Merge: c3f45e8 0459a35
| | Author: José Lorenzo Rodríguez <lorenzo@users.noreply.github.com>
| | Date:   Tue Aug 30 08:01:59 2016 +0200
| |
| |     Merge pull request #9367 from cakephp/fewer-allocations
| |
| |     Do fewer allocations for simple default values.
| |
| * commit 0459a35689fec80bd8dca41e31d244a126d9e15e
| | Author: Mark Story <mark@mark-story.com>
| | Date:   Mon Aug 29 22:21:16 2016 -0400
| |
| |     The action should only be defaulted when there are no patterns
| |
| |     Only default the action name when there is no default & no pattern
| |     defined.
| |
| * commit 80c123b9dbd1c1b3301ec1270adc6c07824aeb5c
| | Author: Mark Story <mark@mark-story.com>
| | Date:   Sun Aug 28 22:35:20 2016 -0400
| |
| |     Do fewer allocations for simple default values.
| |
| |     Don't allocate arrays when we are only assigning a single array key
| |     value.
| |
* |   commit c3f45e811e4b49fe27624b57c3eb8f4721a4323b
|\ \  Merge: 10e5734 43178fd
| |/  Author: Mark Story <mark@mark-story.com>
|/|   Date:   Mon Aug 29 22:15:30 2016 -0400
| |
| |       Merge pull request #9322 from cakephp/add-email-assertions
| |
| |       Add email assertions trait
| |
| * commit 43178fd55d7ef9a42706279fa275bb783063cf34
| | Author: Jad Bitar <jadbitar@mac.com>
| | Date:   Mon Aug 29 17:43:29 2016 -0400
| |
| |     Fix `@since` in new files docblocks
| |

Eğer, sadece hareketin görebileceğiniz gibi 8314c2ff833280bbc7102cb6d4fcf62240cd3ac4ve c3f45e811e4b49fe27624b57c3eb8f4721a4323bsahip *olmak ilk karakteri satırları işlemek. Bu taahhütler ana daldan, diğer dördü diğer dallardan.


11

Aşağıdaki kabuk komutu istediğinizi yapmalıdır:

git log --all --not $(git rev-list --no-walk --exclude=refs/heads/mybranch --all)

Uyarılar

Teslim aldıysanız mybranch, yukarıdaki komut çalışmaz. Çünkü taahhütlere mybranchde ulaşılabilir HEAD, bu nedenle Git taahhütlerin benzersiz olduğunu düşünmez mybranch. İşaretlendiğinde çalışmasını sağlamak mybranchiçin aşağıdakiler için bir hariç tutma eklemeniz gerekir HEAD:

git log --all --not $(git rev-list --no-walk \
    --exclude=refs/heads/mybranch \
    --exclude=HEAD \
    --all)

Ancak, gereken değil dışlamak HEADsürece mybranchteslim edilir aksi takdirde münhasır olmayan hareketin gösteren riski, mybranch.

Benzer şekilde, origin/mybranchyerel mybranchşubeye karşılık gelen bir uzak şubeniz varsa , bunu hariç tutmanız gerekir:

git log --all --not $(git rev-list --no-walk \
    --exclude=refs/heads/mybranch \
    --exclude=refs/remotes/origin/mybranch \
    --all)

Ve uzak dal uzak depo için varsayılan dalsa (genellikle yalnızca doğru origin/master), hariç tutmanız gerekir origin/HEAD:

git log --all --not $(git rev-list --no-walk \
    --exclude=refs/heads/mybranch \
    --exclude=refs/remotes/origin/mybranch \
    --exclude=refs/remotes/origin/HEAD \
    --all)

Şube teslim alınmışsa ve uzak bir şube varsa ve uzak şube uzak depo için varsayılan değerse, çok şey hariç tutulur:

git log --all --not $(git rev-list --no-walk \
    --exclude=refs/heads/mybranch \
    --exclude=HEAD
    --exclude=refs/remotes/origin/mybranch \
    --exclude=refs/remotes/origin/HEAD \
    --all)

açıklama

git rev-listKomutu verilir revizyonları yürür ve SHA1 tanımlayıcıları karşılaşılan dökümlerini düşük seviyeli (tesisat) komuttur. git logYalnızca SHA1'i göstermemesi dışında eşdeğer olarak düşünün; günlük mesajı yok, yazar adı yok, zaman damgası yok, "süslü" şeylerin hiçbiri yok.

--no-walkSeçenek, adından da anlaşılacağı gibi, önler git rev-listsoy zincirini yürürken. Bu nedenle git rev-list --no-walk mybranch, yalnızca bir SHA1 tanımlayıcısı yazdıracaktır: mybranchdalın ipucu tanımlayıcısı .

Bağımsız --exclude=refs/heads/mybranch --alldeğişkenler git rev-list, dışında her başvurudan başlamasını söyler refs/heads/mybranch.

Bu nedenle, Çalıştırdığınızda git rev-list --no-walk --exclude=refs/heads/mybranch --allGit, hariç her ref'nin ipucu işleminin SHA1 tanımlayıcısını yazdırır refs/heads/mybranch. Bu hareketin kaydedilmesini ve atalarının sen olan kaydedilmesini olan değil de-bunlar yok kaydedilmesini olan ilgi değil görmek istiyorum.

Diğer kaydedilmesini biz çıktısını toplamak böylece, görmek istiyorum olanlardır git rev-list --no-walk --exclude=refs/heads/mybranch --allve her şeyi ama bu teslimleri ve onların ataları göstermeye Git söyle.

--no-walkArgümanı büyük depolar için gerekli olan (ve küçük depolara basit bir optimizasyon): Bu, Git yazdırmak zorunda kalacak olmadan ve kabuk toplamak zorunda kalacak (ve bellekte saklamak) çok daha fazla gereğinden fazla tanımlayıcıları işlemek. Büyük bir depoda, toplanan taahhütlerin sayısı kabuğun komut satırı argüman sınırını kolayca aşabilir.

Git hatası mı?

Aşağıdakilerin çalışmasını beklerdim:

git log --all --not --exclude=refs/heads/mybranch --all

ama öyle değil. Sanırım bu Git'teki bir hata, ama belki kasıtlı.


Güzel açıklama. +1
VonC

5
Buraya Mercurial'ın nasıl yapılacağını bilmek istedim hg log -b <branch>. İnsanların neden git'in düşmanca olduğunu söylediğini anlamıyorum. / s
weberc2

Neden git log --all --not --exclude=refs/heads/mybranch --allişe yaramıyor bilmiyorum ama git log refs/heads/mybranch --not --exclude=refs/heads/mybranch --allHEAD ve köken hariç tutmak için aynı uyarılar ile.
Ben C

8

Hızlı cevap:

git log $(git merge-base master b2)..HEAD

Diyelimki:

  1. Bir ana şubeniz olduğunu

  2. Birkaç işlem yapın

  3. B2 adında bir şube oluşturdunuz

  4. Yap git log -n1; Taahhüt Kimliği, b2 ve master arasındaki birleştirme tabanıdır

  5. B2'de birkaç işlem yapın

  6. git log b2 ve master günlük geçmişinizi gösterecek

  7. Taahhüt aralığını kullanın, konsepte aşina değilseniz, sizi google'a veya yığın taşmasına davet ediyorum,

    Gerçek bağlamınız için, örneğin

    git log commitID_FOO..comitID_BAR
    

    "..", log komutu için aralık operatörüdür.

    Bu, basit bir formda, commandID_FOO'dan daha yeni tüm günlükleri bana ver ...

  8. Birleştirme tabanı # 4 noktasına bakın

    Yani: git log COMMITID_mergeBASE..HEADsize farkı gösterecek

  9. Git sizin için birleştirme tabanını bu şekilde alabilir

    git merge-base b2 master
    
  10. Sonunda şunları yapabilirsiniz:

    git log $(git merge-base master b2)..HEAD
    

4

Böyle bir şey deneyebilirsiniz:

#!/bin/bash

all_but()
{
    target="$(git rev-parse $1)"
    echo "$target --not"
    git for-each-ref --shell --format="ref=%(refname)" refs/heads | \
    while read entry
    do
        eval "$entry"

        test "$ref" != "$target" && echo "$ref"
    done
}

git log $(all_but $1)

Veya Git Kullanım Kılavuzu'ndaki tariften ödünç almak :

#!/bin/bash
git log $1 --not $( git show-ref --heads | cut -d' ' -f2 | grep -v "^$1" )

+1. Cevabımda, şubenizin kökenini bulmak için taahhütleri ayrıştırmanız gerektiğini yazıyordum ve sadece bunu yapmışsınız gibi görünüyor.
VonC

Log --walk-reflog'larını kullandınız mı? Bu seçenek hakkında okuyorum ve bana şimdiye kadar ihtiyacım olan sonuçları veriyor, (hala test)
dimirc

@ dimirc Refloglar hep birlikte farklı bir canavardır. Genellikle iyileşme amacıyla, zaman içinde şube noktalarını kaydeder. Sonradan alma kancanızda ne yaptığınızdan emin değilim ama belki açıkladıysanız, millet probleminize daha mantıklı bir cevap verebilir.
John Szakmeister

Sadece bir gönderme tüm taahhüt mesajları ayrıştırmak / kontrol etmek gerekir. Ele almak istediğim durum, birisinin master'da birden fazla işlem gerçekleştirmesi ve birden fazla işlem içeren yeni bir şube oluşturmasıdır. Alma sonrası kanca hem refs / şube, örneğin master ve newbranch için yapılan değişiklikleri kontrol etmek gerekir, ben master taahhüt edilebilir çünkü taahhüt mesajları iki kez ayrışmasını önlemek için yeni şube için sınırları bilmek gerekir.
dimirc

1
Tamam. O zaman bence yukarıda özetlediğim yukarıdaki yaklaşım sizin istediğiniz şey. Reflog ile girişler bir süre sonra düşecek ve bence bu size bazı baş ağrılarına neden olacak. Siz de kullanmaya bakmak isteyebilirsiniz git show-ref --tags.
John Szakmeister

4
git rev-list --exclude=master --branches --no-walk

olmayan her dalın ipuçlarını listeleyecektir master.

git rev-list master --not $(git rev-list --exclude=master --branches --no-walk)

mastertarihinin başka bir şubenin tarihinde olmayan her taahhüdü listeleyecektir .

Sıralama seçimi için filtre boru hattını ayarlayan seçenekler için sıralama önemlidir, bu nedenle --branchesuygulanması gereken hariç tutma kalıplarını --no-walktakip etmeli ve rev-list yürümesi gerekmeyen taahhütleri sağlayan filtreleri takip etmelidir.


4

Bu işlem, geçerli daldaki taahhütlerin çıktısını alır. Herhangi bir argüman iletilirse, sadece sağlamaları çıktılar.

git_show_all_commits_only_on_this_branch

#!/bin/bash
function show_help()
{
  ME=$(basename $0)
  IT=$(cat <<EOF
  
  usage: $ME {NEWER_BRANCH} {OLDER_BRANCH} {VERBOSE}
  
  Compares 2 different branches, and lists the commits found only 
  in the first branch (newest branch). 

  e.g. 
  
  $ME         -> default. compares current branch to master
  $ME B1      -> compares branch B1 to master
  $ME B1 B2   -> compares branch B1 to B2
  $ME B1 B2 V -> compares branch B1 to B2, and displays commit messages
  
  )
  echo "$IT"
  exit
}

if [ "$1" == "help" ]
then
  show_help
fi

# Show commit msgs if any arg passed for arg 3
if [ "$3" ]
then
  OPT="-v"
fi

# get branch names
OLDER_BRANCH=${2:-"master"}
if [ -z "$1" ]
then
  NEWER_BRANCH=$(git rev-parse --abbrev-ref HEAD)
else
  NEWER_BRANCH=$1
fi

if [ "$NEWER_BRANCH" == "$OLDER_BRANCH" ]
then
  echo "  Please supply 2 different branches to compare!"
  show_help
fi

OUT=$(\git cherry $OPT $OLDER_BRANCH $NEWER_BRANCH)

if [ -z "$OUT" ]
then
  echo "No differences found. The branches $NEWER_BRANCH and $OLDER_BRANCH are in sync."
  exit;
fi

if [ "$OPT" == "-v" ]
then
  echo "$OUT"
else
  echo "$OUT" | awk '{print $2}'
fi

1
Bu benim için yaklaşık 100 alakasız günlük mesajı üretti.
Arlie Stephens

Hey @ArlieStephens - Denedim ve hala benim için çalışıyor gibi görünüyordu? Yukarıdakilere yardım ve daha fazla hata mesajı ekledim. Nasıl gittiğini bana bildirin!
Brad Parks

İlginç. Koda şimdi sahip olduğunuza baktığımda, umursadığım dalın ustadan geldiğini varsayarak orijinal kadar basit olabileceğini düşünüyorum. Geçerli kod ile, üst dalı açıkça belirtmiş olabilir. (IIRC, geliştirici
dalım

@ArlieStephens - evet herhangi bir işlevselliği değiştirdiğimi sanmıyorum .... Bir kez daha güncelledim ve bazı yerel testlerden sonra dokümanları biraz daha kesin yaptım ... ve daha önce var olan bir "ayrıntılı" seçeneği ekledim, ama ben bunu
Brad Parks

3

Aşağıdaki komutları kullanıyorum:

git shortlog --no-merges --graph --abbrev-commit master..<mybranch>

veya

git log --no-merges --graph --oneline --decorate master..<mybranch>

1

Bu yaklaşımı nispeten kolay buldum.

Şube ve sonrası

  1. Çalıştırmak

    git rev-list --simplify-by-decoration -2 HEAD
    

Bu sadece iki SHA sağlayacaktır:

1) Şubenin son taahhüdü [C1]

2) ve şubenin ilk taahhüdüne ana taahhüt [C2]

  1. Şimdi koş

    git log --decorate --pretty=oneline --reverse --name-status <C2>..<C1>
    

Burada C1 ve C2, ilk komutu çalıştırdığınızda alacağınız iki dizedir. Bu değerleri <> olmadan ikinci komuta koyun.

Bu, şube içinde dosya değişikliği geçmişinin listesini verecektir.


Sorunun ilk üç satırını okursanız, yazarın bu tam komutu listelediğini ve neden aradıklarının neden olmadığını açıklar
black_fm

Ah @black_fm Yanıtta bazı değişiklikler yaptım. Şimdi yararlı bulursanız oy kullanabilirsiniz. :)
Mustkeem K

0

Benim durumumda Git Flow ve GitHub kullanıyoruz. Tek yapmanız gereken: Özellik dalınızı GitHub'daki geliştirme dalınızla karşılaştırın.

Yalnızca özellik dalınıza yapılan taahhütleri gösterir.

Örneğin:

https://github.com/your_repo/compare/develop...feature_branch_name


"Bir çekme isteğinin nasıl görüneceğini görmek istiyorum" durumuna girdiğinizde, en iyi çözümün genellikle yoksaymak gitve bunun yerine bir çekme isteği yapmak veya dalları karşılaştırmak için GitHub'ı kullanmak olduğunu kabul ediyorum .
pkamb
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.