2017-04-27 2 views
8

Je souhaite déplacer deux fichiers d'un référentiel à un autre. Les fichiers ont été initialement ajoutés comme:Création de correctifs Git pour deux fichiers sur plusieurs renames

  1. /src/init/Price.cs
  2. /tests/init/PriceTests.cs

Les plus tard deux fichiers ont été renommés:

  1. /src/init/PriceValue.cs
  2. /tests/init/PriceValueTests.cs

Et puis déplacé à:

  1. /src/moved/PriceValue.cs
  2. /tests/moved/PriceValueTests.cs

J'ai essayé d'aller par this description pour créer un ensemble de correctifs pour ces fichiers, mais je ne suis pas sûr comment passer dans les six chemins différents les fichiers ont existé.

J'ai réussi à trouver tous les commettre ID affectant PriceValue.cs (à travers renommages et les déplacements), mais en passant ces ID à Git échoue avec le message d'erreur suivant:

$ git format-patch -o /tmp/pricevaluepatches $(git log --all dfeeb 6966b 9f882 …) 
-bash: /usr/local/bin/git: Argument list too long 

Alors, comment puis-je créer un ensemble de correctifs pour cela qui contient uniquement les modifications apportées aux fichiers mentionnés, mais le contient à travers un renommage et un déplacement de chaque fichier?

+0

Avez-vous essayé de mettre tous les ID de validation dans un fichier 'ids.txt' (un par ligne) et d'exécuter' cat ids.txt | xargs git format-correctif -o/tmp/pricevaluepatches'? –

+2

De plus, vous n'avez pas besoin d'exécuter 'git log --all ...' dans votre commande. Un simple 'git format-patch -o/tmp/pricevaluepatches dfeeb 6966b 9f882 ...' devrait suffire. –

+0

@NilsWerner, merci pour les suggestions. Cela ne corrige que la moitié du problème. À partir des validations reconnues par les ID que j'ai, comment puis-je appliquer uniquement les changements qui affectent 'PriceValue.cs' et' PriceValueTests.cs' à travers le changement de nom et le déplacement? –

Répondre

1

Hmm ..... En supposant que je veux conserver les fichiers de correctifs tels qu'ils sont, je voudrais que le fichier patch soit appliqué sur une branche pour que je puisse ensuite le sélectionner sur la bonne branche. Donc, supposons que j'ai sur ma branche principale un fichier nommé /tests/moved/PriceValueTests.cs et que je souhaite y appliquer un patch portant le nom /tests/init/PriceTests.cs à la place. En supposant que je ne le font pas veulent pirater le fichier patch, ce que je ferais est:

  • créer une branche temporaire de mon maître
  • branche temp caisse
  • renommer le fichier vers le même chemin que le fichier patch a (et livrez, bien sûr)
  • appliquent fichier patch sur la branche temporaire (devrait fonctionner maintenant que le chemin du fichier a un fichier correspondant)
  • commettras sur la branche temporaire
  • de chec Kout maître
  • écrémer dernière révision de branche temporaire

Il en est ainsi que git peut suivre le changement de nom et être en mesure de l'appliquer avec succès. Je l'ai fait un certain nombre de fois et l'algorithme de renommage de fichiers de git a tendance à bien faire les choses.

+0

Cela répond à autre chose mais pas à cette question. La question n'a pas de fichiers à patcher, seuls ceux qui sont déplacés d'un référentiel à l'autre. –

6

Vous pouvez obtenir les correctifs de quelques fichiers spécifiques mais pas avant que de commettre sha1 en utilisant

git format-patch sha1 -- file1 file2 ... 

Tous les fichiers peuvent être un ancien fichier (avant un changement de nom) ou un fichier existant.

Si vous voulez tous les commits jusqu'à commettre sha1 vous pouvez utiliser

git format-patch --root sha1 -- file1 file2 ... 

Donc dans votre cas, tous les engage jusqu'à présent (HEAD) de vos six fichiers:

git format-patch --root HEAD -- /src/init/Price.cs /src/init/PriceValue.cs /src/moved/PriceValue.cs /src/init/PriceTests.cs /src/init/PriceValueTests.cs /src/moved/PriceValueTests.cs 
+0

Donc, je devrais connaître tous les ID de validation affectant tous les fichiers à tous les emplacements en premier? –

+0

Non, juste le premier que vous voulez. Si vous voulez * tout commet * de ces fichiers, entrez simplement 'origin' comme sha1. –

+0

@ AsbjørnUlsberg: 'format-patch' va générer une séquence de patchs, qui permettra de recréer un historique linéaire. Il ne vous permettra pas de «transplanter» l'historique d'une branche avec des fusions - un seul correctif ne contient pas les informations sur ses parents. – LeGEC

1

Pour atteindre l'objectif de la question via une fusion (au lieu d'un patch individuel passant par format-patch comme la question posée), on peut supprimer tous les autres fichiers dans un nouveau commit, puis fusionner cette validation à travers le dépôt s dans le référentiel cible (adapté de https://stackoverflow.com/a/10548919/7496656):

cd path/to/project-a 
git checkout -b for-b master # or whichever branch you want to merge from 
git rm -r . 
git checkout HEAD -- src/moved/PriceValue.cs tests/moved/PriceValueTests.cs 
git commit 
cd path/to/project-b 
git remote add project-a path/to/project-a 
git fetch project-a 
git merge --allow-unrelated-histories project-a/for-b 
git remote remove project-a 
cd path/to/project-a 
git branch -D for-b 

Ceci a l'avantage que toute l'histoire est là, COMMIT ID restent les mêmes et il n'y a pas besoin de jongler commits individuels ni les trouver. Cela peut avoir l'inconvénient qu'une vue linéarisée (comme git log) par opposition à la vue graphique (comme gitk) devient probablement plus confuse à mesure que le nombre de commits non liés devient plus grand.

Vous pouvez en outre filtrer le référentiel project-a avant la fusion, pour masquer des fichiers ou des validations non liés. Cependant, les inconvénients sont les suivants: Si vous faites cela plusieurs fois dans un dépôt, peut-être aussi dans l'autre sens, cela rend l'historique moins net car l'histoire commune ne se produit que plusieurs fois (une fois pour chaque fusion). Cela rendrait également cette solution plus difficile que votre première tentative. Cela aurait également l'inconvénient que les ID de validation ne restent pas les mêmes et qu'il ne serait donc pas aussi facile de trouver quels étaient les mêmes commit à travers les dépôts.