Taşınan / yeniden adlandırılan dosyada git diff nasıl yapılır?


128

Kullanarak bir dosyayı taşıdım git mv . Şimdi, yeni dosyada eski dosyayla (eski, artık var olmayan adla) karşılaştırmak için bir fark yapmak istiyorum.

Bunu nasıl yaparım?


4
Yakında (Git 2.9, Haziran 2016), basit bir git diff -- yourRenamedFileşey yeterli olacaktır. Aşağıdaki cevabımı
VonC

Yanıtlar:


145

Git'in farklılaşırken taşınan dosyayı otomatik olarak algılamasına izin vermek için -M kullanmanız gerekir. Sadece kullanarakgit diffKnittl'in bahsettiği gibi benim için işe yaramıyor.

Yani basitçe: git diff -Myapmalı.

Bu anahtarın dokümantasyonu:

-M[<n>], --find-renames[=<n>]
       Detect renames. If n is specified, it is a threshold on the similarity index 
       (i.e. amount of addition/deletions compared to the file’s size). For example, 
       -M90% means git should consider a delete/add pair to be a rename if more than
       90% of the file hasn’t changed.

7
Cankurtaran! Git farklarım artık çok daha iyi. 1) Bu seçeneği her zaman kullanmak güvenli midir? 2) Bu seçeneği benim için varsayılan davranış olarak ekleyebilir miyim ~/.gitconfig?
kevinarpe

5
Yeniden adlandırma algılamasının, yalnızca tarafından işlenen dosyalar koleksiyonunda hem eski hem de yeni dosyalar göründüğünde çalıştığını unutmayın git diff. git diff -MTek bir (yeniden adlandırılmış) dosyada çalıştırıldığında , yeniden adlandırma bildirilmez.
Leon

1
Bu benim için çalışmıyor ama git log --follow -- file_after_move.txtiyi çalışıyor. Taşınmadan önce de dahil olmak üzere tüm geçmişi gösterir. Herhangi bir fikir? Ben koşuyorum git version 2.11.0.windows.1.
bouvierr

1
-CKopya tespit etmek için bir seçenek kullanışlı ve benzer. -MBir dosyayı ikiye yeniden düzenlediğim bir farka bakmak için kullandım (her iki isim de orijinalle eşleşmiyor).
cp.engr

85

Knittl'in yazdıklarına ek olarak , her zaman kullanabilirsiniz:

git diff HEAD:./oldfilename newfilename

burada HEAD:./oldfilename, geçerli dizine göre son işlemede (HEAD'de) eski dosya adı anlamına gelir.

Yeterince yeni git yoksa, bunun yerine kullanmanız gerekir:

git diff HEAD:path/to/oldfilename newfilename

8
Bunun için teşekkürler. Başlık yerine belirli bir kaydetmeyi de belirtebilirsiniz, yanigit diff 39fa7c77e85c51d43ea0cf30d33aec8721812e9e:./oldfilename newfilename
Chris Bloom

8
git diff branch:old/filen.name newfilename
Net değilse

İlk form cd, dizine girerseniz --ve commit:pathçiftten önce eklemezseniz , benim için çalışır . Git burada sözdizimi konusunda çok seçici görünüyor.
dhardy

1
@dhardy <commit-ish>:<pathname>Sözdizimi bir nesne tanımlayıcıdır, bir şey Git-ish; --Git yalnızca dosya adlarını bekledikten sonra .
Jakub Narębski

18

Git 2.9 (Haziran 2016) ile -Martık eklemeniz gerekmeyecek . varsayılan olarak git diffkullanır -M.

Bkz. Commit 5404c11 , commit 9501d19 , commit a9276a6 , commit f07fc9e , commit 62df1e6 (25 Şubat 2016) by Matthieu Moy ( moy) .
(Tarafından Birleştirilmiş - Junio C Hamano gitster- içinde 5d2a30d taahhüt 2016, 03 Apr)

diff: diff.renamesvarsayılan olarak etkinleştir

Yeniden adlandırma tespiti çok kullanışlı bir özelliktir ve yeni kullanıcıların bundan yararlanmak için dokümantasyonu incelemesine gerek yoktur.

Yeniden adlandırma algılamasını etkinleştirmeye yönelik olası itirazlar, bazen başarısız olması ve bazen yavaş olmasıdır. Ancak yeniden adlandırma tespiti, " git status" ve " git merge" gibi bazı durumlarda varsayılan olarak zaten etkinleştirilmiştir , bu nedenle etkinleştirme diff.renames, durumu temelden değiştirmez. Yeniden adlandırma tespiti başarısız olduğunda, artık " git diff" ve " git status" arasında sürekli olarak başarısız oluyor .

Bu ayar sıhhi tesisat komutlarını etkilemez, bu nedenle iyi yazılmış komut dosyaları etkilenmeyecektir.

Bu özellik için yeni testler burada .


1

git diff -MBaşkalarının söylediği gibi yeniden adlandırma algılamasını etkinleştirir (ve @VonC'nin işaret ettiği gibi, varsayılan olarak git 2.9'dan etkinleştirilir). Ancak büyük bir değişiklik kümeniz varsa, hatalı yeniden adlandırma algılaması yine de kapatılabilir. Git, aşağıdaki gibi bir uyarı gösterecektir ve bu, görüntülediğiniz farkın ortasında gözden kaçması kolaydır:

warning: inexact rename detection was skipped due to too many files.
warning: you may want to set your diff.renameLimit variable to at least 450 and retry the command.

Bu durumda, yapılandırma seçeneğini git tarafından önerilen şekilde ayarlayın, örneğin

git config diff.renamelimit 450

ve diff komutunuzu yeniden çalıştırın.


0

Hangi nedenle olursa olsun HEAD:./oldfilename(veya mutlak yol) kullanmak benim için işe yaramadı, ancak işe HEAD:oldfilenameyaradı (teşekkürler cmn):

git diff HEAD:oldfilename newfilename
git diff 2a80f45:oldfilename f65f3b3:newfilename

HTH


Belki senin git anlayamayacak kadar yaşlı HEAD:./oldfilename?
Jakub Narębski

-4

basitçe git diffherhangi bir argüman olmadan çalıştırın veya git diff -- newfilename. git, doğru dosyaları / içerikleri karşılaştıracak kadar akıllıdır (yani yeniden adlandırmadan önce orijinal içerik, yeniden adlandırdıktan sonra değiştirilmiş içerik)


2
git çoğu durumda kesinlikle yeterince akıllı değil. Basitçe git mvtek bir dosya ve ardından aşamalı durumu, aksi halde aynı olan başka bir dalla karşılaştırmak -M, kullanılmadığı sürece "her şey silindi ve yeniden oluşturuldu" diff üretecektir .
Reinderien
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.