2016-09-23 1 views
-3

S'il vous plaît pardonnez mon ignorance ici ... Voici l'arrière-plan: J'ai créé un répertoire TestScritps pour organiser les scripts de test. J'ai déplacé trois scripts de <root dir> à <root dir>/TestScripts. J'ai déménagé un à la fois et a effectué un commit local après chacun d'eux. J'ai alors poussé tous les changements.Pourquoi 'git mv' ne déplace-t-il pas un fichier? Comment le faire agir "normalement"?

Je suis allé à une autre machine et effectué une traction:

$ cd cryptopp/ 
$ git pull 
remote: Counting objects: 25, done. 
remote: Compressing objects: 100% (24/24), done. 
remote: Total 25 (delta 11), reused 0 (delta 0), pack-reused 0 
Unpacking objects: 100% (25/25), done. 
From https://github.com/weidai11/cryptopp 
    2ac9ea1..2a22a84 master  -> origin/master 
Updating 2ac9ea1..2a22a84 
Fast-forward 
TestScripts/cryptest-android.sh | 44 + 
TestScripts/cryptest-ios.sh  | 40 + 
TestScripts/cryptest.sh   | 5729 +++++++++++++++++++++++++++++++++++++++ 
rijndael.cpp     | 2 +- 
setenv-android.sh    | 85 +- 
5 files changed, 5870 insertions(+), 30 deletions(-) 
create mode 100755 TestScripts/cryptest-android.sh 
create mode 100755 TestScripts/cryptest-ios.sh 
create mode 100755 TestScripts/cryptest.sh 

$ ls *.sh 
cryptest-android.sh cryptest.sh  setenv-android.sh setenv-ios.sh 
cryptest-ios.sh  rdrand-nasm.sh setenv-embedded.sh 

Remarquez les fichiers ont été copiés uniquement; ils n'ont pas été déplacés.

J'ai vérifié le git-mv man page, mais le comportement errant ne semble pas être discuté.

J'ai deux questions. Pourquoi git mv ne copie que des fichiers et ne les déplace pas? Comment puis-je faire git mv effectuer "normalement"? Ici, "normalement" signifie ce que presque chaque personne qui a utilisé la ligne de commande attend - il déplace le fichier de <target location> à <destination location>.


Voici l'historique des commandes pertinentes.

994 rm -rf cryptopp/ 
    995 git clone https://github.com/weidai11/cryptopp 
    996 cd cryptopp/ 
    997 mkdir TestScripts 
    998 git mv cryptest.sh TestScripts/ 
    999 ls *.sh 
1000 git commit TestScripts/cryptest.sh -m "Organize test scripts (Issue 303)" 
1001 ls *.sh 
1002 git mv cryptest-ios.sh TestScripts/ 
1003 git commit TestScripts/cryptest-ios.sh -m "Organize test scripts (Issue 303)" 
1004 ls *.sh 
1005 git commit 
+1

Qu'est-ce que vous obtenez de 'git status'? – Amit

+0

Quelle était la séquence exacte des commandes exécutées sur la machine d'origine? –

+0

@Amit - Sur la machine qui a effectué le déplacement: *** 'Votre branche est à jour avec 'origin/master'. *** Cependant, j'ai supprimé le clone et recloué. Je l'ai trouvé nécessaire à l'occasion pour empêcher Git de casser ses fichiers d'index. Quand cela arrive, je ne peux même pas changer de branche, donc c'est un état que j'essaye d'éviter à tout prix. Les copies et les mouvements semblent briser régulièrement Git, donc je le fais après l'opération. – jww

Répondre

3

À partir du sommaire illustré dans la sortie de git pull, je vois que ces fichiers ont pas été supprimés.

Lorsque vous avez par exemple .:

git commit TestScripts/cryptest.sh -m "Organize test scripts (Issue 303)" 

Alors que Git est généralement bien dans les fichiers de suivi se déplace, à l'intérieur d'un mouvement est enregistré comme la suppression d'un fichier et la création d'un nouveau identique. Vous avez commis le nouveau fichier, et pas la suppression du fichier de l'emplacement d'origine, donnant ainsi l'impression que Git vient de copier le fichier.

À l'avenir, il est généralement une bonne idée de laisser le nom de la commande commit:

git commit -m "Organize test scripts (Issue 303)" 

Vous pouvez faire git status l'avance pour voir ce qui sera engagé, et modifier au besoin.

Une session complète pourrait ressembler à ceci:

$ git mv cryptest.sh TestScripts/ 
$ git status 
On branch master 
Changes to be committed: 
    (use "git reset HEAD <file>..." to unstage) 

     renamed: cryptest.sh -> TestScripts/cryptest.sh 

