มีคำสั่ง Git ด่วนเพื่อดูไฟล์เวอร์ชันเก่าหรือไม่?


1509

มีคำสั่งใน Git เพื่อดู (ไม่ว่าจะถูกดัมพ์ไปยัง stdout หรือใน$PAGERหรือ$EDITOR) ไฟล์เฉพาะรุ่นใดรุ่นหนึ่ง?



หากคุณมาที่คำถามนี้เพราะคุณต้องการตรวจสอบไฟล์ไบนารีรุ่นเก่ากว่า (เช่นรูปภาพ) จากนั้นให้ทำการชำระเงินกับคอมมิชชันเก่าดูสิ่งที่คุณต้องการดูแล้วกลับมาที่ HEAD git checkout <sha1-of-the-commit-you-need>หลังจากนั้นทำอย่างนั้นgit checkout HEAD
Homero Esmeraldo

คำตอบ:


1730

คุณสามารถใช้git showกับพา ธ จากรูทของที่เก็บ ( ./หรือ../สำหรับการจัดเส้นทางสัมพันธ์):

$ git show REVISION:path/to/file

แทนที่REVISIONด้วยการแก้ไขที่แท้จริงของคุณ (อาจเป็น Git การกระทำ SHA, ชื่อแท็ก, ชื่อสาขา, ชื่อการส่งญาติหรือวิธีอื่น ๆ ในการระบุการกระทำใน Git)

ตัวอย่างเช่นหากต้องการดูเวอร์ชันของไฟล์<repository-root>/src/main.cตั้งแต่ 4 คอมมิชชันให้ใช้:

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

Git สำหรับ Windows ต้องการเครื่องหมายสแลชแม้ในเส้นทางที่สัมพันธ์กับไดเรกทอรีปัจจุบัน git-showสำหรับข้อมูลเพิ่มเติมโปรดดูที่หน้าคนสำหรับ


5
ดูเหมือนจะไม่ได้ผลจริง - คุณลองไหม สำหรับ "git show HEAD: path / to / file.c" ฉันได้รับข้อผิดพลาด "อาร์กิวเมนต์ที่ไม่ชัดเจน"
ไมค์

2
จะต้องเป็นเส้นทางที่สมบูรณ์จากส่วนบนสุดของ git repo
richq

20
หากคุณใช้ Windows อาจเป็นตัวแยกพา ธ ถ้าฉันแสดงคอมไพล์ HEAD: dir \ subdir \ file ฉันจะได้รับอาร์กิวเมนต์ที่ไม่ต่อเนื่อง ถ้าฉัน git แสดง HEAD: dir / subdir / file มันทำงานได้ตามที่คาดไว้
Matt McMinn

12
เส้นทางที่คุณต้องระบุหลังจาก: มาจากรูทของที่เก็บ git (นี้ได้รับด้านล่างเป็นคำตอบ แต่ฉันคิดว่ามันตั้งใจจะให้เป็นความคิดเห็นในคำตอบนี้)
MatrixFrog

9
หากคุณต้องการดูในการแบ่งเป็นกลุ่มเพื่อให้พวกเขาเลื่อนกันฉันเขียนโพสต์บล็อกสั้น ๆ ที่แสดงวิธีการทำ
Flaviu

257

ทำสิ่งนี้ตามวันที่มีลักษณะเช่นนี้:

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

โปรดทราบว่าHEAD@{2013-02-25}หมายถึง "ตำแหน่งที่ HEAD อยู่ใน 2013-02-25" ในที่เก็บนี้ (ใช้reflog ) ไม่ใช่ "การคอมมิทครั้งสุดท้ายก่อน 2013-02-25 ในสาขานี้ในประวัติศาสตร์"


5
น่ากลัว ประหยัดเวลาของฉันแทนการไปที่ GitHub และดูความมุ่งมั่น
Fizer Khan

"จุด" บนเส้นทางของไฟล์เป็นปัญหาของฉัน ขอบคุณ!
tomascharad

5
คำสั่งนี้มีประโยชน์masterแทนHEAD@{2013-02-25}ถ้าคุณอยู่ในสาขา
funroll

1
คุณสามารถรวมเวลาàลาgit log --since='2016-04-28 23:59:59 +0100'?
dumbledad

7
ความจริงรูปแบบนี้ใช้ reflog เป็นสิ่งที่สำคัญและควรจะเน้นอย่างมากเพราะreflog ไม่ได้มีกระทำทั้งหมด ดูblog.endpoint.com/2014/05/git-checkout-at-specific-date.html
Alice Heaton

