ฉันจะแสดงการเปลี่ยนแปลงที่จัดเตรียมไว้ได้อย่างไร


2138

ฉันแสดงการเปลี่ยนแปลงเล็กน้อยเพื่อมุ่งมั่น; ฉันจะดูความแตกต่างของไฟล์ทั้งหมดที่จัดเตรียมไว้สำหรับการส่งครั้งต่อไปได้อย่างไร? ฉันรู้สถานะ gitแต่ฉันต้องการเห็นความแตกต่างที่เกิดขึ้นจริง - ไม่ใช่แค่ชื่อของไฟล์ที่ถูกจัดฉาก

ฉันเห็นว่าหน้าคนgit-diff (1)พูดว่า

git diff [--options] [-] […]

แบบฟอร์มนี้คือการดูการเปลี่ยนแปลงที่คุณทำกับดัชนี (พื้นที่การจัดเตรียมสำหรับการส่งครั้งต่อไป) กล่าวอีกนัยหนึ่งความแตกต่างคือสิ่งที่คุณสามารถบอกคอมไพล์เพื่อเพิ่มในดัชนี แต่คุณยังไม่ได้ คุณสามารถจัดลำดับการเปลี่ยนแปลงเหล่านี้ได้โดยใช้ git-add (1)

น่าเสียดายที่ฉันไม่เข้าใจเรื่องนี้ ต้องมีสายการบินเดียวที่มีประโยชน์ซึ่งฉันสามารถสร้างชื่อแทนได้ใช่ไหม


76
git status -vทำงานเกินไป ดูคำตอบของฉันด้านล่าง
VonC

3
@VonC ฉันมักจะใช้สิ่งนี้ แต่ส่งไปlessที่ในขณะที่: git status -v | less- ชิ้นที่จัดการได้ :)
นายสำนักงาน

คำตอบ:


2611

มันควรจะเป็น:

git diff --cached

--cachedวิธีการแสดงการเปลี่ยนแปลงในแคช / ดัชนี (เช่นฉากการเปลี่ยนแปลง) HEADกับปัจจุบัน เป็นคำพ้องสำหรับ--staged--cached

--stagedและ--cachedไม่ได้ชี้ไปเพียงแค่ความแตกต่างด้วยความเคารพHEAD HEADหากคุณเชอร์รี่เลือกสิ่งที่จะกระทำการใช้git add --patch(หรือgit add -p) --stagedจะกลับสิ่งที่จัดฉาก


35
หากคุณต้องการชื่อไฟล์เท่านั้นให้ทำตามgit diff --name-only --cachedโพสต์ต่อไปนี้ที่stackoverflow.com/a/4525025/255187
Michel Hébert

4
การใช้งานนี้มีgit difftool --stagedมากกว่าgit diff --stagedที่จะเปิดตัวเครื่องมือ diff ภาพเริ่มต้นในแต่ละไฟล์ difftoolสามารถทดแทนdiffด้วยอาร์กิวเมนต์อื่น ๆ เช่นกัน
LightCC

และคุณสามารถใช้git difftool --staged -dเพื่อแยกไดเรกทอรีทั้งสองในเครื่องมือแสดงผลได้มากกว่าหนึ่งแฟ้มในแต่ละครั้ง
Robert Bernstein

ตั้งแต่อันนี้ถูกทำเครื่องหมายเป็นคำตอบและแสดงก่อนควรรวมคอมไพล์ที่ด้านบนแล้ว git [[อื่น ๆ ]] เพียง 2 เซ็นต์ของฉัน
Vitaliy Terziev

และหากต้องการดูการเปลี่ยนแปลงในไฟล์ฉากหนึ่งไฟล์ต่อไปนี้จะใช้งานได้:git diff --cached -- <stagedfile>
Ob ชัดเจนChild

1604

กราฟิกอย่างง่ายทำให้ชัดเจนยิ่งขึ้น:

Git ง่ายแตกต่าง

คอมไพล์

แสดงการเปลี่ยนแปลงระหว่างไดเรกทอรีทำงานและดัชนี สิ่งนี้แสดงให้เห็นถึงสิ่งที่มีการเปลี่ยนแปลง แต่ไม่ได้มีการจัดเตรียมไว้สำหรับการคอมมิชชัน

