'git status' menunjukkan file yang diubah, tetapi 'git diff' tidak

181

Saya sudah melihat semua pertanyaan serupa. Namun, saya sudah mengecek ulang dan sesuatu yang aneh pasti terjadi.

Pada satu server (Solaris dengan Git 1.8.1) Saya mengkloning repositori Git kemudian menyalin folder .git ke file live saya yang ada. Ini bekerja dengan sempurna, saya bisa berlari

git status

kemudian

git diff [filename]

untuk memeriksa file yang berbeda.

Di server lain (Solaris dengan Git 1.7.6) saya melakukan hal yang persis sama

git diff [filename]

tidak menunjukkan apa-apa, bahkan jika isi file jelas berbeda. Saya juga telah menguji menambahkan file baru, melakukan itu, dan kemudian mengedit. Masalah yang sama, git statusmenunjukkan file yang diubah, tetapi git difftidak menunjukkan apa-apa. Jika saya mengunduh file yang diubah dan menjalankan diff secara lokal maka saya mendapatkan output diff.

Oliver P.
sumber
9
Apakah itu dalam indeks Anda? Jika demikian, Anda dapat melihat perbedaannya dengan git diff --cached.
jeremyharris
2
git diff --cachedhanya memberi saya output kosong juga.
Oliver P
git logjuga tidak memberikan output.
Oliver P
Dengan asumsi benar-benar ada bug, Anda harus dapat membuat contoh minimal. Cobalah untuk mereproduksi dan bagikan sampel.
mheinzerling
1) Mode file diubah? Cari core.fileModeopsi di sini 2) Juga, saya menghadapi masalah serupa dengan konfigurasi Console2 (saya memilikinya di bawah git) ketika Console2 benar-benar berjalan. Mungkin sedikit dari kunci file membuat git ke hal file telah berubah.
madhead

Jawaban:

63

Ada beberapa alasan mengapa git statusmungkin menunjukkan perbedaan tetapi git diffmungkin tidak.

  • Mode (bit izin) file berubah-- misalnya, dari 777 menjadi 700.

  • Gaya umpan baris diubah dari CRLF (DOS) ke LF (UNIX)

Cara termudah untuk mengetahui apa yang terjadi adalah menjalankan git format-patch HEAD^dan melihat apa yang dikatakan patch yang dihasilkan.

cmccabe
sumber
11
jika perubahan file izin berlaku: git config core.filemode false untuk mengabaikan izin file
jruzafa
Bagaimana Anda mengetahui bahwa perubahan feed line dari CRLF ke LF adalah salah satu situasi di mana status git akan menunjukkan perbedaan dan git diff tidak akan?
Alex Spurling
Memiliki rekan kerja yang menggunakan Windows akan membantu Anda mengetahui semua hal menyenangkan tentang akhir baris. Saya pikir mungkin kasus di mana "git diff" menunjukkan perubahan dari CRLF ke LF, meskipun - mungkin tergantung pada konfigurasi Anda. Saya belum pernah bekerja dengan Windows, jadi saya tidak tahu seperti apa defaultnya sekarang.
cmccabe
59

Bagi saya, itu ada hubungannya dengan izin file. Seseorang dengan Mac / Linux di proyek saya tampaknya melakukan beberapa file dengan izin non-standar yang gagal mereproduksi klien Windows git saya. Solusi bagi saya adalah memberi tahu git untuk mengabaikan izin file:

git config core.fileMode false

Wawasan lain: Bagaimana cara saya membuat Git mengabaikan file mode (chmod) berubah?

Alex Abdugafarov
sumber
Ini memecahkan masalah yang saya alami dengan banyak file, meskipun saya pikir itu dengan file yang dibuat / diubah waktu.
Derek
Ini menyelesaikannya untuk saya. Nilai fileMode tampaknya default ke true pada volume Mac / Linux dan false pada volume Windows. Saya memindahkan proyek dari Mac ke Windows dan harus diubah ke false.
geekinit
1
Ini juga membantu jika Anda menjalankan VSCode menggunakan wadah Docker yang me-mount direktori Anda pada Windows 10. Di luar wadah, memeriksa status git, dengan benar menunjukkan bahwa Anda belum mengubah file. Tetapi jika Anda memeriksa status git di dalam wadah, itu menunjukkan file berubah. Menjalankan perintah di atas di dalam wadah memperbaiki masalah saya.
Frederick Ollinger
39