113

ถ้าคุณชอบ GUI คุณสามารถใช้ gitk:

  1. เริ่มต้น gitk ด้วย:

    gitk /path/to/file
    
  2. เลือกการแก้ไขในส่วนด้านบนของหน้าจอเช่นตามคำอธิบายหรือวันที่ ตามค่าเริ่มต้นส่วนล่างของหน้าจอจะแสดง diff สำหรับการแก้ไขนั้น (ตรงกับปุ่มตัวเลือก "แพทช์")

  3. หากต้องการดูไฟล์สำหรับการแก้ไขที่เลือก:

    • คลิกที่ปุ่มตัวเลือก "ต้นไม้" นี่จะแสดงรูทของทรีไฟล์ที่การแก้ไขนั้น
    • เจาะลึกไฟล์ของคุณ

7
นอกจากนี้ยังใช้งานได้กับtigซึ่งเป็นคำชม git repo
Matthew G

1
@Paul Slocum: อาจเป็นเพราะคำสั่งนี้ไม่ใช่คำสั่งทั่วไปไม่ใช่ในตัวของคอมไพล์ ฉันคิดว่าคำสั่งนี้ใช้ได้กับ Windows เท่านั้น
Envil

โปรดทราบว่านี่ใช้งานได้เฉพาะถ้าคุณเริ่มต้นจากรูทของที่เก็บ git ของคุณ
Marc

หากคุณต้องการที่จะตรวจสอบกับการแก้ไขบางอย่างกับ gitk gitk REVISION /path/to/fileคุณยังสามารถใช้ทางลัดนี้: สิ่งนี้มีประโยชน์เมื่อคุณต้องการตรวจสอบกับบางเวอร์ชันเช่น
Christian.D

89

นอกจากนี้คุณยังสามารถระบุcommit hash(มักเรียกว่ายังcommit ID) กับคำสั่งgit show


โดยสังเขป

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


เป็นขั้นเป็นตอน

  1. แสดงบันทึกของการเปลี่ยนแปลงทั้งหมดสำหรับไฟล์ที่กำหนดด้วย git log /path/to/file
  2. ในรายการการเปลี่ยนแปลงที่แสดงจะแสดงcommit hashเช่นcommit 06c98...(06c98 ... เป็นแฮชการกระทำ)
  3. คัดลอก commit hash
  4. เรียกใช้คำสั่งgit show <commitHash>:/path/to/fileโดยใช้commit hashขั้นตอนที่ 3 และpath/to/fileขั้นตอนที่ 1

หมายเหตุ:การเพิ่มเมื่อระบุเส้นทางสัมพันธ์ดูเหมือนว่าสิ่งที่สำคัญคือ./git show b2f8be577166577c59b55e11cfff1404baf63a84:./flight-simulation/src/main/components/nav-horiz.html


1
ในกรณีที่คุณไม่รู้จักพา ธ ไปยังไฟล์ให้ใช้git show <SHA1> --name-onlyเพื่อรับมัน
Tiina

คำสั่งนี้ op - แม้กระทั่ง auto จะเสร็จสมบูรณ์จากหน่วยความจำ - ทดสอบในไดเรกทอรีที่ถูกลบ ... ไม่สามารถรับ op มากกว่า gg ได้
treyBake

43

นอกจากคำตอบของJim Hunzikerแล้ว

คุณสามารถส่งออกไฟล์จากการแก้ไขเป็น

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

หวังว่าจะช่วย :)


23

วิธีดูความแตกต่างอย่างรวดเร็วด้วยการแก้ไขไฟล์แบบเก่า:

git show -1 filename.txt > เพื่อเปรียบเทียบกับการแก้ไขครั้งล่าสุดของไฟล์

git show -2 filename.txt > เพื่อเปรียบเทียบกับการแก้ไขล่าสุดครั้งที่ 2

git show -3 fielname.txt > เพื่อเปรียบเทียบกับการแก้ไขล่าสุดครั้งที่ 3


18
คำสั่งเหล่านั้นแสดงความแตกต่างกับเวอร์ชั่นปัจจุบันสำหรับฉัน แต่ไม่แสดงไฟล์ทั้งหมด
Jean Paul

18

