'git status' mostra i file modificati, ma 'git diff' no


181

Ho dato un'occhiata a tutte le domande simili. Tuttavia, ho ricontrollato e sicuramente sta succedendo qualcosa di strano.

Su un server (Solaris con Git 1.8.1) ho clonato il repository Git, quindi ho copiato la cartella .git nei miei file live esistenti. Funzionava perfettamente, potevo correre

git status

poi

git diff [filename]

per controllare tutti i file che erano diversi.

Su un altro server (Solaris con Git 1.7.6) sto facendo esattamente lo stesso

git diff [filename]

non mostra nulla, anche se il contenuto del file è decisamente diverso. Ho anche testato l'aggiunta di un nuovo file, il commit e la modifica. Lo stesso problema, git statusmostra il file come modificato, ma git diffnon mostra nulla. Se scarico il file modificato ed eseguo un diff localmente, ottengo un output diff.


9
È nel tuo indice? In tal caso, puoi visualizzare il diff con git diff --cached.
jeremyharris,

2
git diff --cachedmi dà anche un output vuoto.
Oliver P,

git loginoltre non fornisce alcun output.
Oliver P,

Supponendo che ci sia davvero un bug, dovresti essere in grado di creare un esempio minimo. Prova a riprodurlo e condividi il campione.
mheinzerling,

1) La modalità file è stata modificata? Cerca l' core.fileModeopzione qui 2) Inoltre, sto riscontrando un problema simile con Console2 config (ce l'ho sotto git) quando Console2 è effettivamente in esecuzione. Forse una specie di blocco di un file fa git a cosa il file è cambiato.
madhead,

Risposte:



63

Ci sono alcuni motivi per cui git statuspotrebbe mostrare una differenza ma git diffpotrebbe non esserlo.

  • La modalità (bit di autorizzazione) del file è cambiata, ad esempio da 777 a 700.

  • Lo stile di avanzamento riga è cambiato da CRLF (DOS) a LF (UNIX)

Il modo più semplice per scoprire cosa è successo è eseguire git format-patch HEAD^e vedere cosa dice la patch generata.


11
se si applicano i file di autorizzazione delle modifiche: git config core.filemode false per ignorare l'autorizzazione dei file
jruzafa

Come hai scoperto che la modifica del feed di linea da CRLF a LF è una delle situazioni in cui lo stato git mostrerà una differenza e git diff no?
Alex Spurling,

Avere colleghi che usano Windows ti aiuterà a scoprire tutti i tipi di cose divertenti sulle terminazioni di linea. Penso che potrebbero essere casi in cui "git diff" mostra il passaggio da CRLF a LF, ma probabilmente dipende dalla tua configurazione. Non lavoro con Windows da un po 'di tempo, quindi non so come siano le impostazioni predefinite ora.
cmccabe,

59

Per me, aveva qualcosa a che fare con le autorizzazioni dei file. Qualcuno con Mac / Linux sul mio progetto sembra impegnare alcuni file con autorizzazioni non predefinite che il mio client Windows Git non è riuscito a riprodurre. La soluzione per me era dire a git di ignorare i permessi dei file:

git config core.fileMode false

Altre intuizioni: come faccio a fare in modo che Git ignori le modifiche alla modalità file (chmod)?


Ciò ha risolto un problema che stavo riscontrando con un mucchio di file, anche se penso che fosse invece con il file creato / modificato al momento.
Derek,

Questo mi ha risolto. Il valore fileMode sembra impostato su true su volumi Mac / Linux e false su volumi Windows. Ho spostato un progetto da Mac a Windows e doveva essere impostato su false.
geekinit

1
Ciò ha anche aiutato se stai eseguendo VSCode utilizzando un contenitore Docker che monta la tua directory su Windows 10. All'esterno del contenitore, controllando lo stato git, viene mostrato correttamente che non hai modificato alcun file. Ma se controlli lo stato di git all'interno del contenitore, mostra che i file sono cambiati. L'esecuzione del comando sopra all'interno del contenitore ha risolto il mio problema.
Frederick Ollinger

39

Ho avuto un problema in cui centinaia di finali di riga sono stati modificati da alcuni programmi ed git diffelencato tutti i file di origine come modificati. Dopo aver corretto le terminazioni di riga, git statuselencare comunque i file come modificati.

Sono stato in grado di risolvere questo problema aggiungendo tutti i file all'indice e quindi ripristinando l'indice.

git add -A
git reset

core.filemode era impostato su false.


Grazie! Ha funzionato come un fascino!
Starwave il

1
Ho risolto con git add --renormalize ., vedi la mia risposta qui sotto.
Stefano M,

17

Sospetto che ci sia qualcosa di sbagliato nella tua installazione di Git o nel tuo repository.