คอมไพล์ diff - แคช

แสดงการเปลี่ยนแปลงระหว่างดัชนีและส่วนหัว (ซึ่งเป็นการกระทำครั้งสุดท้ายในสาขานี้) สิ่งนี้แสดงสิ่งที่ถูกเพิ่มไปยังดัชนีและฉากสำหรับการคอมมิท

git diff HEAD

แสดงการเปลี่ยนแปลงทั้งหมดระหว่างไดเรกทอรีการทำงานและส่วนหัว (ซึ่งรวมถึงการเปลี่ยนแปลงในดัชนี) สิ่งนี้แสดงให้เห็นถึงการเปลี่ยนแปลงทั้งหมดตั้งแต่การกระทำครั้งล่าสุดไม่ว่าพวกเขาจะถูกจัดฉากเพื่อส่งหรือไม่ก็ตาม

ยัง :

มีรายละเอียดเพิ่มเติมเล็กน้อยใน365Git


8
นี่เป็นเรื่องไร้เดียงสาฉันกลัว (ตามปกติแล้วเป็นกรณีที่มีคำอธิบาย git) หากคุณมีการปรับเปลี่ยนในท้องถิ่นให้foo.cและไม่ได้ดำเนินการgit add foo.cแล้วfoo.cคือไม่ได้อยู่ในดัชนี ; มันไม่ได้เป็นฉากสำหรับการกระทำ ถ้าgit diff foo.cอย่างไร้เดียงสาเมื่อเทียบกับการทำงานfoo.cเพื่อจัดทำดัชนีแล้วมันจะต้องแสดงให้เห็นถึงความแตกต่างระหว่างยักษ์ใหญ่ที่ว่างเปล่า / foo.cไฟล์ที่ไม่มีอยู่และเนื้อหาทั้งหมดของ ดังนั้นในความเป็นจริงเมื่อไฟล์ไม่มีอยู่ในดัชนีให้git diffย้อนกลับสำหรับไฟล์นั้นเมื่อใช้การHEADคัดลอก
Kaz

9
@Kaz พูดอย่างเคร่งครัดดัชนีไม่ได้เป็นกระดานชนวนที่ว่างเปล่า เป็นสำเนาเสมือนจริงของการHEADเปลี่ยนแปลงที่ใช้ฉาก โปรดจำไว้ว่า Git ทำงานได้โดยการบันทึกการเปลี่ยนแปลงไม่ใช่โดยการบันทึกไฟล์ทั้งหมด เมื่อคุณสเตจไฟล์มันจะเก็บเฉพาะการเปลี่ยนแปลงที่ทำ หากดัชนีว่างเปล่าเหมือนคุณบ่งบอกถึงมันจะไม่รู้วิธีบันทึกการเปลี่ยนแปลงในดัชนีและจะต้องบันทึกไฟล์ทั้งหมดเป็น "เพิ่งเพิ่ม" - ซึ่งผิด
ADTC

8
@Kaz ทั้งดัชนีและHEADจะมีเวอร์ชันที่ไม่เปลี่ยนแปลงของfoo.cไฟล์ (ไม่ใช่สำเนาทางกายภาพ แต่เป็นเพียงสำเนาเชิงตรรกะให้คุณและฉันเท่านั้นสำหรับ Git พวกเขาเป็นเพียงสตรีมข้อมูลเดียวกันที่ทุกการกระทำที่เกี่ยวข้องกับไฟล์นั้นหมายถึง ) ดังนั้นเมื่อคุณทำgit diffบนอย่างเต็มที่ unstaged foo.cมันไม่ได้จริงๆลดลงกลับไปHEADก็ทำจริงต่างกับดัชนี (ซึ่งเกิดขึ้นที่จะมีรุ่นเดียวกันแน่นอนของไฟล์ที่HEADไม่) ดังนั้นกราฟิกที่ถูกต้อง
ADTC

2
สวัสดีฉันอยากรู้ว่า " ดัชนี " ในบริบทนี้หมายความว่าอย่างไร ขอบคุณ!
Gab 是好人

