Git'te belirli bir kayıt için itme tarihi almanın bir yolu var mı?


93

Git günlüğündeki her kaydetme ile ilişkili bir gönderme tarihini görüntülemenin bir yolu olup olmadığını merak ediyorum. Bu mümkün değilse, tüm taahhütleri belirli bir baskı altında görmenin bir yolu var mı?

Taahhütleri itildikçe takip etmesi gereken bir program yazıyorum. Git günlüğü, gönderim tarihine göre değil, teslim tarihine göre sıralandığından, gönderilen en son taahhütleri göremiyorum. Örneğin, bir kullanıcı ana depoya göndermeden 2 gün önce kendi yerel deposunu taahhüt ederse, bu kayıt, ana depo günlüğündeki diğer kayıtların 2 gün gerisine yerleştirilecektir.

Yanıtlar:


77

Dağınık bilgileri toplamak ve sonunda bu soruya en iyi cevabı bulmak delicesine uzun zamanımı aldı, ama şimdi buna sahip olduğumu biliyorum. Sadece iki satırda, kod yok ve kancalar yok:

# required for a bare repo
git config core.logAllRefUpdates true

git reflog --date=local master

Sonunda basit.

Uyarı: Muhtemelen varsayılan değerleri gc.reflogExpireve değerlerini geçersiz kılmak istersiniz gc.reflogExpireUnreachable. git help reflogAyrıntıları kontrol edin ve bunun nasıl ve neden çalıştığını anlamak için.

Yukarıdaki iki komut , bastırdığınız klonun içinde çalıştırılmalıdır . Bu mümkün değilse, bir yaklaşım başka bir kalıcı klonda çalışacaktır :

git fetch               origin        # often and *regularly*
git reflog --date=local origin/master

Bu kalıcı klonu asla silmeyin, yoksa tarihleri ​​kaybedersiniz.


2
Benim durumumda , itmelerin listesini görmek için git reflog --date=local origin/master(not origin/) yapmam gerektiğini eklemek isterim . Aksi takdirde, listede yalnızca taahhütler, ödünç alma işlemleri ve çekmeler vardı (bu da yararlıdır). Aslında, @ JonathanDay'in cevabı bana işaret etti .
NIA

@NIA: origin / master sadece size bir tahmin verecektir. Yorumunuzun ardından cevabımı güncelledim, bu açıklığa kavuşturuyor mu?
MarcH

37

Git, dağıtılmış bir sürüm kontrol sistemidir, bu nedenle "itme tarihi" ile ne demek istediğinizi dikkatlice tanımlamanız gerekir. Örneğin, A kullanıcısının bazı commit'leri B kullanıcısının havuzuna gönderdiğini varsayalım. Bir süre sonra, B kullanıcısı aynı işlemleri üçüncü bir depoya gönderir. Hangi tarihle ilgileniyorsun?

Paylaşılan bir deponuz olduğunu ve bu paylaşılan deponun kullanıcılarının depoda ne zaman bir şey yayınlandığını belirleyebilmelerini istediğinizi tahmin ediyorum. Bu doğruysa, bu bilgileri paylaşılan depoda toplamanız gerekir.

Kötü haber

Maalesef, commit mesajlarına tarih eklemenin bir yolu yok. Bu, kayıt kimliğini (içeriğin SHA1 karması olan) değiştirerek her türlü soruna neden olur.

Güzel haberler

Neyse ki Git, notlar adı verilen (nispeten yeni) bir özelliğe sahiptir . Bu özellik, görüntüleyebilen kayıtlara rastgele metin eklemenizi sağlar git log. Notlar düzenlenebilir ve başkalarıyla paylaşılabilir.

Paylaşılan havuz tarafından alındığı için her işleme bir "bu işlem [tarih] tarihinde alındı" mesajı eklemek için notlar özelliğini kullanabilirsiniz.

Ayrıntılar git help notesiçin bakın.

Tarih nasıl kaydedilir

İşte tavsiye ettiğim yaklaşım:

  1. post-receiveGüncellenen her referans için her yeni erişilebilir kaydı yürütmek için paylaşılan deponuzdaki kancayı değiştirin .
  2. Her kayıt için, kaydetme notuna "[repository_url] 'nin [kullanıcısı] bu kaydı [ref]' e [tarih] tarihinde ekledi" gibi bir şey ekleyin.

    refs/notes/received-onVarsayılan yerine bu amaca (gibi ) adanmış bir not ref kullanmak isteyebilirsiniz refs/notes/commits. Bu, başka amaçlar için oluşturulan notlarla çakışmaları önleyecektir.

  3. receiveNot referansınızdaki güncellemeleri reddetmek için kancanızı değiştirin (kullanıcıların yanlışlıkla veya kasıtlı olarak notlarla uğraşmasını önlemek için).
  4. Tüm kullanıcılara aşağıdaki komutları çalışma ağaçlarının içinden çalıştırmalarını söyleyin:

    # Fetch all notes from the shared repository.
    # Assumes the shared repository remote is named 'origin'.
    git config --add remote.origin.fetch '+refs/notes/*:refs/remote-notes/origin/*'
    
    # Show all notes from the shared repository when running 'git log'
    git config --add notes.displayRef 'refs/remote-notes/origin/*'
    

    Bu adım gereklidir çünkü Git varsayılan olarak yukarı akış havuzlarındaki dallanmamış, etiket olmayan referansları yok sayar.

Yukarıdakiler referansların yalnızca gelişmiş olduğunu, asla silinmediğini veya zorunlu olarak güncellenmediğini varsayar. Muhtemelen post-receivebu durumları ele almak için kancanın "[tarih] tarihinde kaldırıldı" notlarını da eklemesini isteyeceksiniz .