Prova a correre:

GIT_TRACE=2 git <command>

Vedi se ottieni qualcosa di utile. Se ciò non aiuta, basta usare strace e vedere cosa non va:

strace git <command>

6
@towi: Dal momento che per te è valsa la pena, sarei interessato a vedere cosa hai imparato sul motivo dei tuoi simili fallimenti.
cfi,

5
Nel mio caso, ho aggiunto il -Fflag alla LESSvariabile env che dice a less di uscire se c'è meno di una schermata piena di informazioni da mostrare. Dato che git usa meno come cercapersone e ho avuto un piccolo diff, non veniva mostrato nulla. O ho dovuto aggiungere -Xalla LESSENV che mostra il contenuto sullo schermo anche dopo meno uscite o semplicemente rimuovere -F. GIT_TRACEha mostrato che lessera in esecuzione che mi ha ricordato che ho cambiato la LESSvariabile di recente. Lo stesso motivo nella risposta di @ rcwxok, ma volevo un commento su come GIT_TRACEaiutato.
Raghu Dodda,

Questa risposta mi fornisce accenno di "pager" e mi porta alla soluzione di impostazione core.pagerin .gitconfig, che funziona perfettamente per me.
Sì,

10

Ho avuto un problema simile: git diffavrebbe mostrato differenze, ma git diff <filename>non lo sarebbe. Si è scoperto che ho impostato LESSuna stringa tra cui -F( --quit-if-one-screen). La rimozione di quella bandiera ha risolto il problema.


1
Invece di rimuovere -F, l'aggiunta -Xpotrebbe anche funzionare, vedi la mia risposta di seguito per un caso simile.
avivr

Grazie per questo! Mi stava facendo impazzire.
hackel,

9

Come già notato in una risposta precedente , questa situazione può sorgere a causa di problemi di fine linea (CR / LF vs. LF). Ho risolto questo problema (con Git versione 2.22.0) con questo comando:

git add --renormalize .

Secondo il manuale:

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

È la nuova migliore risposta.
PHPst

5

Risposta breve

Correre a git addvolte aiuta.

Esempio

Lo stato di Git mostra file modificati e git diff non mostra nulla ...

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

... eseguendo git add risolve l'incoerenza.

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

2
Mi sembra "combattere i sintomi" invece di "curare la malattia" ...;)
einjohn,

@einjohn Cosa pensi sia la malattia in questo caso?
Shaun Luttin,

1
La malattia potrebbe essere diverse cose. Come menzionato da altri, potrebbe trattarsi di un problema di autorizzazioni o di qualcosa con i finali di linea. Potrebbe anche essere già in scena cambiamenti. Tuttavia, quest'ultima possibilità non corrisponde al tuo esempio. Tuttavia, con la tua soluzione non conoscerai il motivo (malattia), eliminerai semplicemente il problema (di un diff vuoto (sintomi) apparentemente difettoso). Per essere chiari: non sto dicendo che sia una cattiva soluzione. Potrebbe aiutare qualcuno, se vuole solo che il problema scompaia. ... spero di aver fatto luce sulla mia metafora della malattia. :)
einjohn,

@einjohn Sembra essere la fine della linea per la maggior parte del tempo. Sembra statuse diffhanno modi separati di gestirli.
Shaun Luttin,

5

Ho riscontrato questo problema. Il mio caso era simile al LESSproblema postato da rcwxok .

Nel mio caso, ho impostato la PAGERvariabile di ambiente su PAGER='less -RSF'.

Tuttavia, a differenza delle risposte precedenti, non volevo rimuovere l' -Fopzione, perché l'ho messa esplicitamente lì sperando di evitare di mostrare il diff in lessse è più corto di uno schermo.

Per ottenere il risultato desiderato, invece di rimuovere -F, ho aggiunto -X: PAGER='less -RSFX'. Ciò ha risolto entrambi il git diffproblema e inoltre impedisce di mostrare differenze diff less.


La capitalizzazione sembra strana. Intendi "meno -RSFX" anziché "MENO -RSFX"? Le opzioni sono il caso corretto?
StackzOfZtuff,

1
Sì, grazie, è stato un errore. Non sono sicuro di come sia successo. Ora risolto.
Avivr,

3

Ho appena riscontrato un problema simile. git diff fileha mostrato nulla perché ho aggiunto file per l'indice Git con una parte del suo nome in lettere maiuscole: GeoJSONContainer.js.

Successivamente, l'ho rinominato in GeoJsonContainer.jse le modifiche hanno smesso di essere monitorate. git diff GeoJsonContainer.jsnon stava mostrando nulla. Ho dovuto rimuovere il file dall'indice con un flag force e aggiungere nuovamente il file:

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

