Apakah ada perintah Git cepat untuk melihat versi lama file?


1511

Apakah ada perintah di Git untuk melihat (baik dibuang ke stdout, atau di $PAGERatau $EDITOR) versi tertentu dari file tertentu?



Jika Anda sampai pada pertanyaan ini karena Anda ingin memeriksa versi file biner yang lebih lama (mis. Gambar), maka lebih baik lakukan checkout ke komit lama, lihat apa yang perlu Anda lihat, dan kemudian kembali ke HEAD. Untuk itu, lakukan git checkout <sha1-of-the-commit-you-need>, setelahnya,git checkout HEAD
Homero Esmeraldo

Jawaban:


1732

Anda dapat menggunakan git showlintasan dari akar repositori ( ./atau ../untuk lintasan relatif):

$ git show REVISION:path/to/file

Ganti REVISIONdengan revisi Anda yang sebenarnya (bisa berupa Git commit SHA, nama tag, nama cabang, nama komit relatif, atau cara lain untuk mengidentifikasi komit di Git)

Misalnya, untuk melihat versi file <repository-root>/src/main.cdari 4 komit yang lalu, gunakan:

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

Git untuk Windows memerlukan garis miring maju bahkan di jalur relatif ke direktori saat ini. Untuk informasi lebih lanjut, lihat halaman manual untuk git-show.


5
Tampaknya tidak berhasil - apakah Anda mencobanya? Untuk "git show HEAD: path / to / file.c", saya mendapatkan kesalahan "argumen ambigu".
mike

2
Harus menjadi jalan yang lengkap, dari atas git repo
richq

20
Jika Anda berada di windows, itu mungkin hal pemisah jalur; jika saya melakukan git show HEAD: dir \ subdir \ file, saya mendapatkan argumen anbiguous. Jika saya melakukan git show HEAD: dir / subdir / file, itu berfungsi seperti yang diharapkan.
Matt McMinn

12
Path yang harus Anda berikan setelah: adalah dari akar repositori git. (ini diberikan di bawah sebagai jawaban tapi saya pikir itu dimaksudkan sebagai komentar pada jawaban ini)
MatrixFrog

9
Jika Anda ingin melihatnya dalam split Vim sehingga mereka gulir bersama, saya menulis posting blog pendek yang menunjukkan bagaimana melakukan itu.
Flaviu

257

Melakukan ini berdasarkan tanggal terlihat seperti ini:

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

Catatan itu HEAD@{2013-02-25}berarti "di mana HEAD berada pada 2013-02-25" di repositori ini (menggunakan reflog ), bukan "komit terakhir sebelum 2013-02-25 di cabang ini dalam sejarah".


5
Luar biasa. Menghemat banyak waktu saya daripada pergi ke github dan melihat komit.
Fizer Khan

"Titik" di jalur file adalah masalah saya. Terima kasih!
tomascharad

5
Perintah ini berguna dengan mastersebagai ganti HEAD@{2013-02-25}, jika Anda berada di cabang
funroll

1
Bisakah Anda memasukkan waktu, à la git log --since='2016-04-28 23:59:59 +0100'?
Dumbledad

7
Fakta sintaks ini menggunakan reflog adalah penting dan harus disorot dengan kuat, karena reflog tidak mengandung semua commit . Lihat blog.endpoint.com/2014/05/git-checkout-at-specific-date.html
Alice Heaton

113

Jika Anda menyukai GUI, Anda dapat menggunakan gitk:

  1. mulai gitk dengan:

    gitk /path/to/file
    
  2. Pilih revisi di bagian atas layar, mis. Dengan deskripsi atau tanggal. Secara default, bagian bawah layar menunjukkan perbedaan untuk revisi itu, (sesuai dengan tombol radio "tambalan").

  3. Untuk melihat file untuk revisi yang dipilih:

    • Klik pada tombol radio "tree". Ini akan menunjukkan akar dari pohon file di revisi itu.
    • Telusuri file Anda.

7
Ini juga bekerja dengan tig , yang merupakan penampil kutukan git repo.
Matius G

1
@ Paul Slocum: Mungkin karena perintah ini bukan perintah konvensional, bukan built-in dari git. Saya pikir perintah ini hanya berfungsi untuk Windows.
Envil

Catatan ini sepertinya hanya berfungsi jika Anda memulai dari akar repositori git Anda.
Marc

Jika Anda ingin memeriksa terhadap revisi tertentu dengan gitk Anda juga bisa menggunakan shortcut ini: gitk REVISION /path/to/file. Ini bisa berguna ketika Anda ingin memeriksa versi tertentu misalnya.
Christian.D

89

Anda juga dapat menentukan commit hash(sering juga disebut commit ID) dengan git showperintah .


Pendeknya

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


