Git ile iki tarih arasında gerçekleşen tüm işlemeler arasındaki farkı nasıl alabilirim?


117

Ya da sadece iki tarih arasında gerçekleşen tüm kayıtlar? SVN'de şöyle bir şey yapabilirsiniz:

svn diff -r{date}:{date}

yapmak için! Buna eşdeğer bir Git bulamıyorum.

Özellikle, o gün ve kim tarafından işlenen tüm kodlarla günlük e-postalar göndermek için bir komut dosyası yazmaya bakıyorum.

Yanıtlar:


160

Kullanabilirsin git whatchanged --since="1 day ago" -p

Aynı zamanda bir --untilargüman gerektirir.

Dokümanlar


Teşekkürler! İstediğim şey buydu, belgelerinde listelenmemiş olsa da --committer parametresini bile alıyor! ayrıca, 'git whatchanged', 'git help'de görünmedi! Neden olduğuna dair hiçbir fikrim yok ... tekrar teşekkürler.
Chris

5
Bunu seçtiğiniz cevabınız yapmalısınız ki seth biraz karma olsun.
Scott

18
@brbob Bunun uzun zaman önce yanıtlandığını biliyorum, ancak bununla (benim yaptığım gibi) tökezleyen biri için Git help diyor ki: The command is kept primarily for historical reasons; fingers of many people who learned Git long before git log was invented by reading Linux kernel mailing list are trained to type it. Yani, dokümanlar git logyerine kullanmayı teşvik ediyor git whatchanged; bu son komut da git log'un --no-merge seçeneğini kullanır, böylece aynı sonuçları verirler.
Ramses

2
göre nazik git log komutunun takma olduğunu whatchanged git git günlüğünün doc
Vincent

2
git whatchanged2.21.0'ın son sürümünden itibaren kullanımdan kaldırılmıştır. Tüm git whatchangedelde edilebilir git logve yalnızca tarihsel nedenlerle korunur. Ayrıntılara bakın git-scm.com/docs/git-whatchanged/2.21.0
Devy

60

Önceki önerilerin bazı dezavantajları var. Temelde eşdeğer bir şey arıyordum cvs diff -D"1 day ago" -D"2010-02-29 11:11". Daha fazla bilgi toplarken bir çözüm buldum.

Denediğim şeyler:

  • git whatchanged --since="1 day ago" -pdan burada

    Ancak bu, bir dosyada birden fazla kaydetme olsa bile her kayıt için bir fark verir. "Randevu" nun biraz gevşek bir kavram olduğunu biliyorum , bunu yapmanın bir yolu olmalı diye düşündüm.

  • git diff 'master@{1 day ago}..masterbazı uyarılar verir warning: Log for 'master' only goes back to Tue, 16 Mar 2010 14:17:32 +0100.ve tüm farklılıkları göstermez.

  • git format-patch --since=yesterday --stdout benim için hiçbir şey vermiyor.

  • revs=$(git log --pretty="format:%H" --since="1 day ago");git diff $(echo "$revs"|tail -n1) $(echo "$revs"|head -n1) bir şekilde çalışıyor, ancak karmaşık görünüyor ve mevcut şubeyle sınırlı değil.

En sonunda:

Tuhaf bir şekilde, git-cvsserver "cvs diff -D" yi desteklemez (bu olmadan bir yerde belgelenir).


4
+1 git rev-list, gördüğüm çok benzer problemi çözmek için uzun bir yol kat etti.
me_and

Bu kabul edilen cevap olmamalı, seth'inki daha kısa ve doğru.
ctford

6
@ctford, bence bu doğru değil. Bir dosya için birden çok farklılığı rapor edebilir, svn / cvs diff olarak dosya başına bir fark değil.
Weidenrinde

1
@Weidenrinde +1, bu çok daha akıllı
rostamn739

1
git diff 'master@{1 day ago}..masterSözdizimi aracı "kontrol reflog şube nerede ve şekil masternoktasına kullanılan yerel depoda 1 day ago ". Özellikle, mevcut şubenin gerçek kaydetme geçmişini kullanmayacak master. Bu çok nadiren gerçekten istediğiniz şeydir.
Mikko Rantalainen

22

