Je lirais que lorsque vous renommez des fichiers dans git , vous devez valider toutes les modifications, effectuer votre renommage, puis mettre en scène votre fichier renommé. Git reconnaîtra le fichier à partir du contenu, plutôt que de le voir comme un nouveau fichier non suivi, et conservera l'historique des modifications.
Cependant, en faisant juste ce soir, j'ai fini par revenir git mv
.
> $ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: index.html
#
Renommer ma feuille de style dans le Finder de iphone.css
àmobile.css
> $ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: index.html
#
# Changed but not updated:
# (use "git add/rm <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# deleted: css/iphone.css
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# css/mobile.css
Git pense maintenant que j'ai supprimé un fichier CSS et en ai ajouté un nouveau. Pas ce que je veux, permet d'annuler le changement de nom et de laisser git faire le travail.
> $ git reset HEAD .
Unstaged changes after reset:
M css/iphone.css
M index.html
Retour là où j'ai commencé.
> $ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: index.html
#
Permet d'utiliser à la git mv
place.
> $ git mv css/iphone.css css/mobile.css
> $ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# renamed: css/iphone.css -> css/mobile.css
#
# 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: index.html
#
On dirait que nous sommes bons. Alors pourquoi git n'a-t-il pas reconnu le changement de nom la première fois quand j'ai utilisé le Finder?
add+rm
oumv
- il produit le même résultat. Git utilise ensuite sa détection de renommer / copier pour vous faire savoir qu'il s'agissait d'un renommage. La source que vous avez citée est également inexacte. Peu importe que vous modifiiez + renommer dans le même commit ou non. Lorsque vous effectuez un diff à la fois sur la modification et le changement de nom, la détection de changement de nom le verra comme un changement de nom + modification, ou si la modification est une réécriture totale, elle s'affichera comme ajoutée et supprimée - peu importe comment vous avez effectué il.git mv old new
met automatiquement à jour l'index. Lorsque vous renommez en dehors de Git, vous devrez faire legit add new
etgit rm old
pour mettre en scène les modifications de l'index. Une fois que vous avez fait cela,git status
cela fonctionnera comme prévu.public_html
, qui sont suivis dans git. Après avoir jouégit add .
etgit commit
, il montrait toujours un tas de fichiers «supprimés» dansgit status
. J'ai effectué ungit commit -a
et les suppressions ont été validées mais maintenant je n'ai plus d'historique sur les fichiers qui y viventpublic_html
maintenant. Ce flux de travail n'est pas aussi fluide que je le souhaiterais.Réponses:
Pour
git mv
la page de manuel ditDonc, dans un premier temps, vous devez mettre à jour l'index par vous-même (en utilisant
git add mobile.css
). Cependantgit status
, deux fichiers différents seront toujours affichésVous pouvez obtenir une sortie différente en exécutant
git commit --dry-run -a
, ce qui se traduit par ce que vous attendez:Je ne peux pas vous dire exactement pourquoi nous voyons ces différences entre
git status
etgit commit --dry-run -a
, mais voici un indice de Linus :A
dry-run
utilise les vrais mécanismes de changement de nom, alors quegit status
probablement pas.la source
git add mobile.css
. Sans celagit status -a
, il aurait seulement «vu» la suppression duiphone.css
fichier précédemment suivi mais n'aurait pas touché le nouveaumobile.css
fichier non suivi . En outre,git status -a
n'est pas valide avec Git 1.7.0 et versions ultérieures. "" Git status "n'est plus" git commit --dry-run "." dans kernel.org/pub/software/scm/git/docs/RelNotes-1.7.0.txt . À utilisergit commit --dry-run -a
si vous souhaitez cette fonctionnalité. Comme d'autres l'ont dit, il suffit de mettre à jour l'index etgit status
fonctionnera comme prévu par l'OP.git commit
elle ne valide pas le fichier renommé et l'arborescence de travail est toujours la même.git commit -a
défait à peu près tous les aspects du workflow / modèle de réflexion de git - chaque changement est engagé. que se passe-t-il si vous souhaitez uniquement renommer le fichier, mais valider les modificationsindex.html
dans un autre commit?mobile.css
ce que j'aurais dû mentionner. Mais c'est le point de ma réponse: la page de manuel dit quethe index is updated
lorsque vous utilisezgit-mv
. Merci pour lastatus -a
clarification, j'ai utilisé git 1.6.4git status
ne détectait pas le changement de nom. Courirgit commit -a --dry-run
après avoir ajouté mes "nouveaux" fichiers a montré les renommées et m'a finalement donné confiance pour m'engager!git status
se comporte maintenant commegit commit
.Vous devez ajouter les deux fichiers modifiés à l'index avant que git ne le reconnaisse comme un mouvement.
La seule différence entre
mv old new
etgit mv old new
est que le git mv ajoute également les fichiers à l'index.mv old new
alorsgit add -A
ça aurait marché aussi.Notez que vous ne pouvez pas simplement l'utiliser
git add .
car cela n'ajoute pas de suppressions à l'index.Voir Différence entre "git add -A" et "git add".
la source
git add -A
lien, très utile, car je cherchais un tel raccourci!git add .
Le mieux est de l'essayer par vous-même.
Maintenant, git status et git commit --dry-run -a affiche deux résultats différents où git status affiche bbb.txt comme un nouveau fichier / aaa.txt est supprimé, et les commandes --dry-run montrent le renommage réel.
Maintenant, allez-y et faites l'enregistrement.
Vous pouvez maintenant voir que le fichier est en fait renommé et que ce qui est affiché dans git status est faux.
Morale de l'histoire: si vous n'êtes pas sûr que votre fichier ait été renommé, lancez un "git commit --dry-run -a". Si cela montre que le fichier est renommé, vous êtes prêt à partir.
la source
Pour git 1.7.x, les commandes suivantes ont fonctionné pour moi:
Il n'y avait pas besoin de git add, car le fichier d'origine (c'est-à-dire css / mobile.css) était déjà dans les fichiers validés précédemment.
la source
vous devez
git add css/mobile.css
le nouveau fichier etgit rm css/iphone.css
, donc git le sait. alors il affichera la même sortiegit status
vous pouvez le voir clairement dans la sortie d'état (le nouveau nom du fichier):
et (l'ancien nom):
je pense que dans les coulisses
git mv
n'est rien de plus qu'un script wrapper qui fait exactement cela: supprimer le fichier de l'index et l'ajouter sous un nom différentla source
git rm css/iphone.css
parce que je pensais que cela supprimerait l'historique existant. Peut-être que je comprends mal le flux de travail dans git.git rm
ne supprimera pas l'historique. Il supprime uniquement une entrée de l'index afin que le prochain commit n'ait pas l'entrée. Cependant, il existera toujours dans les commits ancestraux. Ce qui peut vous dérouter, c'est que (par exemple)git log -- new
s'arrêtera au point où vous vous êtes engagégit mv old new
. Si vous souhaitez suivre les renommages, utilisezgit log --follow -- new
.Pensons à vos fichiers du point de vue git.
Votre référentiel a (entre autres)
et il est sous contrôle git:
Testez cela avec:
Quand tu fais
Du point de vue git,
Ainsi, git conseille sur les fichiers qu'il connaît déjà ( iphone.css ) et les nouveaux fichiers qu'il détecte ( mobile.css ) mais uniquement lorsque les fichiers sont dans l'index ou que HEAD git commence à vérifier leur contenu.
En ce moment, ni "suppression de iphone.css" ni mobile.css ne sont sur l'index.
Ajouter la suppression iphone.css à l'index
git vous dit exactement ce qui s'est passé: ( iphone.css est supprimé. Il ne s'est plus rien passé)
puis ajoutez un nouveau fichier mobile.css
Cette fois, la suppression et le nouveau fichier sont sur l'index. Maintenant, git détecte que le contexte est le même et l'expose comme un renommage. En fait, si les fichiers sont similaires à 50%, cela détectera cela comme un renommage, ce qui vous permettra de changer un peu mobile.css tout en conservant l'opération comme un renommage.
Voir ceci est reproductible sur
git diff
. Maintenant que vos fichiers sont sur index, vous devez utiliser--cached
. Modifiez un peu mobile.css , ajoutez-le à l'index et voyez la différence entre:et
-M
est l'option "détecter les renommages" pourgit diff
.-M
signifie-M50%
(50% ou plus de similitude fera git l'exprimer comme un renommage) mais vous pouvez le réduire à-M20%
(20%) si vous éditez beaucoup mobile.css.la source
Étape 1: renommer le fichier de l'ancien fichier en nouveau fichier
Étape 2: git commit et ajout de commentaires
Étape 3: envoyez cette modification au serveur distant
la source
git mv
, le nouveau fichier est déjà dans l'index.C'est là que vous vous êtes trompé.
Ce n'est qu'après avoir ajouté le fichier, que git le reconnaîtra à partir du contenu.
la source
Vous n'avez pas mis en scène les résultats de votre mouvement de recherche. Je crois que si vous faisiez le déplacement via le Finder et que vous le
git add css/mobile.css ; git rm css/iphone.css
faisiez, git calculerait le hachage du nouveau fichier et ne réaliserait alors que le hachage des fichiers correspond (et donc c'est un renommage).la source
Dans les cas où vous devez vraiment renommer les fichiers manuellement, par exemple. en utilisant un script pour renommer par lots un tas de fichiers, puis en utilisant
git add -A .
travaillé pour moi.la source
Pour les utilisateurs de Xcode: si vous renommez votre fichier dans Xcode, l'icône du badge change pour s'ajouter. Si vous effectuez une validation en utilisant XCode, vous créerez en fait un nouveau fichier et perdrez l'historique.
Une solution de contournement est facile mais vous devez le faire avant de valider en utilisant Xcode:
renommé: Project / OldName.h -> Project / NewName.h renommé: Project / OldName.m -> Project / NewName.m
Revenez ensuite à XCode et vous verrez le badge changé de A à M et il est sauvegardé pour valider les changements futurs en utilisant xcode maintenant.
la source