[PATCH] convert: filemap must preserve fast-forward merges (issue3340)

Kevin Bullock kbullock+mercurial at ringworld.org
Sun May 27 20:10:20 CDT 2012


On 27 May 2012, at 1:58 PM, Patrick Mezard wrote:

> # HG changeset patch
> # User Patrick Mezard <patrick at mezard.eu>
> # Date 1338141206 -7200
> # Branch stable
> # Node ID db0660915e353f8a87ed11fb87660a794c0bab45
> # Parent  30e46d7138de0acb2d811162c1cf3441afe1687e
> convert: filemap must preserve fast-forward merges (issue3340)
> 
> When running convert with a filemap, revisions which changes were
> filtered out and not closing branch were discarded. Unfortunately, this
> also discards fast-forward merges between named branches, which are
> fairly important, especially for head revisions.

It appears you mean "merges between a changeset and its ancestor that are on different named branches". While it likely doesn't affect the correctness of your patch, those aren't fast-forward merges. Actually they're the _opposite_ of fast-forward merges: to get such a DAG in Git, which of course invented the confusing term, you need the --no-fast-forward option.

Yet another example why the term "fast-forward merge" is confusing and should be avoided.

pacem in terris / мир / शान्ति / ‎‫سَلاَم‬ / 平和
Kevin R. Bullock

> This patch makes --filemap preserve fast-forward merges between distinct
> named branches, even if the merge brings nothing but a branch switch,
> and even if the empty merge comes from ancestors being filtered by the
> filemap.
> 
> diff --git a/hgext/convert/filemap.py b/hgext/convert/filemap.py
> --- a/hgext/convert/filemap.py
> +++ b/hgext/convert/filemap.py
> @@ -297,6 +297,7 @@
>         # - is not an ancestor of the mapped versions of the other parents
>         mparents = []
>         wp = None
> +        branch = self.commits[rev].branch
>         for i, p1 in enumerate(parents):
>             mp1 = self.parentmap[p1]
>             if mp1 == SKIPREV or mp1 in mparents:
> @@ -305,7 +306,9 @@
>                 if p1 == p2 or mp1 == self.parentmap[p2]:
>                     continue
>                 if mp1 in self.wantedancestors[p2]:
> -                    break
> +                    # Discard fast-forward in the same branch
> +                    if self.commits[p2].branch == branch:
> +                        break
>             else:
>                 mparents.append(mp1)
>                 wp = i
> @@ -319,7 +322,6 @@
>         if 'close' in self.commits[rev].extra:
>             # A branch closing revision is only useful if one of its
>             # parents belong to the branch being closed
> -            branch = self.commits[rev].branch
>             pbranches = [self._cachedcommit(p).branch for p in mparents]
>             if branch in pbranches:
>                 closed = True
> diff --git a/tests/test-convert-filemap.t b/tests/test-convert-filemap.t
> --- a/tests/test-convert-filemap.t
> +++ b/tests/test-convert-filemap.t
> @@ -375,3 +375,88 @@
>   |
>   o  0 "addb" files: b
> 
> +test fast-forward
> +
> +  $ hg init fastforward
> +  $ cd fastforward
> +  $ echo a > a
> +  $ echo b > b
> +  $ hg ci -Am adda
> +  adding a
> +  adding b
> +  $ hg branch foo
> +  marked working directory as branch foo
> +  (branches are permanent and global, did you want a bookmark?)
> +  $ echo a >> a
> +  $ hg ci -m branchfoo
> +  $ hg up -qC 0
> +  $ echo b >> b
> +  $ hg ci -m changeb
> +  $ hg merge foo
> +  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
> +  (branch merge, don't forget to commit)
> +  $ hg ci -m mergefoo
> +  $ hg branch bar
> +  marked working directory as branch bar
> +  (branches are permanent and global, did you want a bookmark?)
> +  $ echo a >> a
> +  $ hg ci -m branchbar
> +  $ hg up -qC 3
> +  $ hg merge bar
> +  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
> +  (branch merge, don't forget to commit)
> +  $ hg ci -m fastforwardbar
> +  $ hg up -qC 1
> +  $ echo b >> b
> +  $ hg ci -m changebagain
> +  $ hg up -qC 5
> +  $ hg merge --tool internal:local 6
> +  0 files updated, 0 files merged, 0 files removed, 0 files unresolved
> +  (branch merge, don't forget to commit)
> +  $ hg ci -m merge6
> +  $ cd ..
> +  $ glog -R fastforward
> +  @    7 "merge6" files:
> +  |\
> +  | o  6 "changebagain" files: b
> +  | |
> +  o |    5 "fastforwardbar" files:
> +  |\ \
> +  | o |  4 "branchbar" files: a
> +  |/ /
> +  o |  3 "mergefoo" files:
> +  |\|
> +  o |  2 "changeb" files: b
> +  | |
> +  | o  1 "branchfoo" files: a
> +  |/
> +  o  0 "adda" files: a b
> +  
> +
> +  $ cat > filemap <<EOF
> +  > include a
> +  > EOF
> +  $ hg convert --filemap filemap fastforward fastforward1
> +  initializing destination fastforward1 repository
> +  scanning source...
> +  sorting...
> +  converting...
> +  7 adda
> +  6 branchfoo
> +  5 changeb
> +  4 mergefoo
> +  3 branchbar
> +  2 fastforwardbar
> +  1 changebagain
> +  0 merge6
> +  $ glog -R fastforward1
> +  o    4 "fastforwardbar" files:
> +  |\
> +  | o  3 "branchbar" files: a
> +  |/
> +  o    2 "mergefoo" files:
> +  |\
> +  | o  1 "branchfoo" files: a
> +  |/
> +  o  0 "adda" files: a
> +  
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at selenic.com
> http://selenic.com/mailman/listinfo/mercurial-devel

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://selenic.com/pipermail/mercurial-devel/attachments/20120527/339c959a/attachment.html>


More information about the Mercurial-devel mailing list