"tarih" git'te biraz gevşek bir kavram. Bir commit, birisi kaydı kendi havuzuna gerçekten çekmeden / tamamlamadan önce bir süre geçmişte olabilecek bir yazar tarihine sahip olacaktır, ayrıca commit, görünüşte daha yeni bir commit üzerine olacak şekilde yeniden oluşturulabilir ve güncellenebilir.

Bir taahhüdün ayrıca, bir taahhüt yeniden onaylanırsa veya herhangi bir şekilde değiştirilirse güncellenen bir taahhüt tarihi vardır. Bu işlemlerin bir tür kronolojik sırada olma olasılığı daha yüksektir, ancak yine de bilgisayarında doğru zaman ayarına sahip olan işlemcinin insafına kalabilirsiniz ve bu durumda bile, değiştirilmemiş bir işlem, daha önce süresiz olarak uzak bir depodaki bir özellik dalında oturabilir. merkezi bir deponun ana dalına birleştiriliyor.

Muhtemelen amaçlarınız için en yararlı olan şey, söz konusu arşivdeki yeniden günlüğe kaydetme tarihidir. Dal başına yeniden günlükleri etkinleştirdiyseniz (bakın git config core.logAllRefUpdates), o zaman ref@{date}bir dalın belirli bir zamanda nerede olduğuna başvurmak için sözdizimini kullanabilirsiniz .

Örneğin

git log -p master@{2009-07-01}..master@{now}

Ayrıca aşağıdaki gibi 'belirsiz' açıklamaları da kullanabilirsiniz:

git log -p "master@{1 month ago}..master@{yesterday}"

Bu komutlar, yazara ve teslim tarihlerine göre gerçekte ne kadar "eski" olduklarına bakılmaksızın, deponun belirli dalında "görünen" tüm işlemleri gösterecektir.

Dallara göre yeniden günlüğün bir depoya özgü olduğunu unutmayın; bu nedenle, günlük komutunu bir klon üzerinde çalıştırıyorsanız ve (örneğin) bir ay boyunca çekmezseniz, son ayın tüm değişiklikleri bir kerede alın, daha sonra geçen ayın tüm değişiklikleri bir @{1 hour ago}..@{now}aralıkta görünecektir . Eğer insanların zorladığı 'merkezi' depoda log komutunu çalıştırabilirseniz, o zaman istediğinizi yapabilir.


Çok iyi bir yazı ve belirtilen soruya iyi cevap ... ama brbob'un amaçladığı şeyi yapmakta pek yardımcı olmayacağını düşünüyorum.
Jakub Narębski

Belli bir merkezi depodaki belirli bir dala itilen şeyi gerçekten ayrıştırmak istiyorsa ve log komutunun o depoda çalıştırılmasına yardımcı olabilir. Bir düzenleme olduğunu düşünüyorum ...
CB Bailey

"Bir taahhüt yeniden onaylanırsa veya herhangi bir şekilde değiştirilirse güncellenen taahhüt tarihi", aslında tarih asla değiştirilmez; tüm commit başka bir commit ile değiştirilir (ağaç sözde aynı olsa da).
hasen

2
@hasen j: Teknik olarak haklısınız. Taahhütler değişmezdir. Eğer rebase veya mesajı işlemek mevcut, yazar detayları ve yazar tarih genellikle eski kopyalanan, taahhüt bir taahhüt değişiklik ve yeni oluşturduğunuzda yüzden işlemek gibi yeni ile taahhüt id işlemek ve tarihi taahhüt güncelliyoruz.
CB Bailey

Not @{time spec}sözdizimi her zaman ifade eder sizin yerel reflog . Gerçek işleme geçmişine (DAG) atıfta bulunmaz. Farkı anlamazsanız, bu sözdizimini kullanmayın!
Mikko Rantalainen

14
git diff --stat @{2013-11-01}..@{2013-11-30}

veya

git diff --stat @{2.weeks.ago}..@{last.week}

Bu reflog'a bağlı mı? Çünkü eğer öyleyse, bu komutu çalıştırdığınız depo, içerdiği commit geçmişinden daha yeniyse (yani yeni klonlanmışsa) bunu gerçekten kullanamazsınız.

2
Evet, bu tamamen reflog'a bağlıdır. Ve evet, bu yalnızca yerel kopyalama geçmişinde çalışır, ancak biraz kullanışlı bir komuttur.
AA.

1
Evet, destekleyecek kadar eski yeniden günlüğe kaydetme girişleriniz olduğu sürece, kesinlikle uygun olduğuna katılıyorum.

