Jak różnicować jeden plik do dowolnej wersji w Git?

324

Jak mogę odróżnić plik, powiedzmy pom.xml, od gałęzi master do dowolnej starszej wersji w Git?

Chris K.
źródło

Odpowiedzi:

347

Możesz to zrobić:

git diff master~20:pom.xml pom.xml

... aby porównać swój prąd pom.xmlz tym z master20 wersji temu przez pierwszego rodzica. Możesz master~20oczywiście zastąpić nazwę obiektu (SHA1sum) zatwierdzenia lub dowolnym z wielu innych sposobów określania wersji .

Zauważ, że to faktycznie porównuje starą pom.xmlz wersją w twoim drzewie roboczym, a nie wersją zatwierdzoną w master. Jeśli chcesz, możesz zamiast tego wykonać następujące czynności:

git diff master~20:pom.xml master:pom.xml
Mark Longair
źródło
12
Pamiętaj, że to nie działa tylko w przypadku plików, ale działa również na przykład w przypadku (podkatalogów) git diff <revision>:foo/ HEAD:foo/.
2
Zauważ również, że w systemie Windows musisz użyć ukośników do katalogów, jeśli używasz specyfikatora wersji lub git wyświetli błąd dotyczący pliku / katalogu nieistniejącego w tej wersji.
Dylan Nissley,
1
@DylanNissley lub nie da ci żadnego błędu ani różnicy. Właśnie to widzę. W każdym razie dziękuję za podpowiedź na temat używania ukośników do przodu zamiast odwrotnych ukośników.
Gary S.
W plikach systemu Windows łatwiej jest zmienić katalog, a następnie wywołać git diff master ~ 20: ./ pom.xml ./pom.xml
lloyd
Niektóre wersje git wymagają „-” między <revision> a <path>
Josh
140
git diff <revision> <path>

Na przykład:

git diff b0d14a4 foobar.txt
Benjamin Pollack
źródło
nie działa dla wersji 1.7.11, jeśli plik nie znajduje się w bieżącym katalogu. Przykład: „git diff f76d078 test / Config” zwraca błąd: „Nie można uzyskać dostępu do„ test / f76d078 ””
simpleuser
1
@ user1663987 prostu przekazać pełną ścieżkę względem katalogu głównego projektu: git diff <revision> root/path/file.
1
test / Config jest względny w stosunku do katalogu głównego (jak w teście jest podkatalog katalogu głównego). ale wtedy twój przykładowy katalog główny / ścieżka / plik wydaje się ZAWIERAĆ katalog główny?
simpleuser
41

Jeśli chcesz zobaczyć różnicę między ostatnim zatwierdzeniem jednego pliku, możesz:

git log -p -1 filename

To da ci różnicę pliku w git, nie porównuje pliku lokalnego.

Gerardo
źródło
2
to nic nie zwraca
Andrei Cristian Prodan
@AndreiCristianProdan Więc nie ma tam żadnych zmian. Możesz zwiększać -1krok po kroku, aż otrzymasz zmiany.
kaiser
To jest bardzo miłe. Stworzyłem funkcję bash, które mogą być użyteczne: gitlog () { git log -${3:-p} -${2:-1} $1; } Używany jak: gitlog Rakefilelub gitlog Rakefile 5i gitlog Rakefile 10 s. Pierwszy pokazuje jedną różnicę; drugi pokazuje pięć różnic; trzeci pokazuje dziesięć --no-patch.
auxbuss
18

Aby zobaczyć, co zostało zmienione w pliku w ostatnim zatwierdzeniu:

git diff HEAD~1 path/to/file.

Możesz zmienić liczbę (~ 1) na n-ty zatwierdzenie, z którym chcesz się różnić.

Juampy NR
źródło
Ta odpowiedź jest naprawdę tylko szczególnym przypadkiem tej bardziej ogólnej odpowiedzi , gdzie HEAD~1jest podstawiona <revision>, co czyni tę odpowiedź duplikatem.
1
to nie działa! fatal: dwuznaczny argument „HEAD ~ 1”: nieznana wersja lub ścieżka nie działa w drzewie roboczym. Użyj „-”, aby oddzielić ścieżki od wersji
Andrei Cristian Prodan
Ta odpowiedź jest dla mnie prosta i funkcjonalna.
Douglas Frari,
6

Ogólna składnia:

$git diff oldCommit..newCommit -- **FileName.xml > ~/diff.txt

dla wszystkich plików o nazwie „FileName.xml” w dowolnym miejscu repozytorium.

Zwróć uwagę na spację między „-” a „**”

Odpowiedz na swoje pytanie:

$git checkout master
$git diff oldCommit..HEAD -- **pom.xml 
or
$git diff oldCommit..HEAD -- relative/path/to/pom.xml 

jak zawsze w przypadku git, możesz użyć tagu / sha1 / „HEAD ^”, aby zidentyfikować zatwierdzenie.

Testowane z git 1.9.1 na Ubuntu.

brzmi jak zabity
źródło
6

Jeśli żadne zatwierdzenie nie jest GŁOWĄ, wówczas rozwinięcie nawiasów bash okaże się bardzo przydatne, szczególnie jeśli twoje nazwy plików są długie, powyższy przykład:

git diff master~20:pom.xml master:pom.xml

Stanie się

git diff {master~20,master}:pom.xml

Więcej na temat rozszerzenia Brace dzięki bash.

robstarbuck
źródło
6

Aby porównać do 5 zatwierdzeń do bieżącego, oba włączone master, po prostu wykonaj:

git diff master~5:pom.xml master:pom.xml

Możesz także odwołać się do numeru skrótu zatwierdzenia, na przykład jeśli numer skrótu to x110bd64, możesz zrobić coś takiego, aby zobaczyć różnicę:

git diff x110bd64 pom.xml
Alireza
źródło
4

git diff -w HEAD origin / master path / to / file

CatalinBerta
źródło
2
git diff master~20 -- pom.xml

Działa, jeśli nie jesteś również w gałęzi master.

Gunar Gessner
źródło
2

Jeśli nic ci nie jest, używając narzędzia graficznego (lub nawet wolisz), możesz:

gitk pom.xml

W gitk możesz następnie kliknąć dowolny zatwierdzenie (aby go „wybrać”) i kliknąć prawym przyciskiem myszy dowolny inny zatwierdzenie, aby wybrać „Zróżnicuj to -> wybrane” lub „Zróżnicuj wybrane -> to” w menu podręcznym, w zależności od preferowanej kolejności.

Martin G.
źródło
0

Jeśli chcesz na przykład różnicować pojedynczy plik w skrytce, możesz to zrobić

git diff stash@{0} -- path/to/file
lacostenycoder
źródło
-1

Jeśli szukasz pliku różnic w konkretnym zatwierdzeniu i chcesz użyć interfejsu użytkownika github zamiast wiersza poleceń (powiedz, że chcesz połączyć go z innymi osobami), możesz:

https://github.com/<org>/<repo>/commit/<commit-sha>/<path-to-file>

Na przykład:

https://github.com/grails/grails-core/commit/02942c5b4d832b856fbc04c186f1d02416895a7e/grails-test-suite-uber/build.gradle

Zwróć uwagę na łącza Poprzedni i Następny w prawym górnym rogu, które umożliwiają nawigację po wszystkich plikach w zatwierdzeniu.

Działa to jednak tylko dla konkretnego zatwierdzenia, a nie do porównywania dowolnych dwóch dowolnych wersji.

Schmick
źródło