Saya memiliki masalah ketika ratusan ujung baris dimodifikasi oleh beberapa program dan git diffmencantumkan semua file sumber sebagai diubah. Setelah memperbaiki akhir baris, git statusmasih terdaftar file yang diubah.

Saya bisa memperbaiki masalah ini dengan menambahkan semua file ke indeks dan kemudian mengatur ulang indeks.

git add -A
git reset

core.filemode disetel ke false.

Jaakko
sumber
Terima kasih! Bekerja seperti pesona!
Starwave
1
Saya diselesaikan dengan git add --renormalize ., lihat jawaban saya di bawah ini.
Stefano M
17

Saya menduga ada sesuatu yang salah dengan instalasi Git Anda atau repositori Anda.

Coba jalankan:

GIT_TRACE=2 git <command>

Lihat apakah Anda mendapatkan sesuatu yang bermanfaat. Jika itu tidak membantu, cukup gunakan strace dan lihat apa yang salah:

strace git <command>
pengguna1338062
sumber
6
@towi: Karena ini sangat berharga bagi Anda, saya akan tertarik melihat apa yang telah Anda pelajari tentang alasan kegagalan serupa Anda.
cfi
5
Dalam kasus saya, saya menambahkan -Fbendera ke LESSvariabel env yang memberitahu kurang untuk keluar jika ada kurang dari satu layar penuh dengan informasi untuk ditampilkan. Karena git menggunakan lebih sedikit sebagai pager, dan saya memiliki sedikit perbedaan, tidak ada yang ditampilkan. Entah saya harus menambahkan -Xke LESSenv yang menunjukkan konten di layar bahkan setelah keluar lebih sedikit atau hanya menghapus -F. GIT_TRACEmenunjukkan bahwa lesssedang dieksekusi yang mengingatkan saya bahwa saya mengubah LESSvariabel baru-baru ini. Alasan yang sama dalam jawaban @ rcwxok, tetapi ingin mengomentari betapa GIT_TRACEmembantu.
Raghu Dodda
Jawaban ini memberikan saya petunjuk dari "pager" dan mengarah saya untuk solusi dari pengaturan core.pagerdi .gitconfig, yang bekerja dengan sempurna untuk saya.
ytu
10

Saya memiliki masalah yang sama: git diffakan menunjukkan perbedaan, tetapi git diff <filename>tidak. Ternyata saya mengatur LESSke string termasuk -F( --quit-if-one-screen). Menghapus bendera itu memecahkan masalah.

rcwxok
sumber
1
Alih-alih menghapus -F, menambahkan -Xmungkin juga berfungsi, lihat jawaban saya di bawah untuk kasus serupa.
avivr
Terima kasih untuk ini! Membuatku gila.
retas
9

Seperti yang sudah disebutkan dalam jawaban sebelumnya , situasi ini mungkin timbul karena masalah akhir baris (CR / LF vs LF). Saya memecahkan masalah ini (di bawah Git versi 2.22.0) dengan perintah ini:

git add --renormalize .

Menurut manual:

       --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.
Stefano M
sumber
Itu jawaban terbaik baru.
PHPst
5

Jawaban singkat

Berlari git addterkadang membantu.

Contoh

Status git menunjukkan file yang diubah dan git diff tidak menunjukkan apa-apa ...

> 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
> 

... menjalankan git add menyelesaikan ketidakkonsistenan.

