Git sürümünü kullanarak bir dosyanın değişiklik geçmişini görüntüleme


3089

Git'te tek bir dosyanın değişiklik geçmişini nasıl değiştirebilirim?

Ben kadarıyla var:

git log -- [filename]

bu da dosyanın işlenme geçmişini gösterir, ancak her dosyanın içeriğinde nasıl değişiklik olur?

MS SourceSafe geçiş yapmaya çalışıyorum ve bu basit bir right-clickshow history.


41
Yukarıdaki bağlantı artık geçerli değil. Bu bağlantı bugün çalışıyor: Git Topluluk Kitabı
chris

1
Yukarıdaki bağlantı (Chris tarafından yayınlanmıştır) artık geçerli değil. Bu bağlantı bugün çalışıyor: git-scm.com/book/en/v2
Cog

Yanıtlar:


2370

Bunun için kullanacağım:

gitk [filename]

veya dosya adlarını geçmiş isimleri takip etmek

gitk --follow [filename]

28
Ama daha doğrusu, yukarıdakileri 'git suçlama' ile birleştiren bir araca sahibim, zaman içinde değiştiğinde bir dosyanın kaynağına göz
atmamı sağlıyor

26
Ne yazık ki, bu dosyanın geçmiş adlarını geçmişini izlemiyor.
Dan Moulding

146
Ayrıca daha önce yeniden adlandırılmış ve ilk önce bu iş parçacığı bulunan dosyaların geçmişini arıyordum. Solüsyon "git log --follow <filename>" Kullanılacak Phil olarak işaret dışarı burada .
Florian Gutmann

115
Yazar bir komut satırı aracı arıyordu. Gitk GIT ile birlikte gelirken, ne bir komut satırı uygulaması ne de özellikle iyi bir GUI.
mikemaccana

72
Bir komut satırı aracı mı arıyordu? "sağ tıklama -> geçmişi göster" kesinlikle bunu ima etmez.
hdgarrood

2234

Kullanabilirsiniz

git log -p filename

git'in her günlük girişi için yamaları oluşturmasına izin vermek.

Görmek

git help log

daha fazla seçenek için - aslında çok güzel şeyler yapabilir :) Belirli bir taahhüt için sadece fark almak için

git show HEAD 

veya tanımlayıcıya göre başka bir düzeltme. Veya kullan

gitk

değişiklikleri görsel olarak gözden geçirmek için.