2
@TomRussell git status -vเทียบเท่ากับgit diff --cached(บวกgit statusแน่นอน)
wisbucky

54

หากคุณต้องการมีความสนใจในมุมมองด้านข้างภาพการกระจายเครื่องมือ diff ภาพสามารถทำเช่นนั้น มันจะแสดงบานหน้าต่างสามบานหากมีการเปลี่ยนแปลงบางส่วน แต่ไม่ใช่ทั้งหมด ในกรณีที่มีข้อขัดแย้งจะมีบานหน้าต่างสี่บาน

ภาพหน้าจอของการกระจายด้วยการแก้ไขแบบฉากและแบบไม่มีการแก้ไข

เรียกใช้ด้วย

diffuse -m

ในสำเนาการทำงาน Git ของคุณ

หากคุณถามฉันภาพที่ดีที่สุดต่างไปจากที่ฉันเคยเห็นมาสิบปี นอกจากนี้ยังไม่เฉพาะกับ Git: มันทำงานร่วมกับ VCS อื่น ๆ มากมายรวมถึง SVN, Mercurial, Bazaar, ...

ดูเพิ่มเติม: แสดงทั้งฉากและต้นไม้ใน git diff?


1
ขอบคุณดูเหมือนว่าเป็นเครื่องมือที่ดี ฉันพบว่า Meld เป็นเครื่องมือ diff diff ที่ดีที่สุดสำหรับ Linux จนถึงตอนนี้ แต่ฉันพลาดที่จะสามารถกระจายข้อความจากคลิปบอร์ด - Meld ต้องการไฟล์สำหรับการป้อนข้อมูล การกระจายช่วยให้สิ่งนี้เช่นเดียวกับการจัดตำแหน่งด้วยตนเอง จะลองดูสักพัก
Drew Noakes

ลิงก์เสียไปที่ diffuse.sourceforge.net ใช้sourceforge.net/projects/diffuseก่อน
user1133275

1
brew install diffuseใช้งานได้กับ OS X ไม่แสดง 3 บานหน้าต่างหากการเปลี่ยนแปลงทั้งแบบไม่มีฉากและฉาก - คุณหมายถึงการเปลี่ยนแปลงที่ยังอยู่ในดัชนีหรือไม่
Brent Faust

คุณมีเวอร์ชั่นของการกระจายแบบไหน? ใช่ - หากคุณเพิ่มไฟล์และแก้ไขไฟล์ในเครื่องควรแสดงสามบานหน้าต่าง
krlmlr

คุณยังสามารถตั้งค่าการกระจายเป็นค่าเริ่มต้นของคุณdifftoolและการใช้งานที่สร้างขึ้นในกลไก / เครื่องมือ / นามแฝงเพื่อเปิดมัน ดูคำตอบของฉันที่นี่: < stackoverflow.com/a/45684512/6501141 >
LightCC

50

โปรดทราบว่าgit status -v ยังแสดงการเปลี่ยนแปลงในฉาก! (หมายถึงคุณจะต้องมีการจัดฉาก - git add-. การเปลี่ยนแปลงบางอย่างไม่มีฉากการเปลี่ยนแปลงต่างไม่มีgit status -v.
มันไม่ว่าตั้งแต่Git 1.2.0 กุมภาพันธ์ 2006 )

ในรูปแบบยาว (ค่าเริ่มต้น) git statusมีตัวเลือก "verbose" ที่ไม่มีเอกสารซึ่งจะแสดงความแตกต่างระหว่าง HEAD และดัชนี

และกำลังจะเสร็จสมบูรณ์ยิ่งขึ้น: ดู " แสดงทั้งฉากและต้นไม้ใน git diff? " (git 2.3.4+, Q2 2015):

git status -v -v

บรรทัดสุดท้ายควรเป็นgit diff HEAD
artur

2
@artur ทำไม ประเด็นของคำตอบคือพูดgit status -vvถึงสิ่งgit diff HEADนั้นด้วย
VonC

git version 1.8.3.1ไม่ทำงานบน ฉันรู้ว่ามันเก่า แต่ถ้าเป็นไปได้โปรดทราบว่าเมื่อใดที่มีการแนะนำการตั้งค่าสถานะนี้
onebree