8
git reflog show origin/master --pretty='%h %gd %gs %s' --date=iso

Bu benim için oldukça iyi çalışıyor gibi görünüyor. Kaydedici tarihi (% cd) yanıltıcıdır çünkü itme tarihiyle aynı olmak zorunda değildir. --Date = iso seçeneği, ancak itme / getirme tarihini verir .

Kaynak / ana sayfadan getirdiyseniz, aldığınız tarihi yazdıracağını unutmayın; Bir başkasının kaydı ittiği tarih DEĞİL.

 - %h:  abrev. hash
 - %gd: human readable reflog selector
 - %gs: reflog subject
 - %s:  subject/commit message

Bonus: Elbette daha güzel biçimlendirme yapabilirsiniz. Şimdiye kadar bu renk kodlamasını beğendim. Yine de yazmak biraz fazla. Bu, SHA'yı kırmızıya, yeniden günlüğe kaydetme seçicisini camgöbeğine ve yeniden günlüğe yazmayı yeşile gönderir.

git reflog show origin/master --pretty='format:%C(red)%h%Creset %C(cyan)%gd%Creset %C(green)%gs%Creset: %s' --date=iso

Merhaba VC, "reflog show origin / master --pretty = '% Cred% h% Creset -% C (yellow)% gd% Creset% Cblue (% gs)% Creset% s' komutunun çıktısının - -date = iso "is" da4c192cd -origin / master @ {2019-02-07 08:13:40 +0100} (çekin: hızlı ileri sarın) JIRA-2542 test raporunu geliştir ", o zaman şubem JIRA'nın içeriği -2542, başlangıç ​​/ ana bilgisayarda hızlı bir şekilde 2019-02-07 08:13:40 tarihinde birleştirildi?
Simon

Merhaba Simon, evet. Dalınıza gittiniz ve o anda hızlı ileri ile orijin / ana üzerinde birleştirildi.
VC

Yalnızca yazarın deposunda çalışır. Bir depoyu klonlarsam, değer boştur. Başkalarının zorlama zamanını göremezsiniz.
ramwin

6

Bir göz atın git reflog show master. Muhtemelen tam olarak istediğiniz format değil, ancak sizi doğru yöne yönlendirmelidir.

Başka bir fikir, bir itme kancası içinde bir komut dosyası çalıştırmaktır.


İtme kancasını çalıştırmayı düşündüm, ama bu son bir çare olmalı gibi görünüyor. Bir kancayla, her kullanıcının depolarının her birinde bu kancaya sahip olması gerekecek gibi görünüyor. Hakkında daha spesifik olabilir misin git reflog show master? Her kullanıcının bireysel taahhütlerinin gönderim tarihini görüntüleyebilmek istiyorum.
justkikuchi

git reflog, içinde çalıştırdığınız depodaki değişikliklerin sırasını gösterir . Tarihi almanın doğrudan bir yolu olup olmadığından emin değilim, ancak içinde .git/logs/refs/heads/masterbir zaman damgası gösteriyor.
Karl Bielefeldt

3
Kancalar gelince, zorlayacak makinede çalışacak kancaları var almaktadırlar için . İtme, yalnızca belirli bir repo ile ilgili olduğundan, üzerinde çalıştırmak istediğiniz belirli bir "kutsanmış" deponuz olduğunu varsayıyorum. Aynı şey git reflogbu konu için de geçerli.
Karl Bielefeldt

5

Uzaktan kumandadaki yeniden günlüğün incelenmesi ile ilgili bu cevap, size hangi dalın itildiğine dair bilgi vererek yardımcı olabilir ( https://stackoverflow.com/a/8791295/336905 ), hangi taahhütlerin itildiğini göstermez, ancak siz yerel tamamlama tarihinden sonraki aktarımı bularak çapraz ilişki kurabilir. Aptalca değil, ancak daha önce @RichardHansen tarafından yayınlanan mükemmel not önerisini henüz uygulamadıysanız kullanışlı


1
Reflog'un origin/branchyalnızca mevcut makinede yapılan değişiklikleri göstereceğini belirten bir notla , bu son derece yararlıdır! Günlük kullanım için herhangi bir kanca uygulamak istemiyorum, bu yüzden basit bir soru için "Hmmm, geçen hafta bu işlemi ne zaman zorladım?" - harika çalışıyor.
NIA

4

Ayrıca, sunucunun kendisindeki git deposundaki "nesneler" dizininde bulunan commit nesnesi dosyasının dosya değişiklik zamanına da bakabilirsiniz.


3

Git AuthorDate, CommitDate'ten neden farklı?

  • AuthorDate commit ilk oluşturulduğu zamandır.
  • CommitDate kaydetmenin en son değiştirildiği zamandır (örn. yeniden taban)

Bunları --prettybiçimlendirme seçenekleriyle elde edebilirsiniz :

       o    %cd: committer date
       o    %cD: committer date, RFC2822 style
       o    %cr: committer date, relative
       o    %ct: committer date, UNIX timestamp
       o    %ci: committer date, ISO 8601 format

Dolayısıyla, siz ve diğer geliştiriciler daha git rebaseönce yapıyorsanız , yazar tarihinden sonra git pusholan bir taahhüt tarihiyle sonuçlanacaksınız .

Bu komut, teslim tarihini gösterir: git log --pretty=fuller


1

Sanırım itme tarihini elde etmek için bir sonraki gösterimi kullanabilirsiniz: git log -g --date = local

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.