8
git show HEAD tüm dosyaları gösterir, tek bir dosyayı nasıl izleyeceğinizi biliyor musunuz (Richard'ın istediği gibi)?
Jonas Byström

5
kullanıyorsunuz: git show <revision> - dosya adı, varsa bu düzeltme için farkları gösterir.
Marcos Oliveira

4
--tat da yararlıdır. -P ile birlikte kullanabilirsiniz.
Raffi Khatchadourian

5
Bu harika. gitk artık var olmayan yolları belirtirken iyi davranmıyor. Git log -p - yolunu kullandım.
Paulo Casaretto

6
Ayrıca gitk, boogie canavarı tarafından yapılmış gibi görünüyor. Bu harika bir cevap ve en iyi orijinal soruya uyarlanmıştır.
ghayes

1497

git log --follow -p -- path-to-file

Bu , dosyanın tüm geçmişini gösterir (yeniden adlandırmaların ötesinde ve her değişiklik için farklılıklar içeren geçmiş dahil).

Başka bir deyişle, adlandırılan dosya bir barzamanlar adlandırılmışsa foo, git log -p bar( --followseçenek olmadan ) dosyanın geçmişini yalnızca yeniden adlandırıldığı noktaya kadar gösterir - dosyanın tarihi olarak bilinirse gösterilmez foo. Kullanıldığında git log --follow -p bardosyada bilinen tüm değişiklikler de dahil olmak üzere dosyanın tüm geçmişi gösterilir foo. Bu -pseçenek, her değişiklik için farkların eklenmesini sağlar.


18
--tat da yararlıdır. -P ile birlikte kullanabilirsiniz.
Raffi Khatchadourian

23
Bunun GERÇEK cevap olduğuna katılıyorum. (1.) --followdosya yeniden -padlarını görmenizi sağlar (2.) dosyanın nasıl değiştirildiğini (3.) yalnızca komut satırı olduğunu görmenizi sağlar.
Trevor Boyd Smith

3
@NHDaly --eklendiğini fark ettim , ama bunun neden bunu en iyi yaptığını bilmiyorum? Ne yapar?
Benjohn

40
@Benjohn --Seçenek Git'e seçeneklerin sonuna geldiğini ve takip eden her şeyin --argüman olarak ele alınması gerektiğini söyler . Bunun için git logsadece çizgi ile başlayan bir yol adınız varsa herhangi bir fark yaratır . Talihsiz adı "--follow" olan bir dosyanın geçmişini bilmek istediğinizi varsayalım:git log --follow -p -- --follow
Dan Moulding

10
@Benjohn: Normalde, --yararlıdır, çünkü revisiongirdiğiniz dosya adıyla eşleşen ve gerçekten korkutucu olabilecek herhangi bir isme karşı da koruma sağlayabilir. Örneğin: bir şube ve adlı bir dosya hem olsaydı foo, git log -p fooiçin git günlük tarihini gösterir foo, değil geçmişini dosyası foo . Ancak @DanMoulding, --followkomutun argümanı olarak yalnızca tek bir dosya adı aldığı için, bu olamaz çünkü daha az gereklidir revision. Bunu yeni öğrendim. Belki o zaman cevabını cevabın dışında bırakma hakkın vardı; Emin değilim.
NHDaly

172

Metin tabanlı kalmayı tercih ederseniz, tig kullanmak isteyebilirsiniz .

Hızlı kurulum:

  • uygun :# apt-get install tig
  • Homebrew (OS X) :$ brew install tig

Geçmişi tek bir dosyada görüntülemek için kullanın: tig [filename]
Veya ayrıntılı repo geçmişine göz atın:tig

Benzeri gitkancak metin tabanlı. Terminaldeki renkleri destekler!


23
Mükemmel metin tabanlı araç, harika cevap. Başsız sunucuma gitk yüklemesinin bağımlılıklarını görünce korktum. Tekrar A +++
Tom McKenzie

Belirli dosyalara da tig ile bakabilirsiniz, yanitig -- path/to/specific/file
gloriphobia

109

git whatchanged -p filenamegit log -p filenamebu durumda da eşdeğerdir .

Ayrıca, bir dosyanın içindeki belirli bir kod satırının ne zaman değiştirildiğini de görebilirsiniz git blame filename. Bu, dosyadaki her satır için kısa bir taahhüt kimliği, yazar, zaman damgası ve eksiksiz kod satırı yazdırır. Bu, bir hata bulduktan ve ne zaman tanıtıldığını (veya kimin hata olduğunu) bilmek istediğinizde çok yararlıdır.


4
+1, ancak filenamekomutta isteğe bağlı değil git blame filename.
rockXrock

7
"Yeni kullanıcılar bunun yerine git-log'u kullanmaya teşvik ediliyor. (...) Komut öncelikle tarihsel nedenlerle korunuyor;"
ciastek

105

SourceTree kullanıcıları

Deponuzu görselleştirmek için SourceTree kullanıyorsanız (ücretsiz ve oldukça iyi) bir dosyayı sağ tıklatıp Seçilen Günlük Kaydı'nı seçebilirsiniz.

resim açıklamasını buraya girin

Ekran (aşağıda) gitk ve listelenen diğer seçeneklerin çoğundan daha dostudur. Ne yazık ki (şu anda) bu görünümü komut satırından başlatmanın kolay bir yolu yok - SourceTree'nin CLI şu anda sadece depoları açıyor.

resim açıklamasını buraya girin


1
Özellikle, bir dosyanın yeniden adlandırılıp adlandırılmadığını veya taşınıp taşınmadığını görmenizi sağlayan "Yeniden adlandırılmış dosyaları izle" seçeneğini beğeniyorum.
Chris

ama yanılmıyorsam (lütfen bana bildirin!), bir GUI bir anda sadece iki sürümü karşılaştırabilirsiniz? Aynı anda birkaç farklı sürümü farklılaştırmak için zarif bir arayüze sahip müşteriler var mı? Yüce Metin gibi bir uzaklaştırma görünümü ile mümkün mü? Bence bu gerçekten yararlı olur.
Sam Lewallen

@SamLewallen Doğru anlarsam, üç farklı taahhüdü karşılaştırmak ister misiniz? Bu, üç yönlü birleştirme (benimki, sizinki, üssü) gibi görünüyor - genellikle bu strateji, üç keyfi taahhüdü karşılaştırmak zorunda olmayan birleştirme çatışmalarını çözmek için kullanılır. Üç yönlü birleşmeyi destekleyen birçok araç vardır stackoverflow.com/questions/10998728/… ancak hile bu araçları besliyor. Gitready.com/intermediate/2009/02/27/…
Mark Fox

Teşekkürler Mark Fox, demek istediğim bu. Bunu yapacak herhangi bir uygulama biliyor musunuz?
Sam Lewallen

1
@ MarnenLaibow-Koser O anda neden SHA'ya ihtiyacım olduğunu hatırlayamıyorum. Ahaha.
AechoLiu

63

Bir dosyanın her satırını en son hangi düzeltmenin ve yazarın değiştirdiğini göstermek için:

git blame filename

veya güçlü suçlama GUI'sini kullanmak istiyorsanız:

git gui blame filename

49

Bunları okuduktan ve biraz oynadıktan sonra diğer cevapların özeti:

Her zamanki komut satırı komutu

git log --follow --all -p dir/file.c

Ancak gitk (gui) veya tig (text-ui) yöntemini, insan tarafından okunabilir daha çok bakış açısı sağlamak için de kullanabilirsiniz.

gitk --follow --all -p dir/file.c

tig --follow --all -p dir/file.c

Debian / ubuntu altında, bu güzel araçlar için install komutu beklendiği gibi:

sudo apt-get install gitk tig

Ve şu anda kullanıyorum:

alias gdf='gitk --follow --all -p'

böylece gdf diralt dizindeki her şeyin odaklanmış bir geçmişini almak için yazabilirim dir.


2
Bence bu harika bir cevap. Belki de oy kullanamıyorsunuz çünkü değişiklikleri görmek için başka yollara (IMHO daha iyi) cevap veriyorsunuz, yani git'e ek olarak gitk ve tig.
PopcornKing

Sadece cevaba eklemek için. Yolu bulun (git alanında, depoda en fazla olanı). Ardından "git log --follow --all -p <folder_path / file_path>" komutunu kullanın. Filde / klasörün geçmiş üzerinde kaldırılmış olması, bu nedenle hala var olan maksimum yolu bulması ve geçmişini getirmeye çalışması olabilir. İşler !
parasrish

2
--alltüm dallar içindir, gerisi @ Dan'ın cevabında açıklanmıştır
cregox

1
Ah adamım, dosya adlarının ötesinde izlemek için iyi bir çözüm arayan çok uzun bir süre sonra, sonunda burada buldum. Cazibe gibi çalışır! Teşekkürler!
xZero

25

Bu takma adı .gitconfig dosyanıza ekleyin:

[alias]
    lg = log --all --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset'\n--abbrev-commit --date=relative

Ve komutu şu şekilde kullanın:

> git lg
> git lg -- filename

Çıktı gitk çıktısıyla hemen hemen aynı görünecektir. Zevk almak.


O lg kısayolunu çalıştırdıktan sonra dedim (ve alıntı yaptım) "Güzel!". Ancak, "--graph" işaretinden sonra "\ n" nin bir hata olduğunu unutmayın.
jmbeck

3
Ayrıca kullanılabilir git lg -p filename- aranan dosyanın güzel bir farkını döndürür.
Egel


18

Git kodunu kullanarak vscode kullanabilirsiniz , bu çok güçlü bir araçtır. GitLens'i yükledikten sonra GitLens sekmesine gidin, öğesini seçin FILE HISTORYve göz atabilirsiniz.

resim açıklamasını buraya girin


15

Bu amaç için git-playback yazdım

pip install git-playback
git playback [filename]

Bunun hem sonuçları komut satırında (beğen git log -p) göstermesi hem de ok tuşlarını (like gitk) kullanarak her bir işlemi atlamanızı sağlaması avantajına sahiptir .



10

Ayrıca, bir dosyanın belirli bir bölümünü değiştiren taahhütleri listeleyen bunu deneyebilirsiniz (Git 1.8.4'te uygulanmıştır).

Döndürülen sonuç, bu bölümü değiştiren taahhütlerin listesi olacaktır. Komut:

git log --pretty=short -u -L <upperLimit>,<lowerLimit>:<path_to_filename>

Burada upperLimit, dosyanın start_line_number ve bottomLimit, dosyanın bitiş_line_number değeridir.

Daha fazla bilgi için https://www.techpurohit.com/list-some-useful-git-commands


9

Eğer bir dosyanın bütün geçmişini görmek istiyorsanız dahil üzerindeki tüm diğer branşlarda kullanın:

gitk --all <filename>

7

Mükemmel Git Uzantıları ile , geçmişte dosyanın hala var olduğu bir noktaya gidersiniz (silinmişse, aksi takdirde HEAD'e gidin), File treesekmeye geçin , dosyayı sağ tıklayın ve seçin File history.

Varsayılan olarak, dosyayı yeniden adlandırmalarla izler ve Blamesekme, adı verilen bir revizyonda görmenizi sağlar.

Bu göstererek gibi bazı küçük FRİKİKLERİNDEN vardır fatal: Not a valid object nameiçinde Viewsilme revizyonu tıklandığında sekmesi, ama bununla yaşayabilirim. :-)


Bunun sadece Windows olduğunu belirtmek gerekir.
Evan Hahn

3
@EvanHahn doğru değil, mono bir üzerinden GitExtension Linux üzerinde de kullanabilirsiniz, biz ubuntu ve w / oldukça mutlu kullanıyoruz. bkz. git-extensions-documentation.readthedocs.org/en/latest/…
Shmil The Cat

7

Depo menüsü altında git GUI'sini (Windows'ta) kullanıyorsanız "Master'ın Geçmişini Görselleştir" i kullanabilirsiniz. Üst bölmedeki bir taahhüdü ve sağ alt taraftaki bir dosyayı vurgulayın; sol altta bu işlemin farkını göreceksiniz.


Bu soruya nasıl cevap veriyor?
jmbeck

3
OP, komut satırını belirtmedi ve SourceSafe'den (yani bir GUI) hareket ederken, Windows'ta Git GUI'de VSS'de yapabileceğinizle hemen hemen aynı şeyi yapabileceğinizi belirtmek alakalı görünüyordu.
cori

6

SmartGit :

  1. Değişmeyen dosyaları görüntülemek için menü etkinken: Değişmeyen dosyaları görüntüleme / gösterme
  2. Dosyayı sağ tıklayın ve 'Günlük' seçeneğini seçin veya 'Ctrl-L' tuşuna basın

4

Aradığım cevap bu iş parçacığında değildi, taahhüt için hazırladığım dosyalardaki değişiklikleri görmek. yani

git diff --cached

1
Yerel (işaretsiz) değişiklikleri dahil etmek istiyorsanız, genellikle git diff origin/masteryerel şubeniz ile ana şube (uzaktan üzerinden güncellenebilir git fetch) arasındaki tam farkları göstermeye
çalışırım

4

TortoiseGit kullanıyorsanız, dosyayı sağ tıklayıp yapabilmeniz gerekir TortoiseGit --> Show Log. Açılan pencerede şunlardan emin olun:

  • ' Show Whole Project' seçeneği işaretlenmemiştir.

  • ' All Branches' seçeneği işaretlidir.


TortoiseGit (ve Eclipse Git de) bir şekilde seçilen dosyanın düzeltmelerini özlüyor, buna güvenmeyin!
Noam Manos

@NoamManos, bu sorunla karşılaşmadım, bu yüzden ifadenizin doğru olup olmadığını doğrulayamıyorum.
user3885927

Benim hatam, sadece Eclipse'de gerçekleşir, ancak TortoiseGit'te, "tüm projeyi göster" seçeneğinin işaretini kaldırırsanız + "tüm dalları" işaretlerseniz (dosyanın başka bir dalda işlenmesi durumunda, ana ile birleştirilmeden önce görebilirsiniz) dalı). Cevabınızı güncelleyeceğim.
Noam Manos