> git add
> git status
On branch master
nothing to commit, working directory clean
> 
Shaun Luttin
sumber
2
Bagi
@ einjohn Menurut Anda apa penyakit dalam kasus ini?
Shaun Luttin
1
Penyakitnya bisa beberapa hal. Seperti yang disebutkan oleh orang lain, itu bisa menjadi masalah izin atau sesuatu dengan akhiran baris. Bisa juga sudah dipentaskan ubahan. Namun, kemungkinan terakhir ini tidak sesuai dengan contoh Anda. Namun demikian, dengan solusi Anda, Anda tidak akan tahu alasan (penyakit), Anda hanya menghilangkan masalah (dari perbedaan kosong yang tampaknya (gejala)). Untuk lebih jelas: Saya tidak mengatakan bahwa itu adalah solusi yang buruk. Mungkin membantu seseorang, jika dia hanya ingin masalah itu hilang. ... mudah-mudahan saya telah menjelaskan tentang penyakit saya. :)
einjohn
@ Einjohn Tampaknya menjadi akhiran garis sebagian besar waktu. Tampaknya statusdan diffmemiliki cara terpisah untuk menangani itu.
Shaun Luttin
5

Saya mengalami masalah ini. Kasus saya adalah mirip dengan yang LESSmasalah diposting oleh rcwxok .

Dalam kasus saya, saya mengatur PAGERvariabel lingkungan ke PAGER='less -RSF'.

Namun, tidak seperti jawaban sebelumnya, saya tidak ingin menghapus -Fopsi, karena saya secara eksplisit meletakkannya di sana berharap untuk mencegah menampilkan diff lessjika itu lebih pendek daripada screenful.

Untuk mendapatkan hasil yang diinginkan, bukan menghapusnya -F, saya menambahkan -X: PAGER='less -RSFX'. Ini keduanya memecahkan git diffmasalah dan juga mencegah menampilkan perbedaan pendek less.

avivr
sumber
Kapitalisasi tampaknya aneh. Apakah maksud Anda "kurang -RSFX" daripada "KURANG -RSFX"? Apakah opsi case yang benar?
StackzOfZtuff
1
Ya, terima kasih, itu kesalahan. Tidak yakin bagaimana itu terjadi. Sekarang sudah diperbaiki.
avivr
3

Saya baru saja menjalankan masalah serupa. git diff filetidak menunjukkan apa-apa karena saya menambahkan file ke indeks Git dengan beberapa bagian namanya dalam huruf besar:GeoJSONContainer.js .

Setelah itu, saya menamainya menjadi GeoJsonContainer.jsdan perubahan berhenti dilacak. git diff GeoJsonContainer.jstidak menunjukkan apa-apa. Saya harus menghapus file dari indeks dengan flag kekuatan, dan menambahkan file lagi:

git rm -f GeoJSONContainer.js
git add GeoJSONContainer.js
Alexandr Lazarev
sumber
2

Anda tidak benar-benar mengajukan pertanyaan yang sebenarnya, tetapi karena ini adalah kasus penggunaan umum, saya cukup sering menggunakan inilah yang saya lakukan. Anda dapat mencoba ini sendiri dan melihat apakah kesalahan berlanjut.

Asumsi saya tentang kasus penggunaan Anda:

Anda memiliki direktori yang sudah ada yang berisi file dan direktori dan sekarang ingin mengubahnya menjadi repositori Git yang dikloning dari tempat lain tanpa mengubah data apa pun di direktori Anda saat ini.

Sebenarnya ada dua cara.

Clone repo - mv .git- git reset --hard

Metode ini adalah apa yang Anda lakukan - untuk mengkloning repositori yang ada ke direktori kosong, lalu memindahkan .gitdirektori ke direktori tujuan. Untuk bekerja tanpa masalah, ini biasanya mengharuskan Anda untuk menjalankannya

git reset --hard

Namun, itu akan mengubah status file di direktori Anda saat ini. Anda dapat mencoba ini pada salinan lengkap / rsync dari direktori Anda dan pelajari perubahannya. Setidaknya setelah itu Anda tidak akan lagi melihat perbedaan antara git logdan status.

Dapatkan repositori baru - arahkan ke asal

Yang kedua kurang mengganggu: cdke tujuan Anda, dan mulai repositori baru dengan

git init

Kemudian Anda memberi tahu repositori baru itu, bahwa ia memiliki leluhur di tempat lain:

git remote add origin original_git_repo_path

Maka aman

git fetch origin master

untuk menyalin data tanpa mengubah file lokal Anda. Semuanya harus baik-baik saja sekarang.