2
@onebree 1.8.3.1 คือเดือนมิถุนายนปี 2013 เก่าแน่นอน แต่git status -vเก่ากว่า ( github.com/git/git/commit/… , git 1.2.0, February 2006!) โปรดทราบว่ามันจะแสดงความแตกต่างระหว่างดัชนีและHEAD: ถ้าคุณเพิ่มอะไรลงในดัชนี (ไม่git add) จากนั้นgit status -vจะไม่แสดงผลต่างใด ๆ git status -v -vเป็นล่าสุด (Git 2.3.4, มีนาคม 2015)
VonC

@VonC ว่าเป็นความผิดพลาดของฉัน ... git diff -vฉันไม่ได้
onebree

25

คุณสามารถใช้คำสั่งนี้

git diff --cached --name-only

--cachedตัวเลือกของgit diffวิธีการที่จะได้รับไฟล์ฉากและ--name-onlyตัวเลือกวิธีการที่จะได้รับเพียงชื่อของไฟล์


2
โปรดแก้ไขด้วยข้อมูลเพิ่มเติม รหัสเท่านั้นและคำตอบ "ลองนี้" จะหมดกำลังใจเพราะพวกเขาไม่มีเนื้อหาที่ค้นหาได้และไม่อธิบายว่าทำไมคนควร "ลองนี้"
abarisone

2
ไม่แน่ใจว่าทำไมฉันถึงต้องการสิ่งนี้ด้วย--name-onlyตัวเลือกที่ฉันอาจใช้เป็นประจำgit status
Simon Forsberg


15

การใช้เครื่องมือ DIFF ที่เป็นภาพ

คำตอบเริ่มต้น (ที่บรรทัดคำสั่ง)

คำตอบยอดนิยมที่นี่อย่างถูกต้องแสดงวิธีการดูการเปลี่ยนแปลงที่แคช / ฉากในIndex:

$ git diff --cached

หรือ$ git diff --stagedซึ่งเป็นนามแฝง


การเรียกใช้ Visual Diff Tool แทน

คำตอบเริ่มต้นจะคายการเปลี่ยนแปลง diff ที่ git bash (เช่นในบรรทัดคำสั่งหรือในคอนโซล) สำหรับผู้ที่ต้องการแสดงภาพความแตกต่างของไฟล์ฉากมีสคริปต์ที่มีอยู่ภายใน git ซึ่งเปิดตัวเครื่องมือ diff diff สำหรับแต่ละไฟล์ดูมากกว่าที่จะแสดงพวกเขาในบรรทัดคำสั่งที่เรียกว่าdifftool:

$ git difftool --staged

สิ่งนี้จะทำเช่นเดียวกันกับgit diff --stagedยกเว้นทุกครั้งที่มีการเรียกใช้เครื่องมือ diff (เช่นทุกครั้งที่ไฟล์ถูกประมวลผลโดย diff) มันจะเรียกใช้เครื่องมือ diff ที่เป็นภาพเริ่มต้น (ในสภาพแวดล้อมของฉันนี่คือkdiff3 )

หลังจากเครื่องมือเริ่มทำงานสคริปต์ diff git จะหยุดชั่วคราวจนกว่าเครื่องมือ diff ภาพของคุณจะปิด ดังนั้นคุณจะต้องปิดแต่ละไฟล์เพื่อดูไฟล์ถัดไป


คุณสามารถใช้difftoolแทนdiffคำสั่งในคอมไพล์ได้

สำหรับความต้องการในการมองเห็นทั้งหมดของคุณgit difftoolจะทำงานแทนgit diffคำสั่งใด ๆรวมถึงตัวเลือกทั้งหมด

ตัวอย่างเช่นหากต้องการให้มีการเปิดใช้เครื่องมือ visual diff โดยไม่ต้องถามว่าจะทำสำหรับแต่ละไฟล์หรือไม่ให้เพิ่ม-yตัวเลือก (ฉันคิดว่าโดยปกติคุณจะต้องการสิ่งนี้ !!):

$ git difftool -y --staged