3

git diff -U <filename> size birleşik bir fark verin.

Kırmızı ve yeşil renkte olmalıdır. Değilse, git config color.ui autoönce : çalıştırın .


2

Git eklentisi ile tutulmayı kullanıyorsanız, geçmişle mükemmel bir karşılaştırma görünümüne sahiptir. Dosyayı sağ tıklayın ve "ile karşılaştır" => "geçmiş" i seçin


Ancak bu, silinmiş bir dosyayı bulmanıza izin vermez.
avgvstvs

Bir dosyanın iki sürümünü karşılaştırmak Bir dosyanın değişiklik geçmişini görüntüleme ile farklıdır
golimar

0

Muhtemelen bu başladığında OP nerede olduğunu, belirli bir taahhütten başlayarak benim repo dosyalarda değişiklikleri gözden geçirmek için vimdiff ile git difftool kullanmama izin verecek basit bir şey arıyorum . Ben bulduğum cevaplar ile çok mutlu değildi, bu yüzden bu git inc remental rep orter (gitincrep) komut dosyası birlikte attı ve benim için yararlı oldu:

#!/usr/bin/env bash

STARTWITH="${1:-}"
shift 1

DFILES=( "$@" )

RunDiff()
{
        GIT1=$1
        GIT2=$2
        shift 2

        if [ "$(git diff $GIT1 $GIT2 "$@")" ]
        then
                git log ${GIT1}..${GIT2}
                git difftool --tool=vimdiff $GIT1 $GIT2 "$@"
        fi
}

