Zobacz historię zmian pliku za pomocą wersji Git


3088

Jak mogę wyświetlić historię zmian pojedynczego pliku w Git, uzupełnić szczegóły o to, co się zmieniło?

Dotarłem do:

git log -- [filename]

która pokazuje mi historię zatwierdzeń pliku, ale jak mogę uzyskać treść każdej zmiany pliku?

Usiłuję dokonać przejścia z MS SourceSafe i kiedyś było to proste right-clickshow history.


41
Powyższy link nie jest już ważny. Ten link działa dzisiaj: Git Community Book
Chris

1
Powyższy link (opublikowany przez Chrisa) jest już nieważny. Ten link działa dzisiaj: git-scm.com/book/en/v2
Cog

Odpowiedzi:


2370

Do tego użyłbym:

gitk [filename]

lub śledzić nazwy poprzednich nazw plików

gitk --follow [filename]

28
Ale wolę nawet narzędzie, które łączy powyższe z „git blame”, co pozwala mi przeglądać źródło pliku, który zmienia się w czasie ...
Egon Willighagen

26
Niestety nie jest to zgodne z historią poprzednich nazw plików.
Dan Molding

146
Szukałem także historii plików, których nazwy wcześniej zmieniłem i najpierw znalazłem ten wątek. Rozwiązaniem jest użycie „git log --follow <nazwa_pliku>”, jak zauważył tutaj Phil .
Florian Gutmann

115
Autor szukał narzędzia wiersza polecenia. Chociaż gitk jest dostarczany z GIT, nie jest to ani aplikacja wiersza poleceń, ani szczególnie dobry GUI.
mikemaccana

72
Czy szukał narzędzia wiersza poleceń? „Kliknij prawym przyciskiem myszy -> pokaż historię” na pewno nie oznacza tego.
hdgarrood

2234

Możesz użyć

git log -p filename

aby git wygenerował łatki dla każdego wpisu dziennika.

Widzieć

git help log

więcej opcji - może zrobić wiele fajnych rzeczy :) Aby uzyskać tylko różnicę dla konkretnego zatwierdzenia, możesz

git show HEAD 

lub jakakolwiek inna zmiana według identyfikatora. Albo użyj

gitk

przeglądać zmiany wizualnie.


8
git show HEAD pokazuje wszystkie pliki, czy wiesz, jak śledzić pojedynczy plik (o co prosił Richard)?
Jonas Byström

5
używasz: git show <wersja> - nazwa pliku, która wyświetli różnice dla tej wersji, jeśli taka istnieje.
Marcos Oliveira,

4
--stat jest również pomocny. Możesz używać go razem z -p.
Raffi Khatchadourian

5
To jest świetne. gitk nie zachowuje się dobrze, gdy określa ścieżki, które już nie istnieją. Użyłem git log -p - path.
Paulo Casaretto

6
Plus gitk wygląda, jakby został zbudowany przez potwora boogie. To świetna odpowiedź i najlepiej dostosować ją do pierwotnego pytania.
ghayes

1495

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

Spowoduje to wyświetlenie całej historii pliku (w tym historii bez zmian nazw i różnic dla każdej zmiany).

Innymi słowy, jeśli nazwany plik barzostał kiedyś nazwany foo, wówczas git log -p bar(bez --followopcji) pokaże historię pliku tylko do momentu, w którym jego nazwa została zmieniona - nie pokaże historii pliku, gdy był znany jako foo. Użycie git log --follow -p barspowoduje wyświetlenie całej historii pliku, w tym wszelkich zmian w pliku, gdy był znany jako foo. Ta -popcja zapewnia uwzględnienie różnic dla każdej zmiany.


18
--stat jest również pomocny. Możesz używać go razem z -p.
Raffi Khatchadourian

