Differences between revisions 4 and 20 (spanning 16 versions)
Revision 4 as of 2008-03-24 10:39:15
Size: 2146
Editor: abuehl
Comment: new layout using included subpages in table
Revision 20 as of 2008-04-15 22:25:52
Size: 3040
Editor: abuehl
Comment: +or use hg strip from mq
Deletions are marked like this. Additions are marked like this.
Line 1: Line 1:
== Concatenating multiple changesets into one changeset == == Concatenating multiple changesets into one ==
Line 5: Line 5:
Suppose you have a repository with a number of changesets which you
want to combine into a single changeset.
=== Problem ===
Suppose you want to concatenate the last k changesets of a [:Repository:repository]
Line 8: Line 8:
This can be done as follows using only the basic operations of
mercurial, namely clone, push, pull.
 {{{#!dot
digraph {
  rankdir = LR;
  node [shape=box];
  S -> "S+1" -> "S+2";
  "S+2" -> "S+k" [style=dashed];
  label="oldrepo"
}}}
Line 11: Line 17:
For simplicity, let us assume that the repository in question has a
single head, and you want to combine the last k revisions into a
single revision.
into a single, combined changeset
Line 15: Line 19:
For concreteness, let us call the base revision R, and the ending
revision R+k.
 {{{#!dot
digraph {
  rankdir = LR;
  node [shape=box];
  S -> "S+k (combined)"
  label="newrepo"
}}}
Line 18: Line 27:
Let us furthermore assume the repository has no local changes. === Solution ===
Execute the following steps:
Line 20: Line 30:
The strategy is to take advantage of mercurial's support for
repositories with more than one head. What we do is create a branch
whose root revision is R and which consists of just one changeset
(actually it can be multiple changesets, the principle is the same,
but for simplicity let us assume one).
'''~+{{{1: hg -R oldrepo update S}}}+~'''
Line 26: Line 32:
Diagramatically, this looks like:  This [:Update:updates] the [:WorkingDirectory:working directory] to revision S.
 Specifically, this means that the contents of the working directory are
 changed to that of revision S, and that S becomes the [:Parent:parent]
 of the working directory.
Line 28: Line 37:
|| [[Include(/fig1)]] || [[Include(/fig2)]] || [[Include(/fig3)]] ||
||<:> [:/fig1:fig 1] ||<:> [:/fig2:fig 2] ||<:> [:/fig2:fig 3] ||
Line 31: Line 38:
The procedure is as follows. '''~+{{{2: hg -R oldrepo revert -r tip --all}}}+~'''
Line 33: Line 40:
 1. hg update R
    This updates the working directory to revision R. Specifically, this
    means that the contents of the working directory are changed to that
    of revision R, and that R becomes the parent of the working directory.
 {{{#!dot
digraph {
  rankdir = LR;
  node [shape=box];
  "working directory" -> S [label="1. update"];
  S -> "S+1" -> "S+2";
  "S+2" -> "S+k" [style=dashed];
  "working directory" -> "S+k" [color=red label="2. revert"];
  "working directory" [shape=ellipse];
  label="oldrepo"
}}}
Line 38: Line 52:
 2. hg revert -r tip --all
    
This reverts the working directory to its contents at tip.
    Since the parent of the working directory is still R, this means that
    the combined contents of all changesets between R and R+k show up as
    the modifications in the working directory.
 This [:Revert:reverts] the working directory to its contents at [:Tip:tip].
 Since the parent of the working directory is still S, this means that
 the combined contents of all changesets between S and S+k show up as
 the modifications in the working directory.
Line 44: Line 57:
 3. hg ci -m "Combined changesets between R and R+k"
    At this point, committing these modifications will create a changeset
    containing all combined changesets between revisions R and R+k.
Line 48: Line 58:
 4. hg clone -r tip oldrepo newrepo
    This assumes you want to get rid of your individual changesets
    (which are a dangling branch in oldrepo) and just keep the combined
    changeset. newrepo will now just have the combined changeset.
'''~+{{{3: hg -R oldrepo commit -m "Combine changesets S+1..S+k"}}}+~'''

 {{{#!dot
digraph {
  rankdir = LR;
  node [shape=box];
  "working directory" -> "S+k (combined)" [color=red label="3. commit"];
  "working directory" -> S [style=invis];
  S -> "S+k (combined)";
  S -> "S+1" -> "S+2";
  "S+2" -> "S+k" [style=dashed];
  "working directory" [shape=ellipse];
  label="oldrepo"
}}}

 [:Commit:Committing] these modifications creates a
 new changeset "S+k (combined)", containing combined changesets S+1 to S+k.


'''~+{{{4: hg clone -r tip oldrepo newrepo}}}+~'''

 {{{#!dot
digraph {
  rankdir = LR;
  node [shape=box];
  "working directory" -> S [style=invis];
  "working directory" -> "S+k (combined)" [color=red label="4. clone -r tip"]
  S -> "S+k (combined)"
  "working directory" [shape=ellipse label="cloned working directory"]
  label="newrepo"
}}}

 [[BR]]This assumes you want to get rid of your individual changesets (which are a dangling [:Branch:branch] in oldrepo) and just keep the combined changeset. newrepo will now just have the combined changeset.

 /!\ This will strip out '''all''' other branches, not just the one dangling branch ''that you don't want.'' If you have other branches that you want to keep, specify their [:Head:head] revisions or [:NamedBranches:branch names] on the [:Clone:clone] call:
 
  {{{hg clone -r tip -r branch1 -r branch2 -r branch3 oldrepo newrepo}}}

 Or you can use the {{{strip}}} command provided by the [:MqExtension:Mercurial Queues Extension].

Concatenating multiple changesets into one

(See also [:EditingHistory])

Problem

Suppose you want to concatenate the last k changesets of a [:Repository:repository]

into a single, combined changeset

Solution

Execute the following steps:

1: hg -R oldrepo update S

  • This [:Update:updates] the [:WorkingDirectory:working directory] to revision S. Specifically, this means that the contents of the working directory are changed to that of revision S, and that S becomes the [:Parent:parent] of the working directory.

2: hg -R oldrepo revert -r tip --all

  • This [:Revert:reverts] the working directory to its contents at [:Tip:tip]. Since the parent of the working directory is still S, this means that the combined contents of all changesets between S and S+k show up as the modifications in the working directory.

3: hg -R oldrepo commit -m "Combine changesets S+1..S+k"

  • [:Commit:Committing] these modifications creates a new changeset "S+k (combined)", containing combined changesets S+1 to S+k.

4: hg clone -r tip oldrepo newrepo

  • BRThis assumes you want to get rid of your individual changesets (which are a dangling [:Branch:branch] in oldrepo) and just keep the combined changeset. newrepo will now just have the combined changeset.

    /!\ This will strip out all other branches, not just the one dangling branch that you don't want. If you have other branches that you want to keep, specify their [:Head:head] revisions or [:NamedBranches:branch names] on the [:Clone:clone] call:

    • hg clone -r tip -r branch1 -r branch2 -r branch3 oldrepo newrepo

    Or you can use the strip command provided by the [:MqExtension:Mercurial Queues Extension].


CategoryTipsAndTricks

ConcatenatingChangesets (last edited 2013-10-10 10:48:33 by RamiroMorales)