'สถานะ git' แสดงไฟล์ที่ถูกเปลี่ยนแปลง แต่ 'git diff' ไม่แสดง


181

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

ในเซิร์ฟเวอร์เดียว (Solaris with Git 1.8.1) ฉันโคลนที่เก็บ Git จากนั้นคัดลอกโฟลเดอร์. git ไปยังไฟล์สดที่มีอยู่ มันทำงานได้อย่างสมบูรณ์แบบฉันสามารถวิ่งได้

git status

แล้วก็

git diff [filename]

เพื่อตรวจสอบไฟล์ใด ๆ ที่แตกต่างกัน

บนเซิร์ฟเวอร์อื่น (Solaris กับ Git 1.7.6) ฉันทำแบบเดียวกันทุกประการ

git diff [filename]

ไม่แสดงอะไรเลยถึงแม้ว่าเนื้อหาของไฟล์จะแตกต่างกันอย่างแน่นอน ฉันยังได้ทดสอบการเพิ่มไฟล์ใหม่ยอมรับและแก้ไข ปัญหาเดียวกันgit statusแสดงไฟล์ว่ามีการเปลี่ยนแปลง แต่git diffไม่แสดงอะไรเลย หากฉันดาวน์โหลดไฟล์ที่เปลี่ยนแปลงและรัน diff แบบโลคัลฉันจะได้รับเอาต์พุต diff


9
อยู่ในดัชนีของคุณหรือไม่ git diff --cachedถ้าเป็นเช่นนั้นคุณสามารถดูต่างกับ
jeremyharris

2
git diff --cachedเพียงแค่ให้ฉันออกว่างเช่นกัน
Oliver P

git logยังให้ผลลัพธ์ไม่
โอลิเวอร์ P

สมมติว่ามีข้อบกพร่องจริง ๆ คุณควรจะสามารถสร้างตัวอย่างขั้นต่ำได้ พยายามทำซ้ำและแบ่งปันตัวอย่าง
mheinzerling

1) เปลี่ยนโหมดไฟล์หรือไม่ มองหาcore.fileModeตัวเลือกที่นี่ 2) นอกจากนี้ฉันกำลังเผชิญปัญหาที่คล้ายกันกับการกำหนดค่า Console2 (ฉันมีมันอยู่ภายใต้คอมไพล์) เมื่อ Console2 กำลังทำงานจริง บางทีการล็อกไฟล์อาจทำให้คอมไพล์เป็นไฟล์ที่เปลี่ยนไป
madhead

คำตอบ:


81

ฉันเพิ่มไฟล์ไปยังดัชนี :

git add file_name

แล้ววิ่ง:

git diff --cached file_name

คุณสามารถดูคำอธิบายของ diff คอมไพล์ที่นี่

หากคุณต้องการเลิกทำการเพิ่มคอมไพล์ของคุณโปรดดูที่นี่: วิธีเลิกทำการ 'คอมไพล์แบบเพิ่ม' ก่อนคอมมิท


63

มีสาเหตุบางประการที่git statusอาจแสดงความแตกต่าง แต่git diffอาจไม่ได้

  • โหมด (บิตการอนุญาต) ของไฟล์เปลี่ยนแปลง - เช่นจาก 777 ถึง 700

  • ลักษณะการป้อนบรรทัดเปลี่ยนจาก CRLF (DOS) เป็น LF (UNIX)

วิธีที่ง่ายที่สุดในการค้นหาว่าเกิดอะไรขึ้นคือการเรียกใช้git format-patch HEAD^และดูสิ่งที่ปะแก้ที่สร้าง


11
หากมีการใช้ไฟล์การเปลี่ยนแปลงการอนุญาต: git config core.filemode false เพื่อเพิกเฉยการอนุญาตไฟล์
jruzafa

คุณทราบได้อย่างไรว่าการป้อนบรรทัดเปลี่ยนจาก CRLF เป็น LF เป็นหนึ่งในสถานการณ์ที่สถานะ git จะแสดงความแตกต่างและ git diff จะไม่แตกต่างกันอย่างไร
Alex Spurling