$ git commit -m "Organize test scripts (Issue 303)" 
$ git status 
On branch master 
nothing to commit, working directory clean 
$ ls cryptest.sh 
ls: cannot access cryptest.sh: No such file or directory 
$ ls TestScripts/cryptest.sh 
TestScripts/cryptest.sh 

Pour fixer, faire:

git rm cryptes*.sh 
git commit 

Si vous voulez fixer la place de votre histoire, vous pouvez le faire:

git rebase -i HEAD^3 

et de changer la commande pour le comm approprié de pick à edit. A chaque arrêt, faites:

git rm <file> 
git commit --amend 
git rebase --continue 

<file> est le fichier d'origine en cours.Notez que cela va réécrire votre historique, ce qui peut causer des problèmes lors du déplacement entre les machines.


Notez qu'il ne devrait pas être nécessaire de supprimer et de re-clone un repo Git, donc si vous avez des problèmes à l'avenir, il est préférable d'essayer de résoudre le problème de la racine. (Search around ou ask here si vous avez besoin d'aide!)

+0

Merci Scott. Comment faire pour que Git se comporte comme prévu? Je veux que 'git mv' fasse réellement ce que presque tout le monde dans le monde libre attend lorsqu'ils déplacent un fichier. – jww

+0

@jww Mise à jour de ma réponse. –

+0

Merci Scott. Je pense que nous souffrons d'une déconnexion (en raison de mon ignorance, mes excuses). Je n'ai pas besoin de réécrire l'histoire ou quelque chose de fantaisie. Essayer de faire quelque chose de fantaisiste et de meneur de jeu ne fait que compliquer ma vie et enlève ma tâche principale. C'est pourquoi je supprime et recommence. Pour référence future, quand j'effectue 'git mv ...; git commit ...; git push', comment puis-je m'assurer qu'un mouvement se produit et non une copie? Le mieux que je puisse dire à Git n'est que des copies; ça ne bouge pas. Y at-il une commande de déplacement * "real" * qui déplace le fichier? – jww

2

Le problème est dans votre (ab) utilisation de la commande git commit.

git mv déplace le fichier comme il se doit. Dites, j'ai une prise en pension avec un seul fichier, appelé a, et je veux le déplacer comme b:

$ git mv a b 
$ git status 
On branch master 
Changes to be committed: 
    (use "git reset HEAD <file>..." to unstage) 

    renamed: a -> b 

$ ls 
b <-- Only b exists here, no a 

Le mouvement est maintenant enregistré dans l'index, mais pas commis. Pour créer le commettras, je fais:

$ git commit -m "Move a as b" 

Cependant, ce que vous avez été:

$ git commit b -m "Move a as b" 
[master b275677] Move a as b 
1 file changed, 0 insertions(+), 0 deletions(-) 
create mode 100644 b 

Lorsque vous donnez un nom de fichier comme argument pour git commit il ne comprend que les fichiers répertoriés dans la validation, au lieu de enregistrer l'index actuel.

En interne, git ne comprend pas ce qu'est un mouvement. Il comprend qu'un fichier a été créé et un autre fichier a été supprimé. Les outils utilisés pour afficher l'historique (git log par exemple) combinent ces deux informations et affichent le fichier comme déplacé. Mais lorsque vous avez spécifié que seul le fichier nouvellement créé doit être inclus dans le commit, il n'a pas enregistré la suppression de l'ancien fichier, il n'apparaît donc pas comme un mouvement lorsque vous avez tiré de l'autre machine.

Donc la réponse à votre question: "Pourquoi git mv ne déplace-t-il pas un fichier? Comment le faire" normalement "?" - il déplace un fichier, mais vous avez spécifiquement dit à git de ne valider que la création du nouveau fichier, pas la suppression de l'ancien. Pour le faire agir normalement, ne faites pas cela - à la place, émettez git commit sans nom de fichier comme arguments.

+0

Merci. * "vous avez spécifiquement dit à git de ne commettre que la création du nouveau fichier" * - en fait, j'ai dit à Git de déplacer un fichier; pas ajouter ou supprimer. Ce qu'il fait dans les coulisses, c'est son affaire. Après le déplacement, il n'y a qu'un seul fichier sur le système de fichiers (re: les commandes 'ls'). C'est celui que je commets. Si Git laissait les deux fichiers sur le système de fichiers, je dirais à git de faire quelque chose avec les deux. Y a-t-il un moyen d'amener Git à agir normalement? – jww

+1

Oui, vous avez dit à git de déplacer un fichier, et c'est ce qu'il a fait. Mais alors vous lui avez dit de ne pas commettre le mouvement entier, mais seulement commettre la création du nouveau fichier. Pour le faire "agir normalement", ne faites pas cela. – 1615903