Selangkah demi selangkah

  1. Perlihatkan log semua perubahan dengan file yang diberikan git log /path/to/file
  2. Dalam daftar perubahan yang ditampilkan, itu menunjukkan commit hashseperti commit 06c98...(06c98 ... menjadi hash komit)
  3. Salin commit hash
  4. Jalankan perintah git show <commitHash>:/path/to/filemenggunakan commit hashlangkah 3 & path/to/filelangkah 1.

Catatan: menambahkan ./ketika menentukan jalur relatif tampaknya penting, yaitu git show b2f8be577166577c59b55e11cfff1404baf63a84:./flight-simulation/src/main/components/nav-horiz.html.


1
jika Anda tidak tahu path ke file, gunakan git show <SHA1> --name-onlyuntuk mendapatkannya.
Tiina

op perintah ini - bahkan secara otomatis selesai dari memori - diuji pada direktori yang dihapus ... tidak bisa mendapatkan lebih banyak op dari itu gg
treyBake

43

Selain jawaban Jim Hunziker ,

Anda dapat mengekspor file dari revisi sebagai,

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

Semoga ini membantu :)


23

Untuk dengan cepat melihat perbedaan dengan revisi file yang lebih lama:

git show -1 filename.txt > untuk membandingkan dengan revisi file terakhir

git show -2 filename.txt > untuk membandingkan dengan revisi terakhir ke-2

git show -3 fielname.txt > untuk membandingkan dengan revisi terakhir 3 terakhir


18
Perintah-perintah itu menunjukkan perbedaan dengan versi saya saat ini tetapi tidak menunjukkan seluruh file.
Jean Paul

18

git log -pakan menunjukkan kepada Anda tidak hanya log komit tetapi juga diff dari setiap komit (kecuali gabungan komit). Kemudian Anda dapat menekan /, masukkan nama file dan tekan enter. Tekan natau puntuk pergi ke kejadian berikutnya / sebelumnya. Dengan cara ini Anda tidak hanya akan melihat perubahan dalam file tetapi juga informasi komit.


3
Sepertinya git log -pmjuga akan menampilkan komit gabungan.
sanbor

2
Anda juga dapat menjalankan git log -p -- filename.txtuntuk membatasi riwayat hanya file yang diinginkan.
Jean Paul

3

Anda dapat menggunakan skrip seperti ini untuk membuang semua versi file ke file yang terpisah:

misalnya

git_dump_all_versions_of_a_file.sh path/to/somefile.txt

Dapatkan skrip di sini sebagai jawaban untuk pertanyaan serupa lainnya


1
git_root, git_log_shortdan git_log_message_for_commithilang.
mogsie

Tangkapan yang bagus! Saya gandakan memposting jawaban ini ke 2 tempat yang berbeda, dan baru saja menghapus yang ini dan terhubung ke yang lain, di mana orang-orang mengatakan kepada saya tentang ini sebelumnya ... terima kasih @mogsie!
Brad Parks

Script ini sangat berguna!
XMAN

3

CARA 1: (Saya lebih suka cara ini)

  1. Temukan id komitmen dengan:git reflog
  2. Daftar file dari komit git diff-tree --no-commit-id --name-only -r <commitHash>

contoh: git diff-tree --no-commit-id --name-only -r d2f9ba4// "d2f9ba4" adalah commit dari "1."

  1. Buka file yang dibutuhkan dengan perintah:

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

contoh: git show d2f9ba4:Src/Ext/MoreSwiftUI/ListCustom.swift// "Src / ..." adalah path file dari "2."

CARA 2:

  1. Temukan id komitmen dengan:git reflog
  2. membuat hard reset ke komit ini: git reset --hard %commit ID%

git reset --hard c14809fa

  1. buat perubahan yang tidak perlu dan lakukan komitmen baru ke cabang yang dibutuhkan :)

0

Membantu mengambil beberapa file dari revisi yang diberikan

Saat mencoba menyelesaikan konflik gabungan, pembantu ini sangat berguna:

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

Pemakaian:

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

Hasil: berikut ini berisi versi alternatif dari file:

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

Dengan cara ini, Anda menyimpan ekstensi file sehingga editor Anda tidak akan mengeluh, dan dapat dengan mudah menemukan file lama tepat di sebelah yang lebih baru.


@MickeyPerlstein jika Anda dapat mencapai antarmuka yang sama dengan implementasi yang lebih baik, saya dengar.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

mungkin saya tidak mengerti (dan jika demikian, permintaan maaf saya) tetapi bukankah itu hanya: "git show version: ./ path> new_path"?
Mickey Perlstein

@MickeyPerlstein hai, ya, perintah saya menghasilkan CLI itu, tetapi loop atas beberapa file dan menghasilkan nama output dari input, jadi Anda tidak perlu mengetik terlalu banyak. Tentu saja tidak ada yang revolusioner, tetapi nyaman.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.