git log -pจะแสดงให้คุณเห็นไม่ใช่แค่บันทึกการกระทำ แต่ยังแสดงความแตกต่างของการส่งข้อมูลแต่ละข้อ (ยกเว้นการกระทำที่ผสาน) จากนั้นคุณสามารถกดใส่ชื่อไฟล์และกด/ enterกดnหรือpเพื่อไปยังเหตุการณ์ถัดไป / ก่อนหน้า วิธีนี้คุณจะไม่เพียง แต่เห็นการเปลี่ยนแปลงในไฟล์ แต่ยังรวมถึงข้อมูลการส่งมอบด้วย


3
ดูเหมือนว่าgit log -pmจะแสดงการรวมการกระทำ
sanbor

2
นอกจากนี้คุณยังสามารถเรียกใช้git log -p -- filename.txtเพื่อยับยั้งประวัติเฉพาะไฟล์ที่ต้องการ
Jean Paul

3

คุณสามารถใช้สคริปต์เช่นนี้เพื่อดัมพ์ไฟล์ทุกเวอร์ชันเพื่อแยกไฟล์:

เช่น

git_dump_all_versions_of_a_file.sh path/to/somefile.txt

รับสคริปต์ที่นี่เป็นคำตอบของคำถามที่คล้ายกันอีกข้อ


1
git_root, git_log_shortและgit_log_message_for_commitจะหายไป
mogsie

จับดี! ฉันโพสต์คำตอบนี้สองครั้งเพื่อจุดที่แตกต่างกัน 2 และเพิ่งลบหนึ่งนี้และเชื่อมโยงไปยังอีกที่ที่ผู้คนบอกฉันเกี่ยวกับเรื่องนี้มาก่อน ... ขอบคุณ @mogsie!
Brad Parks

สคริปต์นี้มีประโยชน์มาก!
XMAN

3

วิธีที่ 1: (ฉันชอบวิธีนี้)

  1. ค้นหากระทำรหัสด้วย:git reflog
  2. รายการไฟล์จากการกระทำ git diff-tree --no-commit-id --name-only -r <commitHash>

ตัวอย่าง: git diff-tree --no-commit-id --name-only -r d2f9ba4// "d2f9ba4" กำลังส่ง id จาก "1. "

  1. เปิดไฟล์ที่ต้องการด้วยคำสั่ง:

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

ตัวอย่าง: git show d2f9ba4:Src/Ext/MoreSwiftUI/ListCustom.swift// "Src / ... " คือพา ธ ไฟล์จาก "2. "

วิธีที่ 2:

  1. ค้นหากระทำรหัสด้วย:git reflog
  2. ทำการรีเซ็ตฮาร์ดเพื่อคอมมิชชันนี้: git reset --hard %commit ID%

รีเซ็ต git - ฮาร์ด c14809fa

  1. ทำการเปลี่ยนแปลงใด ๆ ที่ไม่จำเป็นและทำใหม่มุ่งมั่นในสาขาที่จำเป็น :)

0

ผู้ช่วยในการดึงไฟล์หลายไฟล์จากการแก้ไขที่กำหนด

เมื่อพยายามแก้ไขข้อขัดแย้งในการผสานผู้ช่วยนี้มีประโยชน์มาก:

#!/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 ต้นน้ำ

การใช้งาน:

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

ผลลัพธ์: ข้อมูลต่อไปนี้มีไฟล์ทางเลือกอื่น:

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

ด้วยวิธีนี้คุณจะรักษานามสกุลไฟล์ไว้เพื่อให้ตัวแก้ไขของคุณไม่บ่นและสามารถค้นหาไฟล์เก่าที่อยู่ถัดจากที่ใหม่กว่าได้อย่างง่ายดาย


@MickeyPerlstein หากคุณสามารถทำให้การใช้งานอินเทอร์เฟซเดียวกันกับการใช้งานที่ดีขึ้นฉันคือหูของทุกคน
Ciro Santilli 冠状病毒审查六四事件法轮功

บางทีฉันอาจไม่เข้าใจ (และถ้าเป็นเช่นนั้นคำขอโทษของฉัน) แต่ไม่ใช่เพียง: "git show version: ./ path> new_path"?
มิกกี้ Perlstein

@MickeyPerlstein สวัสดีใช่คำสั่งของฉันสร้าง CLI นั้น แต่มันวนซ้ำหลายไฟล์และสร้างชื่อเอาต์พุตจากอินพุตดังนั้นคุณไม่ต้องพิมพ์มากเกินไป แน่นอนว่าไม่มีการปฏิวัติ แต่สะดวกสบาย
Ciro Santilli 法轮功病毒审查六四事件法轮功
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.