Patchwork [2,of,2,STABLE] bookmarks: resolve divergent bookmarks when moving active bookmark forward

login
register
mail settings
Submitter Sean Farley
Date April 29, 2013, 10:38 p.m.
Message ID <ddd8b869e48d8d353905.1367275122@laptop.local>
Download mbox | patch
Permalink /patch/1503/
State Superseded
Commit 741d94aa92e4562f9ba3ac09a366e1e644ca3d16
Headers show

Comments

Sean Farley - April 29, 2013, 10:38 p.m.
# HG changeset patch
# User Sean Farley <sean.michael.farley@gmail.com>
# Date 1367272357 18000
#      Mon Apr 29 16:52:37 2013 -0500
# Branch stable
# Node ID ddd8b869e48d8d353905e9c0b2964c3795a9dc88
# Parent  d6ff913a84d296fc6d1ed129351eb215d7e6920e
bookmarks: resolve divergent bookmarks when moving active bookmark forward

This patch resolves divergent bookmarks between the current active bookmark
MARK and the new destination. This situation can arise when pulling new
changesets, abandoning your current changesets actively bookmarked with MARK
via strip, and then doing a bare update. The non-divergent but active bookmark
MARK is then moved to a common ancestor of the new changesets and the abandoned
changesets.

Test coverage is added.
Sean Farley - April 30, 2013, 1:12 a.m.
On Mon, Apr 29, 2013 at 7:49 PM, Kevin Bullock
<kbullock+mercurial@ringworld.org> wrote:
> On 29 Apr 2013, at 5:38 PM, Sean Farley wrote:
>
>> # HG changeset patch
>> # User Sean Farley <sean.michael.farley@gmail.com>
>> # Date 1367272357 18000
>> #      Mon Apr 29 16:52:37 2013 -0500
>> # Branch stable
>> # Node ID ddd8b869e48d8d353905e9c0b2964c3795a9dc88
>> # Parent  d6ff913a84d296fc6d1ed129351eb215d7e6920e
>> bookmarks: resolve divergent bookmarks when moving active bookmark forward
>>
>> This patch resolves divergent bookmarks between the current active bookmark
>> MARK and the new destination. This situation can arise when pulling new
>> changesets, abandoning your current changesets actively bookmarked with MARK
>> via strip, and then doing a bare update. The non-divergent but active bookmark
>> MARK is then moved to a common ancestor of the new changesets and the abandoned
>> changesets.
>>
>> Test coverage is added.
>>
>> diff --git a/mercurial/bookmarks.py b/mercurial/bookmarks.py
>> --- a/mercurial/bookmarks.py
>> +++ b/mercurial/bookmarks.py
>> @@ -169,24 +169,28 @@
>>                 del marks[mark]
>>                 deleted = True
>>     return deleted
>>
>> def update(repo, parents, node):
>> +    deletefrom = parents
>>     marks = repo._bookmarks
>>     update = False
>>     cur = repo._bookmarkcurrent
>>     if not cur:
>>         return False
>>
>>     if marks[cur] in parents:
>>         old = repo[marks[cur]]
>>         new = repo[node]
>> +        divs = [repo[b] for b in marks
>> +                if b.split('@', 1)[0] == cur.split('@', 1)[0]]
>> +        deletefrom = [b.node() for b in divs if b.descendant(new) or b == new]
>
> How come these two calculations are slightly different from those in patch 1?

Mainly because of the surrounding code: in patch 1 there was already
some code that used ancestors() while in this code there was already
some code that used descendant(). I didn't know the ramifications (and
code churn) of using a lazy generator here.

Patch

diff --git a/mercurial/bookmarks.py b/mercurial/bookmarks.py
--- a/mercurial/bookmarks.py
+++ b/mercurial/bookmarks.py
@@ -169,24 +169,28 @@ 
                 del marks[mark]
                 deleted = True
     return deleted
 
 def update(repo, parents, node):
+    deletefrom = parents
     marks = repo._bookmarks
     update = False
     cur = repo._bookmarkcurrent
     if not cur:
         return False
 
     if marks[cur] in parents:
         old = repo[marks[cur]]
         new = repo[node]
+        divs = [repo[b] for b in marks
+                if b.split('@', 1)[0] == cur.split('@', 1)[0]]
+        deletefrom = [b.node() for b in divs if b.descendant(new) or b == new]
         if old.descendant(new):
             marks[cur] = new.node()
             update = True
 
-    if deletedivergent(repo, parents, cur):
+    if deletedivergent(repo, deletefrom, cur):
         update = True
 
     if update:
         marks.write()
     return update
diff --git a/tests/test-bookmarks-current.t b/tests/test-bookmarks-current.t
--- a/tests/test-bookmarks-current.t
+++ b/tests/test-bookmarks-current.t
@@ -131,25 +131,31 @@ 
   $ hg bookmark -i -m Y X
   $ hg bookmarks
      X                         0:719295282060
      Z                         0:719295282060
 
-bare update moves the active bookmark forward
+bare update moves the active bookmark forward and clear the divergent bookmarks
 
   $ echo a > a
   $ hg ci -Am1
   adding a
+  $ echo b >> a
+  $ hg ci -Am2
+  $ hg bookmark X@1 -r 1
+  $ hg bookmark X@2 -r 2
   $ hg update X
   0 files updated, 0 files merged, 1 files removed, 0 files unresolved
   $ hg bookmarks
    * X                         0:719295282060
+     X@1                       1:cc586d725fbe
+     X@2                       2:49e1c4e84c58
      Z                         0:719295282060
   $ hg update
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   updating bookmark X
   $ hg bookmarks
-   * X                         1:cc586d725fbe
+   * X                         2:49e1c4e84c58
      Z                         0:719295282060
 
 test deleting .hg/bookmarks.current when explicitly updating
 to a revision