ในกรณีนี้มันจะดึงแต่ละไฟล์ในเครื่องมือ visual diff ทีละไฟล์และจะเพิ่มขึ้นหนึ่งไฟล์ต่อไปหลังจากที่เครื่องมือถูกปิด

หรือดูความแตกต่างของไฟล์เฉพาะที่ถูกจัดฉากในIndex:

$ git difftool -y --staged <<relative path/filename>>

สำหรับตัวเลือกทั้งหมดให้ดูหน้า man:

$ git difftool --help


การตั้งค่าเครื่องมือ Visual Git

หากต้องการใช้เครื่องมือ git แบบเห็นภาพอื่นที่ไม่ใช่ค่าเริ่มต้นให้ใช้-t <tool>ตัวเลือก:

$ git difftool -t <tool> <<other args>>

หรือดูหน้า man difftool สำหรับวิธีการกำหนดค่า git ให้ใช้เครื่องมือ diff diff ที่เป็นค่าเริ่มต้นอื่น


ตัวอย่าง.gitconfigรายการสำหรับ vscode เป็นเครื่องมือ diff / merge

ส่วนหนึ่งของการตั้งค่า difftool เกี่ยวข้องกับการเปลี่ยน.gitconfigไฟล์ไม่ว่าจะผ่านคำสั่ง git ที่เปลี่ยนไฟล์เบื้องหลังหรือแก้ไขโดยตรง

คุณสามารถค้นหา.gitconfigในโฮมไดเร็กตอรี่ของคุณ, เช่น~ใน Unix หรือc:\users\<username>บน Windows)

หรือคุณสามารถเปิดการใช้.gitconfigในการเริ่มต้นแก้ไข Git git config -e --globalของคุณด้วย

นี่คือรายการตัวอย่างในผู้ใช้ทั่วโลกของฉัน.gitconfigสำหรับรหัส VS เป็นทั้งเครื่องมือ diff และเครื่องมือผสาน:

[diff]
    tool = vscode
    guitool = vscode
[merge]
    tool = vscode
    guitool = vscode
[mergetool]
    prompt = true
[difftool "vscode"]
    cmd = code --wait --diff \"$LOCAL\" \"$REMOTE\"
    path = c:/apps/vscode/code.exe
[mergetool "vscode"]
    cmd = code --wait \"$MERGED\"
    path = c:/apps/vscode/code.exe

14

สำหรับการเปรียบเทียบ Staging Area vs Repository (การคอมมิตล่าสุด) ใช้การเปรียบเทียบ

 $git diff --staged

คำสั่งจะเปรียบเทียบ$ git add fileNameการเปลี่ยนแปลงstaged ( ) ของคุณกับการกระทำครั้งล่าสุด หากคุณต้องการที่จะเห็นสิ่งที่คุณจัดฉากที่จะไปสู่ความมุ่งมั่นต่อไปของคุณคุณสามารถใช้คอมไพล์ diff - เวที คำสั่งนี้จะเปรียบเทียบการเปลี่ยนแปลงที่มีการจัดฉากของคุณกับการกระทำครั้งล่าสุด

สำหรับ Working vs Staging ใช้การเปรียบเทียบ

$ git diff 

คำสั่งจะเปรียบเทียบสิ่งที่อยู่ในไดเรกทอรีทำงานของคุณกับสิ่งที่อยู่ในพื้นที่จัดเตรียม เป็นสิ่งสำคัญที่จะต้องทราบว่าคอมไพล์เองไม่แสดงการเปลี่ยนแปลงทั้งหมดที่เกิดขึ้นตั้งแต่การกระทำครั้งล่าสุดของคุณ - เฉพาะการเปลี่ยนแปลงที่ยังไม่มีการเปลี่ยนแปลง หากคุณแสดงการเปลี่ยนแปลงทั้งหมดของคุณ ( $ git add fileName) git diff จะไม่แสดงผลให้คุณ

นอกจากนี้หากคุณจัดวางไฟล์ ( $ git add fileName) แล้วแก้ไขคุณสามารถใช้ git diff เพื่อดูการเปลี่ยนแปลงในไฟล์ที่จัดเตรียมไว้และการเปลี่ยนแปลงที่ไม่จัดทำ