23
Zgadzam się, że to PRAWDZIWA odpowiedź. (1.) --followzapewnia, że ​​widzisz nazwy plików (2.) -pzapewnia, że ​​widzisz, jak plik się zmienia (3.) jest to tylko wiersz poleceń.
Trevor Boyd Smith

3
@NHDaly Zauważam, że --został dodany, ale nie wiem, dlaczego to sprawia, że ​​najlepiej? Co to robi?
Benjohn

40
@Benjohn --Opcja mówi Gitowi , że osiągnęła koniec opcji i że wszystko, co następuje, --powinno być traktowane jako argument. Na git logto tylko czyni żadnej różnicy jeśli masz ścieżkę, która rozpoczyna się w desce rozdzielczej . Powiedzmy, że chcesz poznać historię pliku o niefortunnej nazwie „- obserwuj”:git log --follow -p -- --follow
Dan Molding

10
@Benjohn: Zwykle --jest przydatny, ponieważ może również chronić przed revisionnazwami pasującymi do wprowadzonej nazwy pliku, co może być przerażające. Na przykład: Jeśli masz zarówno gałąź, jak i plik o nazwie foo, git log -p foopokaże historię dziennika git do foo, a nie historię pliku foo . Ale @DanMoulding ma rację, ponieważ ponieważ --followpolecenie przyjmuje jako argument tylko jedną nazwę pliku, jest to mniej konieczne, ponieważ nie może być revision. Właśnie się tego nauczyłem. Może wtedy miałeś rację, pomijając to; Nie jestem pewny.
NHDaly

172

Jeśli wolisz pozostać oparty na tekście, możesz użyć tig .

Szybka instalacja:

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

Użyj go, aby wyświetlić historię jednego pliku: tig [filename]
lub przeglądaj szczegółową historię repozytoriów:tig

Podobne do gitkopartego na tekście. Obsługuje kolory w terminalu!


23
Doskonałe narzędzie tekstowe, świetna odpowiedź. Wystraszyłem się, gdy zobaczyłem zależności instalacji gitk na moim bezgłowym serwerze. Głosowałbym ponownie A +++
Tom McKenzie

Możesz również przeglądać określone pliki za pomocą tig, tj.tig -- path/to/specific/file
gloriphobia

109

git whatchanged -p filenamejest również równoważne git log -p filenamew tym przypadku.

Możesz również zobaczyć, kiedy określony wiersz kodu w pliku został zmieniony za pomocą git blame filename. Spowoduje to wydrukowanie krótkiego identyfikatora zatwierdzenia, autora, znacznika czasu i pełnego wiersza kodu dla każdego wiersza w pliku. Jest to bardzo przydatne po znalezieniu błędu i chcesz wiedzieć, kiedy został wprowadzony (lub kto to był błąd).


4
+1, ale filenamenie jest opcjonalny w poleceniu git blame filename.
rockXrock

7
„Nowi użytkownicy są zachęcani do korzystania z git-log. (...) Polecenie jest przechowywane głównie ze względów historycznych;”
ciastek

104

Użytkownicy SourceTree

Jeśli korzystasz z SourceTree do wizualizacji swojego repozytorium (jest darmowe i całkiem dobre), możesz kliknąć plik prawym przyciskiem myszy i wybrać Log Selected

wprowadź opis zdjęcia tutaj

Wyświetlacz (poniżej) jest o wiele bardziej przyjazny niż gitk i większość innych wymienionych opcji. Niestety (w tej chwili) nie ma łatwego sposobu na uruchomienie tego widoku z wiersza poleceń - CLI SourceTree właśnie otwiera repozytorium.

wprowadź opis zdjęcia tutaj


1
Szczególnie podoba mi się opcja „Śledź pliki o zmienionej nazwie”, która pozwala zobaczyć, czy nazwa pliku została zmieniona lub przeniesiona.
Chris