การมีเพื่อนร่วมงานที่ใช้ Windows จะช่วยให้คุณค้นพบสิ่งที่สนุกสนานเกี่ยวกับการสิ้นสุดบรรทัด ฉันคิดว่าอาจเป็นกรณีที่ "git diff" แสดงการเปลี่ยนแปลงจาก CRLF เป็น LF แม้ว่า - อาจขึ้นอยู่กับการกำหนดค่าของคุณ ฉันไม่ได้ทำงานกับ Windows มาระยะหนึ่งแล้วดังนั้นฉันไม่ทราบว่าค่าเริ่มต้นเป็นอย่างไร
cmccabe

59

สำหรับฉันมันมีบางอย่างเกี่ยวข้องกับการอนุญาตของไฟล์ บางคนที่มี Mac / Linux ในโครงการของฉันดูเหมือนว่าจะยอมรับไฟล์บางอย่างที่มีการอนุญาตที่ไม่ใช่ค่าเริ่มต้นซึ่งไคลเอนต์ Windows git ของฉันไม่สามารถทำซ้ำได้ ทางออกสำหรับฉันคือบอก git ให้เพิกเฉยการอนุญาตไฟล์:

git config core.fileMode false

ข้อมูลเชิงลึกอื่น ๆ : ฉันจะทำให้ Git เพิกเฉยต่อโหมดไฟล์ (chmod) ได้อย่างไร?


สิ่งนี้แก้ไขปัญหาที่ฉันมีกับไฟล์จำนวนมาก แต่ฉันคิดว่ามันเป็นเพราะไฟล์ที่สร้าง / แก้ไขเวลาแทน
Derek

วิธีนี้แก้ไขได้สำหรับฉัน ค่า fileMode จะปรากฏเป็นค่าเริ่มต้นเป็นจริงบน Mac / Linux และโวลุ่มบน Windows ที่เป็นเท็จ ฉันย้ายโครงการจาก Mac ไปยัง Windows และจำเป็นต้องเปลี่ยนเป็นเท็จ
geekinit

1
สิ่งนี้จะช่วยได้หากคุณใช้ VSCode โดยใช้ Docker container ซึ่งติดตั้งไดเรกทอรีของคุณใน Windows 10 ที่ด้านนอกของคอนเทนเนอร์ให้ตรวจสอบสถานะ git แสดงให้เห็นว่าคุณไม่ได้เปลี่ยนแปลงไฟล์ใด ๆ แต่ถ้าคุณตรวจสอบสถานะ git ภายในคอนเทนเนอร์มันจะแสดงไฟล์ที่มีการเปลี่ยนแปลง การเรียกใช้คำสั่งด้านบนภายในคอนเทนเนอร์แก้ไขปัญหาของฉัน
Frederick Ollinger

39

ฉันมีปัญหาที่บางตอนจบของบรรทัดถูกแก้ไขโดยบางโปรแกรมและgit diffแสดงรายการไฟล์ต้นฉบับทั้งหมดว่ามีการเปลี่ยนแปลง หลังจากแก้ไขจุดสิ้นสุดของเส้นgit statusยังคงแสดงรายการไฟล์ตามที่ถูกแก้ไข

ฉันสามารถแก้ไขปัญหานี้ได้โดยการเพิ่มไฟล์ทั้งหมดลงในดัชนีแล้วทำการรีเซ็ตดัชนี

git add -A
git reset

core.filemode ถูกตั้งค่าเป็นเท็จ


ขอบคุณ! ทำงานเหมือนจับใจ!
Starwave

1
ฉันแก้ไขด้วยgit add --renormalize .ดูคำตอบของฉันด้านล่าง
Stefano M

17

ฉันสงสัยว่ามีบางอย่างผิดปกติในการติดตั้ง Git หรือที่เก็บข้อมูลของคุณ

ลองใช้:

GIT_TRACE=2 git <command>

ดูว่าคุณได้อะไรที่มีประโยชน์ หากวิธีนี้ไม่ได้ผลให้ใช้straceแล้วดูว่ามีอะไรผิดปกติ:

strace git <command>

6
@towi: เนื่องจากนี่เป็นสิ่งที่มีค่าสำหรับคุณฉันจะสนใจที่จะเห็นสิ่งที่คุณได้เรียนรู้เกี่ยวกับสาเหตุของความล้มเหลวที่คล้ายกันของคุณ
cfi

5
ในกรณีของฉันฉันเพิ่มการ-Fตั้งค่าสถานะลงในLESSตัวแปร env ซึ่งบอกให้ออกน้อยกว่าหากมีน้อยกว่าหนึ่งหน้าจอที่เต็มไปด้วยข้อมูลที่จะแสดง เนื่องจากคอมไพล์ใช้เพจเจอร์น้อยลงและฉันมีความแตกต่างเล็กน้อยจึงไม่มีการแสดงอะไรเลย อย่างใดอย่างหนึ่งที่ผมต้องเพิ่ม-XไปLESSenv -Fซึ่งแสดงให้เห็นเนื้อหาบนหน้าจอแม้หลังจากที่ออกน้อยหรือเพียงแค่ลบ GIT_TRACEแสดงให้เห็นว่าlessกำลังถูกประหารซึ่งเตือนฉันว่าฉันเปลี่ยนLESSตัวแปรเมื่อเร็ว ๆ นี้ เหตุผลเดียวกันในคำตอบของ @ rcwxok แต่ต้องการแสดงความคิดเห็นเกี่ยวกับวิธีการที่GIT_TRACEช่วย
Raghu Dodda

คำตอบนี้ให้ฉันคำแนะนำของ "เพจเจอร์" และนำไปสู่ผมที่จะแก้ปัญหาของการตั้งค่าcore.pagerใน.gitconfigที่ทำงานได้อย่างสมบูรณ์แบบสำหรับผม
ytu

10

ฉันมีปัญหาที่คล้ายกัน: git diffจะแสดงความแตกต่าง แต่git diff <filename>จะไม่ ปรากฎว่าฉันตั้งค่าLESSสตริงรวมถึง-F( --quit-if-one-screen) การลบการตั้งค่าสถานะนั้นแก้ไขปัญหาได้


1
แทนที่จะลบ-Fการเพิ่ม-Xอาจใช้งานได้ดูคำตอบของฉันด้านล่างสำหรับกรณีที่คล้ายกัน
avivr

ขอบคุณสำหรับสิ่งนี้! กำลังขับรถฉันบ้า
hackel

9

ดังที่ระบุไว้แล้วในคำตอบก่อนหน้านี้สถานการณ์นี้อาจเกิดขึ้นเนื่องจากปัญหาสิ้นสุดบรรทัด (CR / LF เทียบกับ LF) ฉันแก้ไขปัญหานี้ (ภายใต้ Git เวอร์ชัน 2.22.0) ด้วยคำสั่งนี้:

git add --renormalize .

ตามคู่มือ:

       --renormalize
           Apply the "clean" process freshly to all tracked files to
           forcibly add them again to the index. This is useful after
           changing core.autocrlf configuration or the text attribute in
           order to correct files added with wrong CRLF/LF line endings.
           This option implies -u.

มันเป็นคำตอบที่ดีที่สุดใหม่
PHPst

5

คำตอบสั้น ๆ

วิ่ง git addบางครั้งการก็ช่วยได้

ตัวอย่าง

สถานะ Git แสดงไฟล์ที่ถูกเปลี่ยนแปลงและ git diff ไม่แสดงอะไรเลย ...

> git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   package.json

no changes added to commit (use "git add" and/or "git commit -a")
> git diff
> 

... การเพิ่มคอมไพล์แก้ไขความไม่ลงรอยกัน

