J'ai besoin de combiner plusieurs fichiers de sortie git diff qui ne sont pas séquentiels dans un gros fichier diff unifié.
git diff rev1 rev5> diff1.txt
git diff rev44 rev551> diff2.txt
Cela produit un diff1.txt
et diff2.txt
ayant chacun des modifications, des suppressions et des mises à jour sur les lignes, dans un format standard git diff, de manière unifiée.
/ p>
Je voudrais à la fin:
combinez diff1.txt et diff2.txt
dans un fichier diff unifié qui combine les 2 fichiers diff, un peu comme un 'git squash' ou 'merge', mais avec juste la sortie de ceux-ci 2 fichiers diff.
Je ne peux rien faire de similaire ou contourner cela car j'ai généré ces 2 fichiers diff à partir de SVN via l'outil svn diff --git
diff qui produit la différence entre la révision actuelle et précédente dans un git compatible avec le format diff. Je dois donc écraser
ces 2 fichiers diff en un seul.
3 Réponses :
Je pense que vous en avez trop réfléchi. Cela fonctionnera-t-il?
Créez le premier diff
git diff rev44 rev551 >> diff.txt
Ajoutez le deuxième diff au premier. Notez le >>
git diff rev1 rev5 > diff.txt
Je ne veux pas ajouter, mais fusionner les différences, de sorte que si la ligne 2 a été modifiée, puis supprimée, je veux voir la sortie finale comme supprimée.
Le problème ici est que la demande n'a pas de sens.
En fin de compte, un diff est un ensemble d’instructions: appliquez ces modifications - où une modification provient d’un ensemble d’opérations de modification, généralement des «lignes de suppression» , "insérer la (les) ligne (s)", et / ou "changer la (les) ligne (s)" - à ces lignes spécifiées . Suivre les instructions transformera un fichier, le côté gauche du diff, en un deuxième fichier, le côté droit. Dans le cas de la sortie de diff unifié git diff
, le jeu d'instructions inclut un certain contexte pour les fichiers de gauche et de droite et les instructions sont limitées à "supprimer des lignes" et "insérer des lignes" (ou supprimer des mots et insérez des mots).
L'une des propriétés clés ici est que il n'y a que deux fichiers impliqués dans cette opération. Si le diff fournit un certain contexte (comme le font Git), le contexte aide à garantir que quiconque reçoit le diff a en fait le même fichier d'entrée que celui qui a fait le diff. L'application du diff devrait donc aboutir au même fichier de sortie.
Dans votre cas, cependant, vous avez quatre fichiers. Votre premier diff dit appliquer ces modifications au fichier rev1
pour produire le fichier rev5
. Votre deuxième diff dit appliquer ces modifications au fichier rev44
pour produire le fichier rev555
. Il n'y a aucune garantie que rev44
ressemble en aucune façon à rev5
. Cela pourrait ressembler d'une manière ou d'une autre à rev5
, mais ce n'est peut-être pas le cas. Sans beaucoup de contraintes supplémentaires sur les fichiers d'entrée, il est tout simplement impossible de combiner les instructions comme celle-ci. Un seul diff, quelle que soit sa construction, ne changera qu'un un fichier d'entrée en un fichier de sortie. Vous avez deux entrées et deux sorties, vous avez donc besoin de deux diffs. Si vous souhaitez les combiner, vous devez construire les (uniques) fichiers d'entrée et de sortie. Vous êtes le seul à posséder les quatre fichiers, vous êtes donc le seul à pouvoir le faire.
Comme le souligne @torek, ceci est sujet à des conflits. Votre meilleur pari est l'un des
svn checkout rev1 git init git add .; git commit -m rev1 svn checkout rev5 git add .; git commit -m rev5 svn checkout rev44 git add .; git commit -m rev44 svn checkout rev551 git add .; git commit -m rev551
ou si rev44..rev551 a beaucoup de commits,
git branch -f scratch rev5 git clone -sb scratch . `mktemp -d` cd $_
l'un ou l'autre a Git à faire toutes les fusions automatiques possibles et au moins trouver toutes les parties difficiles à résoudre manuellement.
Le ^ 0
est simplement "Je veux ce commit, pas le nom qui y pointe", au cas où vous utiliseriez un nom de branche pour pointer vers rev551, le rebase a gagné ' t déplacez la pointe de la branche, nous créons du contenu jetable juste pour voir les résultats, donc il n'y a pas besoin de noms.
Si vous ne voulez pas toucher votre arbre de travail actuel, créez un clone scratch jetable et faites le travail là-bas,
git checkout rev5 git diff rev44..rev551 | git apply -3 git diff rev1
et ensuite celle qui vous convient le mieux.
ah: juste remarqué que vous ne l'avez pas même avoir un historique git, il s'agit de différences au format git de svn.
Je suis assez confiant en disant que vous avez besoin de la machinerie de fusion de Git pour résoudre les conflits qui peuvent en découler. Cela fait long que je n'ai pas fait svn, quelque chose comme cette séquence devrait le faire:
git rebase --onto rev5 rev44 rev551^0 git diff rev1
alors le rebase ci-dessus devrait obtenir ce que vous voulez, vous pouvez utiliser : / rev44
pour faire référence au dernier commit qui a un "rev44" dans son message, c'est une regex donc : / rev5 $
trouve le dernier dont le message se termine rev5
.
Par squash, voulez-vous dire concaténer?
Je ne veux pas ajouter, mais fusionner les différences, de sorte que si la ligne 2 a été modifiée, puis supprimée, je veux voir la sortie finale comme supprimée.
Pouvez-vous faire une différence entre rev1 et rev551?