2009-07-06 6 views
18

En relation avec Mercurial: Merging one file between branches in one repo, j'essaye d'effectuer une opération de backout sur un seul fichier, même si ce fichier était l'un des nombreux participants à la révision en cours de sauvegarde. HG étant l'outil orienté changeset, il ne veut pas fonctionner sur des fichiers. Le plus proche que j'ai pu trouver était d'utiliser hg export pour créer un diff, modifier manuellement le diff, puis importer hg pour patcher le fichier dans l'ordre inverse.Dans mercurial, comment appliquer un reverse-patch à un fichier particulier?

..mais alors j'ai frappé cette situation ennuyeuse où http://hgbook.red-bean.com/read/finding-and-fixing-mistakes.html prétend qu'il y a une option - inverse à hg patch quand il n'y en a pas. Donc la chose la plus proche que je puisse penser est de générer un patch édité à la main comme ci-dessus, puis en utilisant le patch van -R pour appliquer un patch inverse.

La commande hg backout semble être utile ici, mais est en fait un hareng rouge.

Il doit y avoir un meilleur moyen, non?

+2

L'option --reverse est de * patch *, pas * hg patch *. – balpha

Répondre

22

Vous pouvez le faire en utilisant seulement le -I (inclure les noms correspondant aux modèles donnés) arguments pour backout avec une seule ligne:

hg backout --merge -I thefiletorevert -m 'message' OFFENDINGREVISIONID 

Exemple de script:

hg init testrepo 
cd testrepo 
echo -e "line1\n\nline3" > file1 
echo -e "line1\n\nline3" > file2 
hg commit -A -m 'changes to two files' 
perl -pi -e 's/line1/line 1/' file1 
perl -pi -e 's/line1/line 1/' file2 
hg commit -m 'put spaces in line1' 
perl -pi -e 's/line3/line 3/' file1 
perl -pi -e 's/line3/line 3/' file2 
hg commit -m 'put spaces in line3' 
hg backout --merge -I file1 -m 'remove spaces from line1' 1 

Exemple de sortie :

adding file1 
adding file2 
reverting file1 
created new head 
changeset 3:6d354f1ad4c5 backs out changeset 1:906bbeaca6a3 
merging with changeset 3:6d354f1ad4c5 
merging file1 
0 files updated, 1 files merged, 0 files removed, 0 files unresolved 
(branch merge, don't forget to commit) 

résultant Contenu du fichier:

file1:line1 
file1:line 3 
file2:line 1 
file2:line 3 

avis que fichier1 manque son espace en ligne un après l'backout du milieu changeset, et le journal détaillé montre qu'un seul fichier changé backout:

$ hg log -v -r tip 
changeset: 3:6d354f1ad4c5 
tag:   tip 
parent:  1:906bbeaca6a3 
user:  Ry4an Brase <[email protected]> 
date:  Mon Sep 14 12:17:23 2009 -0500 
files:  file1 
description: 
remove spaces from line1 
+0

Je pense que je comprends cette solution, mais cette affaire semble plus simple que la mienne, puisque ici vous retirez (l'un des fichiers) le changement de pourboire, alors que balpha traite de mon cas plus général de reculer un changement historique. – djsadinoff

+1

Naw, cela fonctionnerait bien pour un changeset sans tip, bien que cela nécessiterait de "hg merge" à la fin. Cependant, vous auriez toujours un graphique d'histoire qui reflète exactement ce qui s'est passé et la parenté de changeset, contrairement à la copie-it-over de balpha, qui donnerait un changelog linéaire. –

+0

Cool. Si vous deviez publier un exemple avec un changement enterré, je le marquerais correctement. – djsadinoff

6

Voici ce que je ferais: Utiliser un nouveau clone de la révision de la pointe.

hg backout --merge -r revision_where_the_change_happened 

pour fusionner les modifications inversées dans la copie de travail.

Maintenant, copiez le fichier en question à votre copie de travail régulier et COMMIT

hg commit -m "Reversed the changes to file.h made in revision bla" 

et jeter le clone créé ci-dessus. De cette façon, mercurial ne sait pas qu'il existe une connexion entre revision_where_the_change_happened et cette validation. Si vous voulez Mercurial de se rappeler cela, au lieu faire

hg revert {all files except the one in question} 

après la fusion backout engager dans la copie de travail et avant de valider. Pour la deuxième façon, vous n'avez pas besoin de travailler sur un clone, car vous voulez garder le backout commit.

Je suppose que le choix du mode d'utilisation dépend de la taille du changement de fichier.

3

Utilisez la commande revert.

hg revert -r1 file 

Cela devrait revenir le contenu du fichier à la version en cours de révision 1. Vous pouvez ensuite modifier davantage et engager normalement.

+0

Il est correct de réinitialiser un fichier à une version antérieure comme celle-ci. Cela fonctionnerait même ici si le fichier n'a pas été changé depuis la mauvaise version. Mais si plus de modifications ont été faites, un simple retour ne fonctionnera pas. Au lieu de cela, vous devrez mettre à jour la mauvaise révision, rétablir le fichier à une bonne version, faire un commit et fusionner les deux têtes. Je crois que c'est essentiellement ce que le backout fait pour vous. –

Questions connexes