> git add
> git status
On branch master
nothing to commit, working directory clean
> 

2
ฟังดูแล้วฉันชอบ 'ต่อสู้กับอาการ' แทนที่จะเป็น 'รักษาอาการป่วย' ... ;)
einjohn

@einjohn คุณคิดว่าเป็นโรคอะไรในกรณีนี้?
Shaun Luttin

1
ความเจ็บป่วยอาจมีหลายสิ่ง ตามที่ผู้อื่นกล่าวถึงอาจเป็นปัญหาสิทธิ์หรือบางอย่างที่มีการสิ้นสุดบรรทัด นอกจากนี้ยังอาจจัดฉากการเปลี่ยนแปลงไว้แล้ว อย่างไรก็ตามความเป็นไปได้สุดท้ายนี้ไม่ตรงกับตัวอย่างของคุณ อย่างไรก็ตามด้วยวิธีการแก้ปัญหาของคุณคุณจะไม่ทราบเหตุผล (เจ็บป่วย) คุณเพียงแค่กำจัดปัญหา (จากความแตกต่างที่ว่างเปล่าดูเหมือน (อาการ)) เพื่อความชัดเจน: ฉันไม่ได้บอกว่ามันเป็นทางออกที่ไม่ดี มันอาจช่วยใครซักคนถ้าเขา / เธอแค่อยากให้ปัญหาหายไป ... หวังว่าฉันจะเข้าใจถึงอาการป่วยของฉัน :)
einjohn

@einjohn ดูเหมือนว่าจะเป็นจุดสิ้นสุดของสายเกือบตลอดเวลา ดูเหมือนstatusและdiffมีวิธีการจัดการเหล่านั้นแยกกัน
Shaun Luttin

5

ฉันพบปัญหานี้ กรณีของฉันก็คล้ายคลึงกับปัญหาโพสต์โดย rcwxokLESSrcwxok

ในกรณีของฉันฉันตั้งค่าPAGERตัวแปรสภาพแวดล้อมเป็นPAGER='less -RSF'ตัวแปรสภาพแวดล้อมในการ

อย่างไรก็ตามไม่เหมือนกับคำตอบก่อนหน้านี้ฉันไม่ต้องการลบ-Fตัวเลือกเนื่องจากฉันวางไว้อย่างชัดเจนเพื่อหวังที่จะป้องกันไม่ให้แสดง difflessกรณีที่สั้นกว่าหน้าจอ

เพื่อให้ได้ผลลัพธ์ที่ต้องการแทนที่จะลบ-Fฉันได้เพิ่ม-X: PAGER='less -RSFX'. นี้ทั้งแก้ไขgit diffปัญหาและนอกจากจะป้องกันไม่ให้แสดง diffs lessสั้น


การใช้อักษรตัวพิมพ์ใหญ่ดูเหมือนแปลก คุณหมายถึง "less -RSFX" แทนที่จะเป็น "LESS -RSFX" หรือไม่ ตัวเลือกเป็นกรณีถูกต้องหรือไม่
StackzOfZtuff

1
ใช่ขอบคุณมันเป็นความผิดพลาด ไม่แน่ใจว่ามันเกิดขึ้นได้อย่างไร แก้ไขแล้ว
avivr

3

ฉันเพิ่งทำงานในปัญหาที่คล้ายกัน git diff fileไม่พบสิ่งใดเพราะฉันได้เพิ่มไฟล์ในดัชนี Git โดยมีชื่อบางส่วนเป็นตัวพิมพ์ใหญ่:GeoJSONContainer.jsกับบางส่วนของชื่อตัวพิมพ์ใหญ่:

หลังจากนั้นฉันได้เปลี่ยนชื่อเป็นGeoJsonContainer.jsและการเปลี่ยนแปลงหยุดการติดตาม git diff GeoJsonContainer.jsไม่แสดงอะไรเลย ฉันต้องลบไฟล์ออกจากดัชนีด้วยการตั้งค่าสถานะบังคับและเพิ่มไฟล์อีกครั้ง:

