105 votes

Git : Comment revenir sur 2 fichiers qui sont obstinément bloqués à "Changed but not committed" ?

J'ai un repo qui contient deux fichiers que j'ai soi-disant modifiés localement.

Je suis donc coincé avec ça :

$ git status
# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   dir1/foo.aspx
#       modified:   dir2/foo.aspx
#
no changes added to commit (use "git add" and/or "git commit -a")

Faire git diff indique que l'ensemble du contenu du fichier a changé, même si, à l'œil nu, cela semble faux (il semble y avoir des plages de lignes communes que diff ne semble pas voir).

Il est intéressant de noter que je ne me souviens pas avoir modifié ces fichiers localement. Ce repo est utilisé avec un repo distant (privé, sur GitHub.com, FWIW).

J'ai beau essayer, je ne parviens pas à me débarrasser de ces modifications locales. J'ai essayé tous les :

$ git checkout -- .
$ git checkout -f
$ git checkout -- dir1/checkout_receipt.aspx
$ git reset --hard HEAD
$ git stash save --keep-index && git stash drop
$ git checkout-index -a -f

En d'autres termes, j'ai essayé tout ce qui est décrit dans le document Comment supprimer les modifications non mises à jour dans Git ? et plus encore. Mais les deux fichiers restent bloqués en tant que "modifiés mais non validés".

Qu'est-ce qui peut bien faire que deux fichiers soient bloqués de la sorte et que l'on ait l'impression qu'il faut "déréviser la table" ?

P.S. Dans la liste ci-dessus des commandes que j'ai déjà essayées, j'ai écrit par erreur git revert alors que je voulais dire git checkout . Je suis désolée et je remercie ceux qui m'ont répondu que je devais essayer. checkout . J'ai édité la question pour la corriger. Il est certain que j'ai déjà essayé checkout .

4voto

Andrew West Points 31

Ce problème peut également être dû au fait que git traite les différences de capitalisation comme des fichiers différents, alors que Windows les traite comme un seul et même fichier. Si le nom d'un fichier n'a changé que sa capitalisation, tous les utilisateurs Windows de ce repo se retrouveront dans cette situation.

La solution consiste à confirmer que le contenu du fichier est correct, puis à le réengager. Nous avons dû fusionner le contenu des deux fichiers car ils étaient différents. Ensuite, tirez et il y aura un conflit de fusion que vous pouvez résoudre en supprimant le fichier en double. Recommencez la résolution de la fusion et vous êtes de retour à un état stable.

4voto

Tadeck Points 37046

Essayez de annuler les modifications locales :

git checkout -- dir1/foo.aspx
git checkout -- dir2/foo.aspx

3voto

Simon Points 4467

J'avais des fichiers modifiés fantômes qui apparaissaient comme modifiés, mais qui étaient en fait identiques.

Exécution de cette commande parfois œuvre :
(Désactive les conversions de fin de ligne "intelligentes" mais souvent inutiles de git)

git config --local core.autocrlf false

Mais dans un autre cas, j'ai découvert que cela était dû à une .gitattributes dans la racine, qui contenait des paramètres de fin de ligne et qui essayait d'appliquer des paramètres de fin de ligne à la racine. autocrlf pour certains fichiers, même lorsqu'il était désactivé. Cela ne m'a pas vraiment aidé, alors j'ai supprimé .gitattributes a été validée, et le fichier n'apparaît plus comme modifié.

2voto

Steve Prentice Points 7638
git checkout dir1/foo.aspx
git checkout dir2/foo.aspx

2voto

Marinos An Points 98

Je pense qu'il serait utile de fournir une indication sur la manière de reproduire le problème afin de mieux comprendre le problème :

$ git init
$ echo "*.txt -text" > .gitattributes
$ echo -e "hello\r\nworld" > 1.txt
$ git add 1.txt 
$ git commit -m "committed as binary"
$ echo "*.txt text" > .gitattributes
$ echo "change.." >> 1.txt

# Ok let's revert now

$ git checkout -- 1.txt
$ git status
 modified:   1.txt

# Oooops, it didn't revert!!

# hm let's diff:

$ git diff
 warning: CRLF will be replaced by LF in 1.txt.
 The file will have its original line endings in your working 
 directory.
 diff --git a/1.txt b/1.txt
 index c78c505..94954ab 100644
 --- a/1.txt
 +++ b/1.txt
 @@ -1,2 +1,2 @@
 -hello
 +hello
  world

# No actual changes. Ahh, let's change the line endings...

$ file 1.txt 
 1.txt: ASCII text, with CRLF line terminators
$ dos2unix 1.txt
 dos2unix: converting file 1.txt to Unix format ...
$ git diff
 git diff 1.txt
 diff --git a/1.txt b/1.txt
 index c78c505..94954ab 100644
 --- a/1.txt
 +++ b/1.txt
 @@ -1,2 +1,2 @@
 -hello
 +hello
  world

# No, it didn't work, file is still considered modified.

# Let's try to revert for once more:
$ git checkout -- 1.txt
$ git status
 modified:   1.txt

# Nothing. Let's use a magic command that prints wrongly committed files.

$ git grep -I --files-with-matches --perl-regexp '\r' HEAD

HEAD:1.txt

Deuxième mode de reproduction : Dans le script ci-dessus, remplacez cette ligne :
echo "*.txt -text" > .gitattributes
avec
git config core.autocrlf=false
et conserver le reste des lignes en l'état


Qu'est-ce que tout cela dit ? Un fichier texte puede (dans certaines circonstances) être avec CRLF, (par ex. -text en .gitattributes / ou core.autocrlf=false ).

Lorsque nous voudrons par la suite traiter le même fichier en tant que texte ( -text -> text ), il faudra l'engager à nouveau.
Bien sûr, vous pouvez temporairement revenir en arrière (comme l'a correctement répondu Abu Assar ). Dans notre cas :

echo "*.txt -text" > .gitattributes
git checkout -- 1.txt
echo "*.txt text" > .gitattributes

La réponse est : vous voulez vraiment faire ça, parce que ça va causer le même problème à chaque fois que vous changez le fichier.


Pour mémoire :

Pour vérifier quels fichiers peuvent causer ce problème dans votre repo, exécutez la commande suivante (git doit être compilé avec --with-libpcre) :

git grep -I --files-with-matches --perl-regexp '\r' HEAD

En engageant le(s) fichier(s) (en supposant que vous vouliez les traiter comme du texte), cela revient à faire ce qui est proposé dans ce lien http://help.github.com/line-endings/ pour résoudre ces problèmes. Mais, au lieu de supprimer .git/index et de réaliser reset vous pouvez simplement modifier le(s) fichier(s), puis exécuter la commande git checkout -- xyz zyf puis s'engager.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X