2

Non hai fatto una vera domanda, ma dato che questo è un caso d'uso generale che sto usando abbastanza spesso, ecco cosa faccio. Puoi provare tu stesso e vedere se l'errore persiste.

La mia ipotesi sul tuo caso d'uso:

Hai una directory esistente che contiene file e directory e ora vuoi convertirla in un repository Git che viene clonato da qualche altra parte senza modificare i dati nella directory corrente.

Ci sono davvero due modi.

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

Questo metodo è quello che hai fatto: clonare il repository esistente in una directory vuota, quindi spostare la .gitdirectory nella directory di destinazione. Per funzionare senza problemi, questo generalmente richiede di eseguire

git reset --hard

Tuttavia, ciò cambierebbe lo stato dei file nella directory corrente. Puoi provare questo su una copia completa / rsync della tua directory e studiare cosa cambia. Almeno dopo non dovresti più vedere discrepanze tra git loge status.

Init nuovo repository - punta all'origine

Il secondo è meno inquietante: cdnella tua destinazione e avvia un nuovo repository con

git init

Quindi dici a quel nuovo repository, che ha un antenato in qualche altro posto:

git remote add origin original_git_repo_path

Quindi in sicurezza

git fetch origin master

per copiare i dati senza modificare i file locali. Ora dovrebbe andare tutto bene.

Consiglio sempre il secondo modo per essere meno soggetto a errori.


Sembra implicare che si tratti di un errore git . Ok, potrebbe essere. Pensavo ancora che mi mancasse un'adeguata comprensione git, perché non sono intelligente come Linus ;-)
towi

@towi: No, non sto insinuando che questo è un errore git, né sto implicando il contrario. Non ho familiarità con gli interni git. Ma come regola generale, spostando le .gitcartelle in altre aree di lavoro, stiamo potenzialmente violando ipotesi di git. Se questo si traduce in un comportamento irregolare, non possiamo incolpare Git, dobbiamo incolpare noi stessi per giocare brutti scherzi con Git. git fornisce mezzi per risolvere questo problema, ad es reset --hard. È solo che non è quello che vogliamo. Questo è esattamente il motivo per cui la init/remote addvia è raccomandata e tutto va bene.
cfi,

@towi e Oliver P: Anche se capisco che vorresti risolvere il tuo caso particolare di errore, a volte è solo consigliato seguire le raccomandazioni generali, specialmente se si adattano perfettamente al tuo caso d'uso. Inoltre non c'è perdita di dati. E il remote addmodo di fare le cose può ancora essere applicato a una situazione incasinata come quella descritta da Oliver P
cfi,

1
Un downvote senza un commento non aiuta a migliorare questa risposta, né il sito nel suo insieme. Chiunque declassa, lascia un commento in modo che il problema possa essere risolto.
cfi,

1

Mi sono imbattuto di nuovo in questo problema. Ma questa volta è successo per un motivo diverso. Avevo copiato i file nel repository per sovrascrivere le versioni precedenti. Ora posso vedere i file modificati ma diff non restituisce i diff.

Ad esempio, ho un file mainpage.xaml. In Esplora file ho incollato un nuovo file mainpage.xaml su quello nel mio repository corrente. Ho fatto il lavoro su un'altra macchina e ho appena incollato il file qui.
git mostra modificato

Il file mostra modificato, ma quando eseguo git diff, non mostrerà le modifiche. Probabilmente è perché il fileinfo sul file è cambiato e git sa che non è proprio lo stesso file. Interessante.

git diff non mostra nulla

Puoi vedere che quando eseguo diff sul file non mostra nulla, restituisce solo il prompt.


1

Ho avuto lo stesso problema descritto nel modo seguente: Se ho digitato

$ git diff

Git è semplicemente tornato al prompt senza errori.

Se ho digitato

$ git diff <filename>

Git è semplicemente tornato al prompt senza errori.

Infine, leggendo in giro ho notato che in git diffrealtà chiama il mingw64\bin\diff.exeper fare il lavoro.

Ecco l'accordo. Sto eseguendo Windows e avevo installato un'altra utility Bash e ha cambiato il mio percorso in modo che non indicasse più la mia directory mingw64 \ bin .

Quindi se digiti:

git diff

e ritorna al prompt che potresti avere questo problema.

L'attuale diff.exe che viene eseguito gitsi trova nella directory mingw64 \ bin

Alla fine, per risolvere questo problema, ho effettivamente copiato la mia mingw64\bindirectory nella posizione in cui Git la stava cercando. L'ho provato e ancora non ha funzionato.

Quindi, ho chiuso la finestra di Git Bash e l'ho aperta di nuovo, sono andato nel mio stesso repository che non funzionava e ora funziona.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.