web-dev-qa-db-fra.com

Git: Comment restaurer 2 fichiers qui sont obstinément bloqués dans "Modifié mais pas commis"?

J'ai un repo qui a deux fichiers que j'ai soi-disant changé localement.

Donc, je suis coincé avec ceci:

$ 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 tout le contenu du fichier a changé, même si cela semble faux (il semble y avoir des gammes de lignes communes que diff ne semble pas voir).

Fait intéressant, je ne me souviens pas d'avoir changé ces fichiers localement. Ce référentiel est utilisé avec un référentiel distant (privé, sur GitHub.com, FWIW).

Peu importe ce que j'ai essayé, je ne peux pas ignorer ces modifications locales. J'ai tout essayé:

$ 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 Comment supprimer les modifications non mises en scène dans Git? plus plus. Mais les 2 fichiers restent bloqués car "modifiés mais non validés".

Qu'est-ce qui ferait que deux fichiers soient bloqués comme ceci et apparemment "un-revert-table" ??

P.S. Dans la liste ci-dessus montrant les commandes que j'avais déjà essayées, j'ai écrit par erreur git revert alors que je voulais dire git checkout. Je suis désolé et merci à ceux d'entre vous qui ont répondu que je devrais essayer checkout. J'ai édité la question pour la corriger. J'ai certainement déjà essayé checkout.

76
Greg Hendershott

Quelles sont les fins de ligne dans les fichiers? Je parie qu'ils sont CRLF. Si tel est le cas, consultez ce guide: http://help.github.com/line-endings/

En bref, vous devez vous assurer que git est configuré pour convertir les fins de ligne en LF lors de la validation, puis valider ces fichiers. Les fichiers dans le référentiel doivent toujours être au format LF, les fichiers extraits doivent être natifs du système d'exploitation, en supposant que vous définissiez git correctement.

31
Tekkub

J'ai passé des heures à essayer de résoudre un problème similaire - une branche distante que j'avais extraite, qui indiquait obstinément quatre fichiers comme étant "modifiés mais non mis à jour", même en supprimant tous les fichiers et en exécutant à nouveau git checkout -f (ou d'autres variantes de ce message)!

Ces quatre fichiers étaient nécessaires mais n’avaient certainement pas été modifiés par moi. Ma solution finale - persuader Git qu'ils n'avaient pas été changés. Ce qui suit fonctionne pour tous les fichiers extraits, indiquant le statut 'modifié' - assurez-vous que vous avez déjà validé/stocké ceux qui ont vraiment été modifiés!

git ls-files -m | xargs -i git update-index --assume-unchanged "{}"

Sur Mac OSX, cependant xargs fonctionne un peu différemment (merci Daniel pour le commentaire):

git ls-files -m | xargs -I {} git update-index --assume-unchanged {}

J'ai ajouté ceci comme espace réservé pour moi pour la prochaine fois, mais j'espère que cela aidera aussi quelqu'un d'autre.

-Al

102
Alan Forsyth

voici comment j'ai résolu le même problème dans mon cas: ouvrir.

* text=auto

à:

#* text=auto

enregistrer et fermer, puis revenir ou réinitialiser, .__, grâce à @Simon East

21
Abu Assar

Une autre possibilité est que la différence (cela vous empêche de restaurer ces fichiers avec une commande d'extraction) est celle du mode fichier. Voilà ce qui m'est arrivé. Sur ma version de git, vous pouvez découvrir cela en utilisant

git diff dir1/foo.aspx

Et il vous montrera les changements de mode de fichier. Il ne vous laissera toujours pas les rétablir, cependant. Pour cette utilisation soit

git config core.filemode false

ou changez votre git .config dans votre éditeur de texte en ajoutant

[coeur]

filemode = false

Après cela, vous pouvez utiliser

réinitialisation git HEAD dir1/foo.aspx

et le fichier devrait disparaître.

(J'ai tout cela de la réponse à Comment puis-je modifier le mode git ignore (chmod)? )

10
Eyal

Essayez de annuler les modifications locales :

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

Certains de mes fichiers fantômes ont été modifiés, mais ils étaient identiques.

Exécuter cette commande parfois fonctionne:
(Désactive les conversions de fin de ligne "intelligentes" mais souvent inutiles)

git config --local core.autocrlf false

Mais dans un autre cas, j’ai trouvé que cela était dû à un fichier .gitattributes dans la racine, qui contenait certains paramètres de fin de ligne, qui essayait d’appliquer autocrlf à certains fichiers même s’il était désactivé. Cela n’a pas été vraiment utile, j’ai donc supprimé .gitattributes, validé, et le fichier n’a plus été modifié.

3
Simon East
git checkout dir1/foo.aspx
git checkout dir2/foo.aspx
2
Steve Prentice

Je pense qu’il serait utile de donner un indice 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

2ème façon de reproduire: Dans le script ci-dessus, remplacer cette ligne:
echo "*.txt -text" > .gitattributes
avec
git config core.autocrlf=false
et garder le reste des lignes tel quel


Qu'est-ce que tout ce qui précède dit? Un fichier texte peut (dans certaines circonstances) être commis avec CRLF, (par exemple -text dans .gitattributesou core.autocrlf=false). 

Plus tard, lorsque nous voudrons traiter le même fichier en tant que texte (-text -> text), il devra être validé à nouveau.
Bien sûr, vous pouvez le retourner temporairement (comme corrigé correctement par Abu Assar ). Dans notre cas: 

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

_/La réponse est: voulez-vous vraiment le faire, car le problème sera toujours le même chaque fois que vous modifierez le fichier.


Pour mémoire:

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

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

En commettant le (s) fichier (s) (en supposant que vous souhaitiez les traiter comme du texte), vous remplissez les fonctions proposées dans ce lien http://help.github.com/line-endings/ pour résoudre ces problèmes. Mais, au lieu de supprimer .git/index et d'exécuter reset, vous pouvez simplement modifier le (s) fichier (s), puis exécuter git checkout -- xyz zyf, puis valider.

1
Marinos An

Pour moi, le problème ne concernait pas les fins de ligne. Il s'agissait de changer la casse dans le nom du dossier (Reset_password -> Reset_Password). Cette solution m'a aidé: https://stackoverflow.com/a/34919019/1328513

1
Ievgen

Vous avez peut-être également eu un problème lié aux répertoires nommant des casses de lettres . Certains de vos collègues auraient pu changer le nom du répertoire myHandler to MyHandler . Si vous avez ensuite poussé et extrait certains des fichiers du répertoire d'origine, vous auriez eu 2 répertoires distincts sur le référentiel distant ET seulement un sur votre ordinateur local puisque sous Windows, vous ne pouvez en avoir qu’un seul. Et vous avez des problèmes.

Pour vérifier si c'est le cas, il suffit de voir si le référentiel distant a une double structure.

Pour résoudre ce problème, faites une copie de sauvegarde du répertoire parent en dehors du référentiel, puis supprimez le répertoire parent, puis appuyez dessus. Faites un pull (c'est ici que le second marqué comme supprimé doit apparaître dans le statut) et Poussez à nouveau . Après cela, recréez toute la structure à partir de votre sauvegarde et Poussez à nouveau les modifications.

0
smexy