git mv et ne change que la casse du répertoire

259

Bien que j'ai trouvé une question similaire, je n'ai pas trouvé de réponse à mon problème

Lorsque j'essaie de renommer le répertoire de FOO en foo via git mv FOO fooj'obtiens

fatal: renaming 'FOO' failed: Invalid argument

D'ACCORD. Alors j'essayegit mv FOO foo2 && git mv foo2 foo

Mais quand j'essaye de m'engager via git commit .j'obtiens

# On branch master
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
# foo
nothing added to commit but untracked files present (use "git add" to track)

Lorsque j'ajoute le répertoire via git add foorien ne change et git commit .me redonne le même message.

Qu'est-ce que je fais mal? Je pensais que j'utilisais un système sensible à la casse (OSX), pourquoi ne puis-je pas simplement renommer le répertoire?

oschrenk
la source
10
Le système de fichiers d'OS X n'est pas sensible à la casse.
mipadi
2
@mipadi Il peut fonctionner en mode sensible à la casse, mais il est généralement désactivé par défaut.
GordonM
1
Cette question et ses réponses sont également utiles dans Windows. Pensez à déloger "osx"
Barett
1
Voir stackoverflow.com/a/24979063/6309 : depuis git 2.0.1, un simple git mvfonctionne.
VonC
Sur Windows, vous pouvez utiliser le standard git mv foo Foosi vous utilisez un shell cygwin.
Andrew Scott

Réponses:

410

Vous êtes dans un environnement insensible à la casse. De plus, l'ajout sans le -Ane prendra pas en charge le côté supprimer dumv Git. Avertissement! Assurez-vous qu'aucune autre modification ni aucun fichier non suivi ne sont présents lorsque vous effectuez cette opération, sinon ils seront validés dans le cadre de cette modification! git stash -ud'abord, faites cela et ensuite git stash pop. Continuer: Pour contourner ce problème, procédez comme suit:

mv foo foo2
git add -A
git commit -m "renaming"
mv foo2 FOO
git add -A
git commit --amend -m "renamed foo to FOO"

C'est la manière longue de changer le répertoire de travail, de valider puis de réduire les 2 validations. Vous pouvez simplement déplacer le fichier dans l'index, mais pour quelqu'un qui est nouveau dans git, il peut ne pas être suffisamment explicite sur ce qui se passe. La version plus courte est

git mv foo foo2
git mv foo2 FOO
git commit -m "changed case of dir"

Comme suggéré dans l'un des commentaires, vous pouvez également effectuer un rebase interactif ( git rebase -i HEAD~5si le mauvais cas a été introduit il y a 5 commits) pour y remédier et ne pas faire apparaître le mauvais cas n'importe où dans l'historique. Vous devez être prudent si vous le faites car les hachages de validation à partir de ce moment seront différents et les autres devront rebaser ou fusionner leur travail avec le passé récent de la branche.

Ceci est lié à la correction du nom d'un fichier: git n'est-il pas sensible à la casse?

Adam Dymitruk
la source
1
Merci. Cela me rendait fou. Je ne connaissais pas l'option -A ou --amend.
oschrenk
7
Attention à -A, car il ajoutera récursivement tout le contenu de votre répertoire actuel, y compris les éléments non suivis. Pourrait être mieux juste git add foo2.
rich.e
2
C'est exact. Cependant, vous devrez planifier à la fois la suppression de foo2 ainsi que l'ajout de FOO séparément. -As'occupe des deux. Vice versa pour la première étape. J'ajouterai l'avertissement. Merci!
Adam Dymitruk
Vous pouvez également nettoyer votre historique avec une rebase interactive git rebase -i HEAD~2. Remarque: Pour simplifier cela, définissez le message final dans votre premier commit et corrigez le second.
Alex B.
5
J'ai eu du succès avec git mv foo foo2; git mv foo2 FOO; git commit
Chris
146

Vous voulez définir l'option core.ignorecasesur false, ce qui obligera Git à faire attention à la casse sur les systèmes de fichiers qui ne le supportent pas nativement. Pour activer dans votre référentiel:

$ git config core.ignorecase false

Ensuite, vous pouvez renommer le fichier avec git mvet cela fonctionnera comme prévu.

mipadi
la source
1
Je pense que cela peut avoir des effets indésirables ailleurs. Les systèmes insensibles à la casse devraient laisser Git penser que c'est le même répertoire.
Adam Dymitruk
2
J'ai ajouté l'option à ma configuration globale mais cela n'a pas aidé
oschrenk
3
Je vois un comportement étrange en utilisant cela avec OSX. hrm I modified a file that doesn't exist.. hrm error: The following untracked working tree files would be overwritten by checkout:mais ... ces fichiers n'existent pas.
Skylar Saveland
C'était exactement ce que je cherchais. J'utilise CentOS 5.6 et il n'a pas repris le changement de boîtier.
crmpicco
5
Ça ne marche pas! Sur Git 1.8.3, Git traitera le fichier renommé comme un nouveau fichier, au lieu d'être supprimé + ajouté. La validation de ce type laissera le référentiel avec deux mêmes fichiers, par exemple foo et FOO existent tous les deux! Mais lors du paiement, un seul fichier apparaît (mais un cas peut dominer l'autre)
Johnny Wong
68

J'ai pu résoudre ce problème en utilisant git 1.7.7 en utilisant un nom de fichier temporaire:

$ git mv improper_Case improve_case2
$ git mv improve_case2 improve_case
$ git commit -m "<your message>"
mgadda
la source
Intéressant. Peut-être que GIT a amélioré quelque chose depuis lors. Lorsque je tomberai à nouveau sur ce problème, je réessaierai.
oschrenk
beaucoup plus facile de le faire de cette façon
olore
A travaillé pour moi sur macOS.
Mr_Pouet
14

(git mv -sans variante.)

J'ai rencontré ce problème dans Git sur Mac OS X 10.9. Je l'ai résolu comme suit:

git rm -r --cached /path/to/directory

Cela met en scène le répertoire à supprimer dans Git mais ne supprime en fait aucun fichier physique ( --cached). Cela fait également apparaître le répertoire, maintenant avec le cas approprié, dans les fichiers non suivis.

Vous pouvez donc faire ceci:

mv /path/to/directory /path/to/DIRECTORY
git add -A /path/to/DIRECTORY

Git reconnaîtra alors que vous avez renommé les fichiers, et lorsque vous le faites, git statusvous devriez voir un certain nombre de renamed:lignes. Inspectez-les et assurez-vous qu'ils semblent corrects. Si tel est le cas, vous pouvez valider les modifications normalement.

wizonesolutions
la source
J'ai trouvé que la mvcommande ne fonctionnait pas pour renommer le répertoire; J'ai dû le renommer dans Finder. En dehors de cela, ce correctif fonctionne parfaitement.
Adam S
9

Il s'agit d'une solution rapide et sans bug:

git mv -f path/to/foo/* path/to/FOO/

Avertissement! Renommez toujours tous les fichiers du dossier renommé (utilisez /*).

Ne renommez pas de fichiers uniques. Cela conduit à un bogue, décrit dans cette réponse .

Si vous voulez d'abord voir le résultat en premier, utilisez -n:

git mv -f -n path/to/foo/* path/to/FOO/

Après avoir fait un mv:

  1. Valider les modifications
  2. Paiement vers toute autre révision
  3. Retour en caisse.

Maintenant, Git aurait dû renommer le dossier LES DEUX dans ses fichiers internes et dans le système de fichiers.

Nick Volynkin
la source
Est-ce uniquement pour Git 2.0.1 comme je l'ai mentionné dans les commentaires de la question ci-dessus? (se référant à stackoverflow.com/a/24979063/6309 )
VonC
8

Forcer avec l'option -f:

git mv -f FOO foo
konyak
la source
Ne fonctionne pas pour moi. Mon réglage est "ignorecase = true" de .git / config. Le renommage ne peut pas être transféré dans la zone de transfert de cette manière. (Git version 1.8.3.msysgit.0) La solution d'Adam Dymitruk est la seule bonne réponse.
Johnny Wong
@JohnnyWong changez votre réglage en false, cela a fonctionné pour moi
Inder Kumar Rathore
Est-ce que cela se mettra à jour sur tous les ordinateurs des autres utilisateurs s'ils tirent, même si leur ordinateur est configuré pour ignorer la casse?
Bryce
@Bryce Non, vous devrez valider les modifications et les envoyer au référentiel central avant que les autres utilisateurs puissent tirer les modifications.
konyak
3

J'avais un problème connexe.

Un dossier nommé «Pro» (créé en premier) et un autre «pro» (créé par erreur). Sous Mac, c'est la même chose, mais différent selon git.

$ git config core.ignorecase false

la configuration git renommait les fichiers dans le bon dossier (merci), et créait également des fichiers fantômes dans 'pro' (Non !!). Je ne pouvais pas ajouter de modifications de fichiers fantômes à la piste et je ne pouvais pas vérifier d'autres branches à moins de transporter ces fichiers avec moi, et je ne pouvais pas non plus le réinitialiser d'une manière ou d'une autre.

Au lieu de cela, je l'ai fait

$ git rm -r --cached pro
$ git status // => pro files removed, new Pro files untracked
$ git add Pro

Pour le rendre plus sûr, je l'ai fait dans une branche fixe séparée, puis j'ai fusionné pour revenir à la branche principale

Pour le problème de fichier fantôme créé par, n'importe quel gourou peut-il expliquer comment et pourquoi? Merci d'avance.

Seeliang
la source
2

Vous n'utilisez pas un système de fichiers sensible à la casse dans OS X, sauf si vous l'avez choisi explicitement. HFS + peut être sensible à la casse, mais la valeur par défaut est insensible à la casse.

Nicholas Knight
la source
4
L'utilisation du système de fichiers sensible à la casse sur OS X n'est pas une bonne idée. Beaucoup d'applications ne fonctionnent PAS correctement, j'ai appris cela. Un problème particulier est qu'Adobe Photoshop refusera l'installation en disant que le système de fichiers sensible à la casse n'est pas pris en charge.
jpswain
1

Voici une solution très simple autour de tous les gitfoo de cette page.

  1. Copiez manuellement les fichiers de votre projet.
  2. git rm tous les fichiers.
  3. git commit comme d'habitude.
  4. ajoutez les fichiers manuellement.
  5. git ajouter tous les fichiers.
  6. git commit comme d'habitude.
  7. profit.
Askdesigners
la source
1
Cela fonctionne localement, mais si quelqu'un d'autre fait un pull cela ne changera pas son cas.
Jason
Merci de m'avoir aidé à corriger les doubles entrées dans git avec différents cas. J'en ai utilisé une variante. Je viens de renommer le dossier parent. Vous avez commis un commit. Puis renommé le dossier parent pour revenir à l'original. Et a fait un deuxième commit. Maintenant, les anciennes entrées avec le cas différent ont disparu.
dreamerkumar
0

Améliorer la réponse d'Adam Dymitruk (idiot que SO ne me laisse pas commenter sa réponse), utiliser "git mv" mettra automatiquement en scène exactement les fichiers déplacés. Aucun stockage n'est nécessaire et le "git add -A" risqué peut être évité:

old="abc";    new="ABC";
tmp="$old-renamed";
git mv "$old" "$tmp";
git commit -m "Renamed '$old' to '$tmp'.";
git mv "$tmp" "$new";
git commit --amend -m "Renamed '$old' to '$new'.";
Rainer Blome
la source
0

Cela a très bien fonctionné pour moi sur Windows. PowerShell utilisé avec les éléments suivants:

  1. mv .\Folder-With-Wrong-Casing .\temp
  2. git add -A
  3. git commit -m "renamed folder with wrong casing to temp"
  4. mv .\temp .\Folder-with-Correct-Casing
  5. git add -A
  6. git commit --amend -m "Renamed to proper casing"
  7. (optionnel) git push

Merci à la réponse d'Adam ci-dessus.

Tony
la source