Differences between revisions 3 and 5 (spanning 2 versions)
Revision 3 as of 2011-02-09 17:14:22
Size: 4751
Comment: changing some links for pointing on translated pages + some improvements
Revision 5 as of 2011-06-30 22:27:22
Size: 7222
Comment: changes from original english page
Deletions are marked like this. Additions are marked like this.
Line 1: Line 1:
#language fr
#pragma section-numbers 2
Line 3: Line 5:
== Backout == = Backout =
Line 9: Line 11:
<<TableOfContents>>
Line 12: Line 16:
<<BR>><<BR>>

==== Voici quelques explications complémentaires de Matt sur le fonctionnement interne (légèrement adapté, par expérience) ====

== Fonctionnement interne ==

Voici quelques explications complémentaires de Matt sur le fonctionnement interne (légèrement adapté, par expérience)
Line 17: Line 22:
Soit <rev de départ> la révision à laquelle nous allons faire un backout.<<BR>> Soit `<rev de départ>` la révision à laquelle nous allons faire un backout.
Line 30: Line 35:
L'étape 4 permet de s'assurer que les changesets parents sont fusionnés dans le bon ordre. C'est à dire : parent1 = <rev de départ>, et parent2 = <la nouvelle rev backout>.
<<BR>><<BR>>

==
== Un exemple: ====
L'étape 4 permet de s'assurer que les changesets parents sont fusionnés dans le bon ordre. C'est à dire : `parent1 = <rev de départ>` et `parent2 = <la nouvelle rev backout>`.

== Un exemple: ==
Line 149: Line 153:
<<BR>><<BR>>
Voir aussi : [[FrenchUpdate|Update]], [[FrenchRevert|Revert]], [[FrenchCommit|Commit]], [[FrenchMerge|Merge]]

== Backout d'un Changeset fusionné ==

Imaginez une situation dans laquelle nous fusionnons deux changesets. Le premier changeset contient `a b` dans un fichier donné, le second contient `x y` dans ce même fichier. La fusion entraîne un conflit que nous résolvons ainsi :

{{{#!dot
    digraph G {
      graph[rankdir=LR]
      node[shape=box]

      a -> b -> c
      x -> y -> c

      a [label="a"]
      b [label="a b"]
      c [label="a b Y X"]
      x [label="x"]
      y [label="x y"]
    }
}}}

Nous travaillons un peu sur la branche du dessus pour ajouter `c` dans ce fichier. Nous découvrons alors que la fusion était mauvaise. Nous faisons un backout dessus :

{{{#!dot
    digraph G {
      graph[rankdir=LR]
      node[shape=box]

      a -> b -> c -> d -> e
      x -> y -> c

      a [label="a"]
      b [label="a b"]
      c [label="a b Y X"]
      d [label="a b c Y X"]
      e [label="a b c", color=red]
      x [label="x"]
      y [label="x y"]
    }
}}}

Le nouveau changeset rouge est le backout, il a supprimé les lignes `Y` et `X` de la mauvaise fusion, mais il a gardé la nouvelle ligne `c` qui a été ajoutée après la fusion.

Nous faisons quelques changements supplémentaires à la branche du dessous et la fusionnons encore :

{{{#!dot
    digraph G {
      graph[rankdir=LR]
      node[shape=box]

      a -> b -> c -> d -> e -> f
      x -> y -> c
      y -> z -> f

      a [label="a"]
      b [label="a b"]
      c [label="a b Y X"]
      d [label="a b c Y X"]
      e [label="a b c", color=red]
      f [label="a b c z"]
      x [label="x"]
      y [label="x y", color=green]
      z [label="x y z", color=blue]
    }
}}}

L'idée est que le nouveau changeset fusionné devrait contenir les lignes `x y z` parallèlement aux lignes `a b c`.
Cependant ce qui se passe est que la fusion contient un backout sur les lignes `x` et `y` !

Le meilleur ancêtre commun des changesets rouge `a b c` et bleu `x y z` est le changeset avec `x y`. La triple façon de fusionner considère ainsi le fichier dans ces configurations :

 * base : `x y`
 * local : `a b c`
 * autre : `x y z`

L'algorithme de fusion conclue que les lignes `x` et `y` ont été retirées volontairement, tandis que `a b c` et `z` ont été ajoutées. Le résultat est que les lignes `x y` sont écartées de manière tacite !

== Voir aussi ==

 * [[FrenchUpdate|Update]]
 * [[FrenchRevert|Revert]]
 * [[FrenchCommit|Commit]]
 * [[FrenchMerge|Merge]]

(Traduction du texte original en anglais : Backout)

Backout

hg backout [OPTION]... [-r] REV

Annule les effets du précédent changeset.

Backout fonctionne en appliquant les modifications inverses à celles du dernier changeset. Ce nouveau changeset est validé (commit) au dépôt et éventuellement fusionné (merge).

Référence manuel : http://www.selenic.com/mercurial/hg.1.html#backout

1. Fonctionnement interne

Voici quelques explications complémentaires de Matt sur le fonctionnement interne (légèrement adapté, par expérience) (voir aussi ce fil de discussion e-mail)

Soit <rev de départ> la révision à laquelle nous allons faire un backout. Backout est en fait la compilation de quatre étapes en une :

  1. hg update -C -r <rev-pour-le-backout>

  2. hg revert --all -r <parent de rev-pour-le-backout>

  3. hg commit

  4. hg update -C -r <rev de départ>