ale jeśli się nie mylę (proszę dać mi znać!), można porównać tylko dwie wersje na raz w GUI? Czy są jacyś klienci, którzy mają elegancki interfejs do różnicowania kilku różnych wersji jednocześnie? Być może z widokiem oddalenia, jak w Sublime Text? Myślę, że byłoby to bardzo przydatne.
Sam Lewallen,

@SamLewallen Jeśli dobrze rozumiem, chcesz porównać trzy różne zmiany? Brzmi to podobnie jak łączenie trójstronne (moje, twoje, baza) - zwykle ta strategia służy do rozwiązywania konfliktów scalania, niekoniecznie porównując trzy arbitralne zatwierdzenia. Istnieje wiele narzędzi, które obsługują połączenia w trzech kierunkach stackoverflow.com/questions/10998728/…, ale sztuczka polega na wprowadzeniu tych narzędzi do konkretnych wersji gitready.com/intermediate/2009/02/27/...
Mark Fox

Dzięki Mark Fox, o to mi chodzi. Czy znasz jakieś aplikacje, które to zrobią?
Sam Lewallen,

1
@ MarnenLaibow-Koser Nie pamiętam, dlaczego potrzebuję SHA w tym czasie. Ahaha.
AechoLiu

63

Aby pokazać, która wersja i autor ostatnio zmodyfikowali każdą linię pliku:

git blame filename

lub jeśli chcesz użyć potężnego interfejsu graficznego:

git gui blame filename

49

Podsumowanie innych odpowiedzi po ich przeczytaniu i zagraniu:

Zwykłym poleceniem z wiersza poleceń byłoby

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

Ale możesz także użyć gitk (gui) lub tig (text-ui), aby uzyskać znacznie bardziej czytelne dla człowieka sposoby patrzenia na to.

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

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

W debian / ubuntu polecenie instalacji tych pięknych narzędzi jest zgodne z oczekiwaniami:

sudo apt-get install gitk tig

I obecnie używam:

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

więc mogę po prostu pisać, gdf diraby uzyskać skoncentrowaną historię wszystkiego w podkatalogu dir.


2
Myślę, że to świetna odpowiedź. Być może nie dostajesz również głosu, ponieważ odpowiadasz na inne sposoby (lepiej IMHO), aby zobaczyć zmiany, np. Za pomocą gitk i tig oprócz git.
PopcornKing

Wystarczy dodać do odpowiedzi. Znajdź ścieżkę (w git space, do którego istnieje jeszcze w repozytorium). Następnie użyj polecenia podanego powyżej „git log --follow --all -p <ścieżka_folderu / ścieżka_pliku>”. Może się zdarzyć, że folder / filde zostałby usunięty z historii, dlatego znajdź maksymalną ścieżkę, która wciąż istnieje, i spróbuj pobrać jej historię. Pracuje !
parasrish

2
--alldotyczy wszystkich gałęzi, pozostałe wyjaśniono w odpowiedzi @ Dana
cregox

1
Och, człowieku, po tak długim czasie szukania dobrego rozwiązania do śledzenia plików poza nazwami, w końcu znalazłem je tutaj. Działa jak urok! Dzięki!
xZero

25

Dodaj ten alias do .gitconfig:

[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

I użyj następującego polecenia:

> git lg
> git lg -- filename

Wyjście będzie wyglądało prawie dokładnie tak samo jak wyjście gitk. Cieszyć się.


Po uruchomieniu tego skrótu lg powiedziałem (i cytuję) „Piękne!”. Zauważ jednak, że „\ n” po „--graph” jest błędem.
jmbeck

3
Można również użyć git lg -p filename- zwraca piękną różnicę szukanego pliku.
Egel

22

Ostatnio odkryłem tigi uznałem, że jest to bardzo przydatne. Są przypadki, w których chciałbym, żeby to zrobił A lub B, ale przez większość czasu jest raczej schludnie.

W twoim przypadku tig <filename>może być to, czego szukasz.

http://jonas.nitro.dk/tig/


na centos yum zainstaluj tig
zzapper

17

Możesz używać vscode z GitLens , jest to bardzo potężne narzędzie. Po zainstalowaniu GitLens przejdź do karty GitLens, wybierz FILE HISTORYi możesz ją przeglądać.

wprowadź opis zdjęcia tutaj


15

W tym celu napisałem git-odtwarzanie

pip install git-playback
git playback [filename]

Ma to tę zaletę, że wyświetla wyniki w wierszu poleceń (jak git log -p), a jednocześnie umożliwia przejście przez każdy zatwierdzenie za pomocą klawiszy strzałek (jak gitk).



9

Jeśli chcesz zobaczyć całą historię pliku, w tym we wszystkich innych gałęziach, użyj:

gitk --all <filename>

9

Możesz także spróbować tego, który wyświetla zatwierdzenia, które zmieniły określoną część pliku (zaimplementowane w Git 1.8.4).

Zwrócony wynik to lista zatwierdzeń, które zmodyfikowały tę konkretną część. Komenda :

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

gdzie upperLimit to numer_początkowy, a lowerLimit to numer_początkowy pliku.

Więcej szczegółów na https://www.techpurohit.com/list-some-useful-git-commands


7

Dzięki doskonałym rozszerzeniom Git przejdziesz do punktu w historii, w którym plik nadal istniał (jeśli został usunięty, w przeciwnym razie po prostu przejdź do HEAD), przejdź do File treekarty, kliknij plik prawym przyciskiem myszy i wybierz File history.

Domyślnie następuje zmiana nazwy pliku, a Blamezakładka pozwala zobaczyć nazwę w danej wersji.

Ma kilka drobnych błędów, takich jak pokazywanie fatal: Not a valid object namena Viewkarcie po kliknięciu wersji usuwania, ale mogę z tym żyć. :-)


Warto zauważyć, że jest to tylko system Windows.
Evan Hahn

3
@EvanHahn nie jest dokładny, za pomocą mono można używać GitExtension również w systemie Linux, używamy go na Ubuntu i całkiem szczęśliwy w / it. patrz git-extensions-documentation.readthedocs.org/en/latest/…
Shmil The Cat

7

Jeśli używasz git GUI (w systemie Windows) w menu Repozytorium, możesz użyć „Wizualizacji historii mistrza”. Zaznacz zatwierdzenie w górnym panelu i plik w prawym dolnym rogu, a zobaczysz różnicę dla tego zatwierdzenia w lewym dolnym rogu.


Jak to odpowiada na pytanie?
jmbeck

3
Cóż, OP nie określił wiersza poleceń i przejście z SourceSafe (które jest GUI) wydaje się istotne, aby wskazać, że możesz zrobić prawie to samo, co możesz zrobić w VSS w Git GUI w systemie Windows.
cori

6

SmartGit :

  1. W menu włącz wyświetlanie niezmienionych plików: Wyświetl / pokaż niezmienione pliki
  2. Kliknij plik prawym przyciskiem myszy i wybierz „Log” lub naciśnij „Ctrl-L”

4

Odpowiedź, której szukałem, ale nie w tym wątku, to zobaczyć zmiany w plikach, które przygotowałem do zatwierdzenia. to znaczy

git diff --cached

1
Jeśli chcesz uwzględnić zmiany lokalne (niestopniowe), często uruchamiam, git diff origin/masteraby pokazać pełne różnice między oddziałem lokalnym a oddziałem głównym (które można zaktualizować zdalnie przez git fetch)
ghayes

4

Jeśli używasz TortoiseGit, powinieneś być w stanie kliknąć plik prawym przyciskiem myszy i zrobić TortoiseGit --> Show Log. W wyskakującym oknie upewnij się, że:

  • ' Show Whole Project' opcja nie jest zaznaczona.

  • ' All Branches' opcja jest zaznaczona.