OLDVERS=""
RUNDIFF=""

for NEWVERS in $(git log --format=format:%h  --reverse)
do
        if [ "$RUNDIFF" ]
        then
                RunDiff $OLDVERS $NEWVERS "${DFILES[@]}"
        elif [ "$OLDVERS" ]
        then
                if [ "$NEWVERS" = "${STARTWITH:=${NEWVERS}}" ]
                then
                        RUNDIFF=true
                        RunDiff $OLDVERS $NEWVERS "${DFILES[@]}"
                fi
        fi
        OLDVERS=$NEWVERS
done

Args olmadan çağrıldığında, bu repo geçmişinin başından başlar, aksi takdirde sağladığınız kısaltılmış kesin karmasıyla başlar ve bugüne devam eder - çıkmak için istediğiniz zaman ctrl-C tuşlarına basabilirsiniz. İlkinden sonraki herhangi bir argüman fark raporlarını sadece bu argümanlar arasında listelenen dosyaları içerecek şekilde sınırlayacaktır (ki bu OP'nin istediği şeydir ve küçük projeler hariç tüm öneriler). Belirli dosyalarda yapılan değişiklikleri kontrol ediyorsanız ve baştan başlamak istiyorsanız, arg1 için boş bir dize sağlamanız gerekir. Bir vim kullanıcısı değilseniz, vimdiff'i en sevdiğiniz fark aracıyla değiştirebilirsiniz.

Davranış, ilgili değişiklikler bulunduğunda kaydedilen yorumları çıkarmak ve değiştirilen her dosya için vimdiff çalıştırmaları sunmaya başlamaktır (bu git difftool davranışıdır, ancak burada çalışır).

Bu yaklaşım muhtemelen oldukça naiftir, ancak burada ve ilgili bir postta birçok çözümden bakarken, birçoğu, kendi öğrenme eğrisine sahip arayüzlere sahip, yönetici erişimine sahip olmadığım bir sisteme yeni araçlar yüklemeyi içeriyordu. Yukarıdaki senaryo, herhangi biriyle uğraşmadan istediğimi yaptı. Daha sofistike bir şeye ihtiyacım olduğunda burada birçok mükemmel öneriye bakacağım - ancak bunun OP'ye doğrudan yanıt verdiğini düşünüyorum.


0

Dosyanın geçmişini hızlı bir şekilde bulmak için çok basit bir çözüm buldum.

  1. Dosyada rastgele bir değişiklik yapın
  2. Kaynak ağacınızda taahhüt edilmemiş değişiklikler olarak gösterilecektir
  3. Dosyayı sağ tıklayın ve 'Seçilen Günlüğü' seçin.

resim açıklamasını buraya girin

Tüm taahhütlerin tarihini gösterecekti.


Bu GUI nereden geliyor?
colidyre

Sourcetree UI. Thanks
savvyBrar
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.