Il y a une cinquième étape qui se fait automatiquement si vous utilisez l'option --merge :

  1. hg merge  (fusionne <rev de départ> avec la révision nouvellement validée à l'étape 3.)

Ainsi qu'une sixième étape, manuelle celle-là :

  1. hg commit  (le resultat de la fusion)

Lorsque l'étape 3 (commit) avorte, vous vous retrouvez avec les deux premières étapes terminées et vous pouvez faire :

  • hg commit  et résoudre par vous même les problème, et / ou

  • hg update -C  pour abandonner le processus

L'étape 4 permet de s'assurer que les changesets parents sont fusionnés dans le bon ordre. C'est à dire : parent1 = <rev de départ> et parent2 = <la nouvelle rev backout>.

2. Un exemple:

$ hg init depot
$ cd depot
$ echo ligne1 > fichier.txt
$ echo ligne2 >> fichier.txt
$ hg ci -Am "ajout de fichier"

Editons file.txt, pour obtenir :

ligne1
ligne1a
ligne2

On commit et on fait quelques modifications :

$ hg ci -m "ajout ligne1a"
$ echo ligne3 >> fichier.txt
$ hg ci -m "ajout ligne3"
$ echo ligne4 >> fichier.txt
$ hg ci -m "ajout ligne4"

Ce qui produit l'arbre suivant (un brin raccourci) :

@  changeset:   3:36b1c0649d3e
|  tag:         tip
|  summary:     ajout ligne4
|
o  changeset:   2:2612107e45fe
|  summary:     ajout ligne3
|
o  changeset:   1:1f33c361852e
|  summary:     ajout ligne1a
|
o  changeset:   0:e3e45b087239
   summary:     ajout de fichier

Maintenant on fait un backout sur le changeset 1:1f33c361852e.

$ hg backout -r 1

L'arbre est désormais :

o  changeset:   4:c3daad6d657d
|  tag:         tip
|  parent:      1:1f33c361852e
|  summary:     Backed out changeset 1f33c361852e
|
| @  changeset:   3:36b1c0649d3e
| |  summary:     ajout ligne4
| |
| o  changeset:   2:2612107e45fe
|/   summary:     ajout ligne3
|
o  changeset:   1:1f33c361852e
|  summary:     ajout ligne1a
|
o  changeset:   0:e3e45b087239
   summary:     ajout de fichier

On fusionne et commit, ce qui donne l'arbre final :

@    changeset:   5:236d8d74edf8
|\   tag:         tip
| |  parent:      3:36b1c0649d3e
| |  parent:      4:c3daad6d657d
| |  summary:     merge backout
| |
| o  changeset:   4:c3daad6d657d
| |  parent:      1:1f33c361852e
| |  summary:     Backed out changeset 1f33c361852e
| |
o |  changeset:   3:36b1c0649d3e
| |  summary:     ajout ligne4
| |
o |  changeset:   2:2612107e45fe
|/   summary:     ajout ligne3
|
o  changeset:   1:1f33c361852e
|  summary:     ajout ligne1a
|
o  changeset:   0:e3e45b087239
   summary:     ajout de fichier

Et fichier.txt est comme suit, s'étant vu joliment éliminé la 'ligne1a' de la rev 1.

ligne1
ligne2
ligne3
ligne4



Quand on essaie cela en séparant les étapes, et qu'on oublie l'étape 4, on obtient un arbre légèrement différent. Notez l'ordre inversé des parents dans le changeset 5:0eeac5ff9c76.

@    changeset:   5:0eeac5ff9c76
|\   tag:         tip
| |  parent:      4:cbca219e80e1      | <---
| |  parent:      3:f82e9468d652      |
| |  summary:     merge backout
| |
| o  changeset:   4:cbca219e80e1
| |  parent:      1:0cf85b44002c
| |  summary:     Backed out changeset 0cf85b44002c
| |
o |  changeset:   3:f82e9468d652
| |  summary:     ajout ligne4
| |
o |  changeset:   2:24ceac6b9018
|/   summary:     ajout ligne3
|
o  changeset:   1:0cf85b44002c
|  summary:     ajout ligne1a
|
o  changeset:   0:73af1be51d81
   summary:     ajout de fichier

3. Backout d'un Changeset fusionné

Imaginez une situation dans laquelle nous fusionnons deux changesets. Le premier changeset contient a b dans un fichier donné, le second contient x y dans ce même fichier. La fusion entraîne un conflit que nous résolvons ainsi :

Nous travaillons un peu sur la branche du dessus pour ajouter c dans ce fichier. Nous découvrons alors que la fusion était mauvaise. Nous faisons un backout dessus :

Le nouveau changeset rouge est le backout, il a supprimé les lignes Y et X de la mauvaise fusion, mais il a gardé la nouvelle ligne c qui a été ajoutée après la fusion.

Nous faisons quelques changements supplémentaires à la branche du dessous et la fusionnons encore :

L'idée est que le nouveau changeset fusionné devrait contenir les lignes x y z parallèlement aux lignes a b c. Cependant ce qui se passe est que la fusion contient un backout sur les lignes x et y !

Le meilleur ancêtre commun des changesets rouge a b c et bleu x y z est le changeset avec x y. La triple façon de fusionner considère ainsi le fichier dans ces configurations :

  • base : x y

  • local : a b c

  • autre : x y z

L'algorithme de fusion conclue que les lignes x et y ont été retirées volontairement, tandis que a b c et z ont été ajoutées. Le résultat est que les lignes x y sont écartées de manière tacite !

4. Voir aussi


FrenchCommand

FrenchBackout (last edited 2012-02-22 06:53:22 by Jérôme Melis)