git rm -f GeoJSONContainer.js
git add GeoJSONContainer.js

2

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

ข้อสมมติของฉันเกี่ยวกับกรณีการใช้ของคุณ:

คุณมีไดเรกทอรีที่มีไฟล์และไดเรกทอรีอยู่แล้วและต้องการแปลงเป็นที่เก็บ Git ที่ถูกโคลนจากที่อื่นโดยไม่ต้องเปลี่ยนข้อมูลใด ๆ ในไดเรกทอรีปัจจุบันของคุณ

มีสองวิธีจริงๆ

โคลน repo - mv .git - git reset - ฮาร์ด

วิธีนี้เป็นสิ่งที่คุณทำ - เพื่อโคลนที่เก็บข้อมูลที่มีอยู่ในไดเรกทอรีว่างแล้วย้าย.gitไดเรกทอรีไปยังไดเรกทอรีปลายทาง ในการทำงานโดยไม่มีปัญหาคุณต้องเรียกใช้โดยทั่วไป

git reset --hard

อย่างไรก็ตามนั่นจะเปลี่ยนสถานะของไฟล์ในไดเรกทอรีปัจจุบันของคุณ คุณสามารถลองทำสิ่งนี้ได้ที่สำเนา / rsync ของไดเรกทอรีและศึกษาการเปลี่ยนแปลง อย่างน้อยหลังจากนั้นคุณไม่ควรจะเห็นความแตกต่างระหว่างและgit logstatus

พื้นที่เก็บข้อมูลใหม่เริ่มต้น - ชี้ไปที่จุดเริ่มต้น

สิ่งที่สองคือการรบกวนน้อยลง: cdสู่ปลายทางของคุณและเริ่มที่เก็บข้อมูลใหม่ด้วย

git init

จากนั้นคุณบอกที่เก็บใหม่ว่ามันมีบรรพบุรุษที่อื่น:

git remote add origin original_git_repo_path

ปลอดภัยแล้ว

git fetch origin master

เพื่อคัดลอกข้อมูลโดยไม่ต้องเปลี่ยนไฟล์ในเครื่องของคุณ ตอนนี้ทุกอย่างควรจะดี

ฉันมักจะแนะนำวิธีที่สองสำหรับข้อผิดพลาดน้อยได้ง่าย


คุณดูเหมือนจะบ่งบอกว่านี่เป็นข้อผิดพลาดของคอมไพล์ ตกลงเป็นไปได้ ฉันยังคงสันนิษฐานว่าผมขาดความเข้าใจที่ถูกต้องคอมไพล์เพราะผมไม่ได้เป็นสมาร์ทไลนัส ;-)
towi

@ โตโต้: ไม่ฉันไม่ได้หมายความว่านี่เป็นข้อผิดพลาดทางคอมไพล์หรือฉันไม่ได้หมายถึงสิ่งที่ตรงกันข้าม ฉันไม่คุ้นเคยกับเรื่องภายใน git แต่ตามกฎทั่วไปแล้วการย้ายไปรอบ ๆ.gitโฟลเดอร์ไปยังพื้นที่ทำงานอื่น ๆ เราอาจละเมิดสมมติฐานของ git หากสิ่งนี้ส่งผลให้เกิดพฤติกรรมที่ผิดปกติเราไม่สามารถตำหนิคอมไพล์ได้เราต้องตำหนิตัวเองสำหรับการเล่นเล่ห์เหลี่ยมกับคอมไพล์ reset --hardคอมไพล์ให้หมายถึงการแก้ไขปัญหานั้นเช่น มันเป็นเพียงแค่นั้นไม่ใช่สิ่งที่เราต้องการ นี่คือเหตุผลinit/remote addที่แนะนำวิธีการและทั้งหมดเป็นอย่างดี
cfi

