Czy istnieje szybkie polecenie Git, aby zobaczyć starą wersję pliku?


1509

Czy w Git jest polecenie, aby zobaczyć (zrzuconą na standardowe wyjście lub w $PAGERlub $EDITOR) określoną wersję określonego pliku?



Jeśli przyszedłeś do tego pytania, ponieważ chcesz sprawdzić starszą wersję pliku binarnego (np. Obraz), to lepiej wykonaj kasę do starego zatwierdzenia, zobacz, co musisz zobaczyć, a następnie wróć do HEAD. W tym celu wykonaj git checkout <sha1-of-the-commit-you-need>późniejgit checkout HEAD
Homero Esmeraldo

Odpowiedzi:


1730

Możesz użyć git showścieżki z katalogu głównego repozytorium ( ./lub ../względnej ścieżki ):

$ git show REVISION:path/to/file

Zastąp REVISIONaktualną wersją (może to być SHA zatwierdzenia Git, nazwa znacznika, nazwa gałęzi, względna nazwa zatwierdzenia lub inny sposób identyfikacji zatwierdzenia w Git)

Na przykład, aby wyświetlić wersję pliku <repository-root>/src/main.csprzed 4 zatwierdzeń, użyj:

$ git show HEAD~4:src/main.c

Git dla Windows wymaga ukośników nawet w ścieżkach względem bieżącego katalogu. Aby uzyskać więcej informacji, sprawdź stronę podręcznika dla git-show.


5
To tak naprawdę nie działa - próbowałeś? W przypadku „git show HEAD: path / to / file.c” pojawia się błąd „dwuznaczny argument”.
Mike

2
Musi to być pełna ścieżka od szczytu repozytorium git
richq

20
Jeśli korzystasz z systemu Windows, może to być separator ścieżki; jeśli zrobię git show HEAD: dir \ subdir \ file, otrzymam jednoznaczny argument. Jeśli zrobię git show HEAD: dir / subdir / file, działa zgodnie z oczekiwaniami.
Matt McMinn

12
Ścieżka, którą musisz podać po: jest z katalogu głównego repozytorium git. (podano to poniżej jako odpowiedź, ale myślę, że miało to być komentarzem do tej odpowiedzi)
MatrixFrog

9
Jeśli chcesz zobaczyć to w Vimie, aby przewijały się razem, napisałem krótki post na blogu pokazujący, jak to zrobić.
Flaviu,

257

Wykonanie tego według daty wygląda następująco:

git show HEAD@{2013-02-25}:./fileInCurrentDirectory.txt

Zauważ, że HEAD@{2013-02-25}oznacza to „gdzie HEAD był w dniu 25.02.2013” ​​w tym repozytorium (używając reflog ), a nie „ostatni zatwierdzenie przed 25.02.2013 w tej gałęzi w historii”.


5
Niesamowite. Oszczędza dużo czasu zamiast chodzić na github i patrzeć na zatwierdzenie.
Fizer Khan,

„Kropka” na ścieżce pliku była moim problemem. Dzięki!
tomascharad

5
To polecenie jest przydatne masterzamiast HEAD@{2013-02-25}, jeśli jesteś na gałęzi
funroll

1
Czy możesz podać czas, la git log --since='2016-04-28 23:59:59 +0100'?
dumbledad

7
Fakt, że ta składnia używa reflogu, jest ważny i powinien być mocno podkreślony, ponieważ reflog nie zawiera wszystkich zatwierdzeń . Zobacz blog.endpoint.com/2014/05/git-checkout-at-specific-date.html
Alice Heaton

113

Jeśli lubisz GUI, możesz użyć gitk:

  1. uruchom gitk za pomocą:

    gitk /path/to/file
    
  2. Wybierz wersję w górnej części ekranu, np. Według opisu lub daty. Domyślnie dolna część ekranu pokazuje różnicę dla tej wersji (odpowiadająca przyciskowi opcji „łatka”).

  3. Aby zobaczyć plik dla wybranej wersji:

    • Kliknij przycisk radiowy „drzewo”. Spowoduje to wyświetlenie katalogu głównego drzewa plików w tej wersji.
    • Przejdź do swojego pliku.

7
Działa to również z tig , który jest przeglądarką git repo przekleństw.
Matthew G

1
@Paul Slocum: Może być, ponieważ to polecenie nie jest konwencjonalnym poleceniem, a nie wbudowanym programem git. Myślę, że to polecenie działa tylko w systemie Windows.
Wysłannik

Zauważ, że działa to tylko wtedy, gdy zaczynasz od katalogu głównego repozytorium git.
Marc

Jeśli chcesz sprawdzić przed pewnej rewizji z gitk można też użyć tego skrótu: gitk REVISION /path/to/file. Może się to przydać, gdy chcesz na przykład sprawdzić pewną wersję.
Christian.D.

89

Możesz także określić commit hash(często nazywany commit ID) git showpoleceniem .


W skrócie

git show <commitHash>:/path/to/file


Krok po kroku

  1. Pokaż dziennik wszystkich zmian dla danego pliku za pomocą git log /path/to/file
  2. Na pokazanej liście zmian pokazuje commit hashtakie, jak commit 06c98...(06c98 ... będący skrótem zatwierdzenia)
  3. Skopiuj commit hash
  4. Uruchom polecenie, git show <commitHash>:/path/to/fileużywając commit hashkroku 3 i path/to/filekroku 1.