"สำหรับการทำงานเทียบกับการใช้พื้นที่เก็บข้อมูลเปรียบเทียบ$ git diff " ฉันค่อนข้างแน่ใจว่าgit diffเปรียบเทียบระหว่าง Working vs Staging ดูstackoverflow.com/a/1587952
wisbucky

8

หากความตั้งใจของคุณคือการกำหนดเป้าหมายสาขา repo ระยะไกลและผ่านครั้งแรกของคุณที่บันทึกการเปลี่ยนแปลงกระทำไม่สมบูรณ์คุณสามารถแก้ไขคำสั่งกระทำก่อนที่จะผลักดันเช่นนี้

ในท้องถิ่น

... ทำการเปลี่ยนแปลงบางอย่าง ...

git diff # look at unstaged changes

git commit -am"partial description of changes"

... จำการเปลี่ยนแปลงเพิ่มเติมที่กล่าวถึงโดยไม่ได้ตั้งใจ ...

git diff origin / master # ดูที่ staged แต่ไม่ผลักการเปลี่ยนแปลง

... แก้ไขคำสั่งคอมมิชชัน staged ...

git commit --amend -m"i missed mentioning these changes ...."

git push

7

หากคุณมีไฟล์มากกว่าหนึ่งไฟล์ที่มีการเปลี่ยนแปลงตามขั้นตอนอาจใช้งานได้จริงgit add -iกว่านั้นให้เลือก6: diffและสุดท้ายเลือกไฟล์ที่คุณสนใจ


6

โดยค่าเริ่มต้นgit diffใช้เพื่อแสดงการเปลี่ยนแปลงที่ไม่ได้ถูกเพิ่มลงในรายการไฟล์ที่อัพเดต git แต่ถ้าคุณต้องการแสดงการเปลี่ยนแปลงที่เพิ่มหรือถูกทำให้ยุ่งเหยิงคุณจะต้องให้ตัวเลือกเพิ่มเติมที่จะทำให้ git รู้ว่าคุณสนใจไฟล์ที่ถูก stagged หรือเพิ่มต่างกัน

$ git diff          # Default Use
$ git diff --cached # Can be used to show difference after adding the files 
$ git diff --staged # Same as 'git diff --cached' mostly used with latest version of git 

ตัวอย่าง

$ git diff 
diff --git a/x/y/z.js  b/x/y/z.js index 98fc22b..0359d84 100644
--- a/x/y/z.js 
+++ b/x/y/z.js @@ -43,7 +43,7 @@ var a = function (tooltip) {

-        if (a)
+        if (typeof a !== 'undefined')
             res = 1;
         else
             res = 2;

$ git add x/y/z.js
$ git diff
$

เมื่อคุณเพิ่มไฟล์คุณจะไม่สามารถใช้ค่าเริ่มต้นของ 'git diff' ได้คุณต้องทำดังนี้: -

$ git diff --cached
diff --git a/x/y/z.js  b/x/y/z.js index 98fc22b..0359d84 100644
    --- a/x/y/z.js 
    +++ b/x/y/z.js @@ -43,7 +43,7 @@ var a = function (tooltip) {

    -        if (a)
    +        if (typeof a !== 'undefined')
                 res = 1;
             else
                 res = 2;

2

git guiและgit-colaเป็นยูทิลิตี้กราฟิกที่ให้คุณดูและจัดการดัชนี ทั้งสองอย่างรวมถึงการแสดงภาพที่เรียบง่ายสำหรับไฟล์ที่มีการจัดฉากและgit-colaยังสามารถเปิดใช้เครื่องมือ diff ที่มองเห็นได้ทีละด้าน

ดูคำตอบที่เกี่ยวข้องอย่างใกล้ชิดของฉันที่วิธีการลบไฟล์ออกจากดัชนีในคอมไพล์? และยังแคตตาล็อกนี้อย่างเป็นทางการของGit - GUI ลูกค้า


0

คิดเกี่ยวกับgitkเครื่องมือด้วย git และมีประโยชน์มากในการดูการเปลี่ยนแปลง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.