TortoiseGit (i Eclipse Git) w jakiś sposób pomija poprawki wybranego pliku, nie licz na to!
Noam Manos

@NoamManos, nie napotkałem tego problemu, więc nie mogę zweryfikować, czy twoje stwierdzenie jest prawidłowe.
user3885927,

Mój błąd, dzieje się to tylko w Eclipse, ale w TortoiseGit możesz zobaczyć wszystkie wersje pliku, jeśli odznaczenie „pokaż cały projekt” + sprawdzenie „wszystkich gałęzi” (w przypadku, gdy plik został zatwierdzony w innej gałęzi, zanim został scalony z głównym Oddział). Zaktualizuję twoją odpowiedź.
Noam Manos,

3

git diff -U <filename> dać ci zunifikowaną różnicę.

Powinien być zabarwiony na czerwono i zielono. Jeśli nie, uruchom: git config color.ui autonajpierw.


2

Jeśli używasz Eclipse z wtyczką git, ma doskonały widok porównania z historią. Kliknij plik prawym przyciskiem myszy i wybierz „porównaj z” => „historia”


Nie pozwoli to jednak znaleźć usuniętego pliku.
avgvstvs

Porównanie dwóch wersji pliku różni się od przeglądania historii zmian pliku
golimar

0

Prawdopodobnie wiem, gdzie był OP, kiedy to się zaczęło, szukając czegoś prostego, co pozwoliłoby mi użyć git difftool z vimdiff do przeglądu zmian w plikach w moim repozytorium, zaczynając od określonego zatwierdzenia. Nie byłem zbyt zadowolony z odpowiedzi, które znalazłem, więc rzuciłem razem ten skrypt git incremental rep orter (gitincrep) i było to dla mnie przydatne:

#!/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

Wywoływany bez argumentów, rozpocznie się od początku historii repo, w przeciwnym razie rozpocznie się od skróconego skrótu zatwierdzenia, który podasz i przejdziesz do teraźniejszości - możesz w każdej chwili wyjść z Ctrl-C. Wszelkie argumenty po pierwszym ograniczą raporty różnic, aby zawierały tylko pliki wymienione wśród tych argumentów (myślę, że tego właśnie chciał OP i zalecałbym dla wszystkich oprócz drobnych projektów). Jeśli sprawdzasz zmiany w określonych plikach i chcesz zacząć od początku, musisz podać pusty ciąg dla arg1. Jeśli nie jesteś użytkownikiem vima, możesz go wymienić vimdiff swoim ulubionym narzędziem do porównywania .

Zachowanie polega na wyświetlaniu komentarzy zatwierdzania po znalezieniu odpowiednich zmian i rozpoczęciu oferowania uruchomień vimdiff dla każdego zmienionego pliku (to znaczy zachowanie git difftool , ale działa tutaj).

Takie podejście jest prawdopodobnie dość naiwne, ale przeglądając wiele rozwiązań tutaj i na powiązany post, wielu z nich wymagało zainstalowania nowych narzędzi w systemie, w którym nie mam dostępu administratora, z interfejsami o własnej krzywej uczenia się. Powyższy skrypt zrobił to, co chciałem, bez zajmowania się tym. Przejrzę tutaj wiele doskonałych sugestii, gdy będę potrzebować czegoś bardziej wyrafinowanego - ale myślę, że to bezpośrednio reaguje na PO.


0

Znalazłem bardzo proste rozwiązanie, aby szybko znaleźć historię pliku.

  1. Wprowadź losową zmianę w pliku
  2. Pojawią się jako niezaangażowane zmiany w Twoim źródle
  3. Kliknij plik prawym przyciskiem myszy i wybierz „Log Selected”

wprowadź opis zdjęcia tutaj

Pokazuje historię wszystkich zobowiązań.


Skąd pochodzi ten GUI?
colidyre

Interfejs Sourcetree. Dzięki
savvyBrar
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.