Uwaga: dodanie ./przy określaniu ścieżki względnej wydaje się ważne, tj git show b2f8be577166577c59b55e11cfff1404baf63a84:./flight-simulation/src/main/components/nav-horiz.html.


1
jeśli nie znasz ścieżki do pliku, użyj jej, git show <SHA1> --name-onlyaby ją zdobyć.
Tiina,

to polecenie op - nawet auto uzupełnia z pamięci - testowane w usuniętym katalogu ... nie można uzyskać więcej
operacji

43

Oprócz Jim Hunziker „s odpowiedź

możesz wyeksportować plik z wersji jako,

git show HEAD@{2013-02-25}:./fileInCurrentDirectory.txt > old_fileInCurrentDirectory.txt

Mam nadzieję że to pomoże :)


23

Aby szybko zobaczyć różnice w starszych wersjach pliku:

git show -1 filename.txt > aby porównać z ostatnią wersją pliku

git show -2 filename.txt > aby porównać z 2. ostatnią wersją

git show -3 fielname.txt > aby porównać z ostatnią trzecią ostatnią wersją


18
Te polecenia pokazują dla mnie różnice w obecnej wersji, ale nie pokazują całego pliku.
Jean Paul

18

git log -ppokaże ci nie tylko dzienniki zatwierdzeń, ale także różnicę każdego zatwierdzenia (z wyjątkiem zatwierdzeń scalania). Następnie możesz nacisnąć /, wprowadzić nazwę pliku i nacisnąć enter. Naciśnij nlub, paby przejść do następnego / poprzedniego wystąpienia. W ten sposób zobaczysz nie tylko zmiany w pliku, ale także informacje o zatwierdzeniu.


3
Wygląda na to, git log -pmże pokazywałby również zatwierdzenia scalania.
sanbor

2
Możesz także uruchomić, git log -p -- filename.txtaby ograniczyć historię tylko do żądanego pliku.
Jean Paul

3

Możesz użyć takiego skryptu, aby zrzucić wszystkie wersje pliku w celu oddzielenia plików:

na przykład

git_dump_all_versions_of_a_file.sh path/to/somefile.txt

Pobierz skrypt tutaj jako odpowiedź na kolejne podobne pytanie


1
git_root, git_log_shortA git_log_message_for_commitbrakuje.
mogsie

Dobry chwyt! Dwukrotnie opublikowałem tę odpowiedź w 2 różnych miejscach, po prostu usunąłem tę i powiązałem z drugą, gdzie ludzie mówili mi o tym wcześniej ... dzięki @mogsie!
Brad Parks

Ten skrypt jest bardzo przydatny!
XMAN,

3

SPOSÓB 1: (Wolę w ten sposób)

  1. Znajdź identyfikator zatwierdzenia za pomocą:git reflog
  2. Lista plików z zatwierdzenia git diff-tree --no-commit-id --name-only -r <commitHash>

przykład: git diff-tree --no-commit-id --name-only -r d2f9ba4// „d2f9ba4” to identyfikator zatwierdzenia z „1.”

  1. Otwórz potrzebny plik za pomocą polecenia:

git show <commitHash>:/path/to/file

przykład: git show d2f9ba4:Src/Ext/MoreSwiftUI/ListCustom.swift// „Src / ...” to ścieżka do pliku z „2”

SPOSÓB 2:

  1. Znajdź identyfikator zatwierdzenia za pomocą:git reflog
  2. wykonaj twardy reset tego zatwierdzenia: git reset --hard %commit ID%

git reset --hard c14809fa

  1. wprowadź niepotrzebne zmiany i dokonaj nowego zatwierdzenia w potrzebnej gałęzi :)

0

Pomocnik, aby pobrać wiele plików z danej wersji

Podczas próby rozwiązania konfliktów scalania ten pomocnik jest bardzo przydatny:

#!/usr/bin/env python3

import argparse
import os
import subprocess

parser = argparse.ArgumentParser()
parser.add_argument('revision')
parser.add_argument('files', nargs='+')
args = parser.parse_args()
toplevel = subprocess.check_output(['git', 'rev-parse', '--show-toplevel']).rstrip().decode()
for path in args.files:
    file_relative = os.path.relpath(os.path.abspath(path), toplevel)
    base, ext = os.path.splitext(path)
    new_path = base + '.old' + ext
    with open(new_path, 'w') as f:
        subprocess.call(['git', 'show', '{}:./{}'.format(args.revision, path)], stdout=f)

GitHub w górę .

Stosowanie:

git-show-save other-branch file1.c path/to/file2.cpp

Wynik: poniższe zawierają alternatywne wersje plików:

file1.old.c
path/to/file2.old.cpp

W ten sposób zachowujesz rozszerzenie pliku, aby Twój edytor nie narzekał i mógł łatwo znaleźć stary plik tuż obok nowszego.


@MickeyPerlstein, jeśli potrafisz osiągnąć ten sam interfejs dzięki lepszej implementacji, jestem cała w uszach.
Ciro Santilli 冠状 病毒 审查 六四 事件 法轮功

może nie rozumiem (a jeśli tak, przepraszam), ale czy nie jest to po prostu: „git show version: ./ path> new_path”?
Mickey Perlstein

@MickeyPerlstein cześć, tak, moje polecenie generuje interfejs CLI, ale zapętla wiele plików i generuje nazwę wyjściową na podstawie danych wejściowych, więc nie musisz pisać zbyt wiele. Oczywiście nic rewolucyjnego, ale wygodne.
Ciro Santilli 26 病毒 审查 六四 事件 法轮功
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.