@towi และ Oliver P: ในขณะที่ฉันเข้าใจว่าคุณต้องการให้กรณีของคุณมีข้อผิดพลาดแก้ไขบางครั้งก็แนะนำให้ไปกับคำแนะนำทั่วไป - โดยเฉพาะอย่างยิ่งถ้าพวกเขาพอดีกับกรณีการใช้งานของคุณอย่างสมบูรณ์ นอกจากนี้ยังไม่มีการสูญเสียข้อมูล และremote addวิธีการทำสิ่งต่าง ๆ ยังสามารถนำไปใช้กับสถานการณ์ที่สับสนได้เช่นเดียวกับที่ Oliver P
cfi บรรยายไว้

1
Downvote ที่ไม่มีความคิดเห็นไม่ช่วยปรับปรุงคำตอบนี้หรือไซต์โดยรวม ใครก็ตามที่ลงคะแนนโปรดแสดงความคิดเห็นเพื่อให้สามารถแก้ไขปัญหาได้
cfi

1

ฉันสะดุดกับปัญหานี้อีกครั้ง แต่คราวนี้มันเกิดขึ้นด้วยเหตุผลที่แตกต่างกัน ฉันคัดลอกไฟล์ลงใน repo เพื่อเขียนทับเวอร์ชันก่อนหน้า ตอนนี้ฉันสามารถเห็นไฟล์ที่มีการแก้ไข แต่ diff ไม่กลับ diffs

ตัวอย่างเช่นฉันมีไฟล์ mainpage.xaml ใน File Explorer ฉันวางไฟล์ mainpage.xaml ใหม่ทับไฟล์ที่อยู่ใน repo ปัจจุบันของฉัน ฉันทำงานบนเครื่องอื่นและเพิ่งวางไฟล์ที่นี่
git แสดงการแก้ไข

ไฟล์แสดงการแก้ไข แต่เมื่อฉันรัน git diff มันจะไม่แสดงการเปลี่ยนแปลง อาจเป็นเพราะ fileinfo ในไฟล์มีการเปลี่ยนแปลงและ git รู้ว่ามันไม่ใช่ไฟล์เดียวกัน น่าสนใจ

คอมไพล์ diff แสดงอะไร

คุณจะเห็นว่าเมื่อฉันเรียกใช้ diff บนไฟล์มันจะไม่แสดงอะไรเลยเพียงแค่ส่งคืนพร้อมท์


1

ฉันมีปัญหาเดียวกันนี้ที่อธิบายในวิธีต่อไปนี้: ถ้าฉันพิมพ์

$ git diff

Git เพียงกลับไปที่พรอมต์โดยไม่มีข้อผิดพลาด

ถ้าฉันพิมพ์

$ git diff <filename>

Git เพียงกลับไปที่พรอมต์โดยไม่มีข้อผิดพลาด

ในที่สุดโดยการอ่านรอบ ๆ ฉันสังเกตเห็นว่าgit diffจริง ๆ แล้วเรียกmingw64\bin\diff.exeการทำงาน

นี่คือข้อตกลง ฉันใช้ Windows และติดตั้งยูทิลิตี Bash อื่นและเปลี่ยนเส้นทางของฉันดังนั้นจึงไม่ชี้ไปที่mingw64 \ binของฉันอีกต่อไปไดเรกทอรี

ดังนั้นถ้าคุณพิมพ์:

git diff

และมันเพิ่งกลับไปที่พรอมต์คุณอาจมีปัญหานี้

diff.exe จริงซึ่งดำเนินการโดยgitจะอยู่ในไดเรกทอรี mingw64 \ bin ของคุณ

ในที่สุดเพื่อแก้ไขปัญหานี้ฉันคัดลอกของฉัน mingw64\binไดเรกทอรีไปยังตำแหน่ง Git ที่กำลังค้นหาอยู่ฉันลองและยังใช้งานไม่ได้

จากนั้นฉันปิดหน้าต่างGit Bashและเปิดอีกครั้งไปยังที่เก็บข้อมูลเดียวกันที่ล้มเหลวและตอนนี้ก็ใช้งานได้

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