AA teşekkür ederim. Cevabınızı kullanarak şunları yapabildim: git annotate --stat .. @ {2017-08-8} dosyaadı | daha az; git annotate --stat .. @ {5.days.ago} dosya adı; böylece değişiklikleri bağlamda görebiliyorum.
Chris

Not @{time spec}sözdizimi her zaman ifade eder sizin yerel reflog . Gerçek işleme geçmişine (DAG) atıfta bulunmaz. Farkı anlamazsanız, bu sözdizimini kullanmayın!
Mikko Rantalainen

4

belki

$ git format-patch --committer=<who> --since=yesterday --stdout

istediğiniz şey nedir ('--stdout' ile veya olmadan)?


1
Kısa bir soru, - çünkü taahhüt tarihini kullanıyor mu?
CB Bailey

3

Genel çözümün şunu kullanmak olduğuna inanıyorum:

git rev-list -n1 --first-parent --until=<a date string> <a ref>

--First-parent olmadan, daha sonra birleştirilen a refancak şu anda birleştirilmemiş olan bir şubeden taahhüt alabilirsiniz .a date string .

İşte --childrenve grepyerine bir alternatif -n1:

mlm_git_ref_as_of() {
    # # Examples #
    #
    # Show all commits between two dates:
    #
    #     git log $(mlm_git_ref_as_of '2012-05-21 09:00:00-0400')..$(mlm_git_ref_as_of '2012-05-21 17:00:00-0400')
    #
    # Show diffs of all commits between two dates:
    #
    #     git diff $(mlm_git_ref_as_of '2012-05-21 09:00:00-0400')..$(mlm_git_ref_as_of '2012-05-21 17:00:00-0400')
    local as_of="$1"
    local ref="${2:-HEAD}"
    # Get the most recent commit (--children, grep -v ' ') that was on
    # the given branch ($ref, --first-parent) as of a given date
    # ($as_of)
    git rev-list --children --first-parent --until="$as_of" "$ref" | grep -v ' '
}

git whatchangedBu Soru-Cevap bölümünü okumadan önce aşina değildim , ama benim için çok farklı sonuçlar veriyor, bu yüzden ne yaptığından emin değilim.


3

Belirli bir tarihten itibaren tüm değişikliklerin farkını elde etmenin başka bir basit yolu, Xo tarihte veya daha sonra gerçekleşen ilk kesinlemeyi bulup ardından kullanmaktır.

git diff X

Bu, yeni bir klondaki yeniden günlüğe kaydetme girişlerine bağlı olmaması avantajına sahiptir.

git diff <reference>@{n}..
git log <reference>@{n}..

çözümleri


3

Git dosyalarının dalınızda tarihe göre değişikliklerini izlemek için aşağıdaki formülü kullanın:

  1. şubenizi kontrol edin.
  2. uzak depodan değişiklikleri çek ve güncelle
  3. tarih aralığından farklı dosyaları izle

Formül :

git checkout <branch>
git pull
git diff --stat @{fromDate}..@{toDate}

Tarihlerin YYYY-AA-GG biçiminde olmasına dikkat edin :

git diff --stat @{2019-08-20}..@{2019-08-21}

Belirli bir zaman aralığında belirli bir dosyadaki değişiklikleri gözlemlemek isterseniz (koddaki farkı izleyin), sadece geçerli dosyaya gidin:

Örnek :

git diff @{2019-01-01}..@{2019-01-02} ~/dev/myApp/package.json

2

Bu daha komik bir cevap çünkü muhtemelen daha iyi bir yol var. Bu, bugün için tüm commit karmalarını gösterecektir.

git log --pretty="format:%H %ai" | grep `date +"%Y-%m-%d"` | awk {'print $1'}`

; ·)


2

Git-format-patch'i de kullanabilirsinizYamalar (farklar) hazırlamak ve e-posta yoluyla göndermek için .

Kaydetme aralığını belirlemek için [başlangıç] veya [revizyon aralığı] seçeneklerini kullanın.


0

Bunu yaptığım şekilde atacağım: git logbir tarih için size mevcut dal için kesin hashler verir. Daha sonra git diff 8fgdfg8..565k4l5, dosyalara göre birleştirilmiş bana uygun bir fark veren bir şey kullanıyorum . Umarım bu yardımcı olur, pek test edilmemiştir

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.