Saya selalu merekomendasikan cara kedua agar tidak terlalu rentan kesalahan.

cfi
sumber
Anda tampaknya menyiratkan bahwa ini adalah kesalahan git . Ok, bisa jadi. Saya masih beranggapan saya kurang memahami git, karena saya tidak sepintar Linus ;-)
towi
@towi: Tidak, saya tidak menyiratkan bahwa ini adalah kesalahan git, saya juga tidak menyiratkan sebaliknya. Saya tidak akrab dengan internal git. Tapi sebagai aturan umum, dengan memindahkan .gitfolder ke area kerja lain, kita berpotensi melanggar asumsi git. Jika ini mengakibatkan perilaku tidak menentu yang tidak bisa kita menyalahkan git, kita harus menyalahkan diri sendiri karena bermain trik dengan git. git menyediakan cara untuk memperbaikinya, mis reset --hard. Hanya saja bukan itu yang kita inginkan. Inilah alasan mengapa init/remote addcara ini direkomendasikan, dan semuanya baik-baik saja.
cfi
@towi dan Oliver P: Sementara saya mengerti Anda ingin kasus kesalahan khusus Anda diselesaikan, kadang-kadang hanya disarankan untuk pergi dengan rekomendasi umum - terutama jika mereka cocok dengan use case Anda dengan sempurna. Juga tidak ada kehilangan data. Dan remote addcara melakukan sesuatu masih dapat diterapkan pada situasi yang kacau seperti yang dijelaskan oleh Oliver P
cfi
1
Downvote tanpa komentar tidak membantu meningkatkan jawaban ini, maupun situs secara keseluruhan. Siapa pun yang mundur, silakan tinggalkan komentar agar masalah ini dapat diatasi.
cfi
1

Saya menemukan masalah ini lagi. Tetapi kali ini terjadi karena alasan yang berbeda. Saya telah menyalin file ke repo untuk menimpa versi sebelumnya. Sekarang saya dapat melihat file-file tersebut dimodifikasi tetapi diff tidak mengembalikan diff.

Sebagai contoh, saya memiliki file mainpage.xaml. Di File Explorer saya menempelkan file mainpage.xaml baru di atas yang ada di repo saya saat ini. Saya melakukan pekerjaan di komputer lain dan hanya menempelkan file di sini.
git show dimodifikasi

File menunjukkan dimodifikasi, tetapi ketika saya menjalankan git diff, itu tidak akan menampilkan perubahan. Itu mungkin karena fileinfo pada file telah berubah dan git tahu bahwa itu sebenarnya bukan file yang sama. Menarik.

git diff tidak menunjukkan apa-apa

Anda dapat melihat bahwa ketika saya menjalankan diff pada file itu tidak menunjukkan apa-apa, hanya mengembalikan prompt.

raddevus
sumber
1

Saya memiliki masalah yang sama dijelaskan dengan cara berikut: Jika saya mengetik

$ git diff

Git hanya kembali ke prompt tanpa kesalahan.

Jika saya mengetik

$ git diff <filename>

Git hanya kembali ke prompt tanpa kesalahan.

Akhirnya, dengan membaca sekitar saya perhatikan bahwa git diffsebenarnya memanggil mingw64\bin\diff.exeuntuk melakukan pekerjaan.

Ini kesepakatannya. Saya menjalankan Windows dan telah menginstal utilitas Bash lain dan itu mengubah jalur saya sehingga tidak lagi menunjuk ke direktori mingw64 \ bin saya .

Jadi, jika Anda mengetik:

git diff

dan itu hanya kembali ke prompt Anda mungkin memiliki masalah ini.

Diff.exe aktual yang dijalankan oleh gitterletak di direktori mingw64 \ bin Anda

Akhirnya, untuk memperbaikinya, saya benar-benar menyalin mingw64\bindirektori saya ke lokasi yang dicari Git. Saya mencobanya dan masih tidak berhasil.

Kemudian, saya menutup jendela Git Bash saya dan membukanya lagi pergi ke repositori yang sama yang gagal dan sekarang berfungsi.

raddevus
sumber