Re: [PATCH 2 of 3] rebase: allow rebase even if some revisions need no rebase (BC) (issue5422)

2017-05-11 Thread Martin von Zweigbergk via Mercurial-devel
On Fri, May 5, 2017 at 11:14 PM, Martin von Zweigbergk
 wrote:
> On Fri, May 5, 2017 at 7:19 PM, Yuya Nishihara  wrote:
>> On Thu, 04 May 2017 13:20:11 -0700, Martin von Zweigbergk via 
>> Mercurial-devel wrote:
>>> # HG changeset patch
>>> # User Martin von Zweigbergk 
>>> # Date 1489219466 28800
>>> #  Sat Mar 11 00:04:26 2017 -0800
>>> # Node ID 2765672140ea50f5587be486b25af10509a3d35b
>>> # Parent  5af88edb7a0bbafad999a2cef8968efbfd64becf
>>> rebase: allow rebase even if some revisions need no rebase (BC) (issue5422)
>>>
>>> This allows you to do e.g. "hg rebase -d @ -r 'draft()'" even if some
>>> drafts are already based off of @. You'd still need to exclude
>>> obsolete and troubled revisions, though. We will deal with those cases
>>> later.
>>>
>>> Implemented by treating state[rev]==rev as "no need to rebase". I
>>> considered adding another fake revision number like revdone=-6. That
>>> would make the code clearer in a few places, but would add extra code
>>> in other places.
>>
>> Perhaps updatebookmarks() will need a guard to not flag
>> tr.hookargs['bookmark_moved'] by null move.
>
> Ah, good catch! I will also try to add more tests.

I couldn't actually find any concrete effect of this. The only
difference if we don't consider bookmarks "moves" from X to X is that
deletedivergent() does not get called. I can't see how that would make
a difference in practice either. I'll still change it in v2 because it
makes sense to not include the un-moved nodes in the 'nstates' dict
used for bookmarks.

>
>>
>> I'm not sure if the fake revision is better. Using 'state[rev] = rev' makes
>> sense, but we'll have to check all places where state[rev] are used anyway.
>
> I'm not sure which I prefer either, so I'll just pick the 'state[rev]
> = rev' version for v2, but let me know if you change you mind.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 2 of 3] rebase: allow rebase even if some revisions need no rebase (BC) (issue5422)

2017-05-05 Thread Martin von Zweigbergk via Mercurial-devel
On Fri, May 5, 2017 at 7:19 PM, Yuya Nishihara  wrote:
> On Thu, 04 May 2017 13:20:11 -0700, Martin von Zweigbergk via Mercurial-devel 
> wrote:
>> # HG changeset patch
>> # User Martin von Zweigbergk 
>> # Date 1489219466 28800
>> #  Sat Mar 11 00:04:26 2017 -0800
>> # Node ID 2765672140ea50f5587be486b25af10509a3d35b
>> # Parent  5af88edb7a0bbafad999a2cef8968efbfd64becf
>> rebase: allow rebase even if some revisions need no rebase (BC) (issue5422)
>>
>> This allows you to do e.g. "hg rebase -d @ -r 'draft()'" even if some
>> drafts are already based off of @. You'd still need to exclude
>> obsolete and troubled revisions, though. We will deal with those cases
>> later.
>>
>> Implemented by treating state[rev]==rev as "no need to rebase". I
>> considered adding another fake revision number like revdone=-6. That
>> would make the code clearer in a few places, but would add extra code
>> in other places.
>
> Perhaps updatebookmarks() will need a guard to not flag
> tr.hookargs['bookmark_moved'] by null move.

Ah, good catch! I will also try to add more tests.

>
> I'm not sure if the fake revision is better. Using 'state[rev] = rev' makes
> sense, but we'll have to check all places where state[rev] are used anyway.

I'm not sure which I prefer either, so I'll just pick the 'state[rev]
= rev' version for v2, but let me know if you change you mind.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: [PATCH 2 of 3] rebase: allow rebase even if some revisions need no rebase (BC) (issue5422)

2017-05-05 Thread Yuya Nishihara
On Thu, 04 May 2017 13:20:11 -0700, Martin von Zweigbergk via Mercurial-devel 
wrote:
> # HG changeset patch
> # User Martin von Zweigbergk 
> # Date 1489219466 28800
> #  Sat Mar 11 00:04:26 2017 -0800
> # Node ID 2765672140ea50f5587be486b25af10509a3d35b
> # Parent  5af88edb7a0bbafad999a2cef8968efbfd64becf
> rebase: allow rebase even if some revisions need no rebase (BC) (issue5422)
> 
> This allows you to do e.g. "hg rebase -d @ -r 'draft()'" even if some
> drafts are already based off of @. You'd still need to exclude
> obsolete and troubled revisions, though. We will deal with those cases
> later.
> 
> Implemented by treating state[rev]==rev as "no need to rebase". I
> considered adding another fake revision number like revdone=-6. That
> would make the code clearer in a few places, but would add extra code
> in other places.

Perhaps updatebookmarks() will need a guard to not flag
tr.hookargs['bookmark_moved'] by null move.

I'm not sure if the fake revision is better. Using 'state[rev] = rev' makes
sense, but we'll have to check all places where state[rev] are used anyway.
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


[PATCH 2 of 3] rebase: allow rebase even if some revisions need no rebase (BC) (issue5422)

2017-05-04 Thread Martin von Zweigbergk via Mercurial-devel
# HG changeset patch
# User Martin von Zweigbergk 
# Date 1489219466 28800
#  Sat Mar 11 00:04:26 2017 -0800
# Node ID 2765672140ea50f5587be486b25af10509a3d35b
# Parent  5af88edb7a0bbafad999a2cef8968efbfd64becf
rebase: allow rebase even if some revisions need no rebase (BC) (issue5422)

This allows you to do e.g. "hg rebase -d @ -r 'draft()'" even if some
drafts are already based off of @. You'd still need to exclude
obsolete and troubled revisions, though. We will deal with those cases
later.

Implemented by treating state[rev]==rev as "no need to rebase". I
considered adding another fake revision number like revdone=-6. That
would make the code clearer in a few places, but would add extra code
in other places.

diff --git a/hgext/rebase.py b/hgext/rebase.py
--- a/hgext/rebase.py
+++ b/hgext/rebase.py
@@ -384,7 +384,9 @@
 names = repo.nodetags(ctx.node()) + repo.nodebookmarks(ctx.node())
 if names:
 desc += ' (%s)' % ' '.join(names)
-if self.state[rev] == revtodo:
+if self.state[rev] == rev:
+ui.status(_('already rebased %s\n') % desc)
+elif self.state[rev] == revtodo:
 pos += 1
 ui.status(_('rebasing %s\n') % desc)
 ui.progress(_("rebasing"), pos, ("%d:%s" % (rev, ctx)),
@@ -1248,6 +1250,7 @@
 roots.sort()
 state = dict.fromkeys(rebaseset, revtodo)
 detachset = set()
+emptyrebase = True
 for root in roots:
 commonbase = root.ancestor(dest)
 if commonbase == root:
@@ -1260,9 +1263,13 @@
 else:
 samebranch = root.branch() == dest.branch()
 if not collapse and samebranch and root in dest.children():
+# mark the revision as done by setting its new revision
+# equal to its old (current) revisions
+state[root.rev()] = root.rev()
 repo.ui.debug('source is a child of destination\n')
-return None
+continue
 
+emptyrebase = False
 repo.ui.debug('rebase onto %s starting from %s\n' % (dest, root))
 # Rebase tries to turn  into a parent of  while
 # preserving the number of parents of rebased changesets:
@@ -1305,6 +1312,13 @@
 # ancestors of  not ancestors of 
 detachset.update(repo.changelog.findmissingrevs([commonbase.rev()],
 [root.rev()]))
+if emptyrebase:
+return None
+for rev in sorted(state):
+parents = [p for p in repo.changelog.parentrevs(rev) if p != nullrev]
+# if all parents of this revision are done, then so is this revision
+if parents and all((state.get(p) == p for p in parents)):
+state[rev] = rev
 for r in detachset:
 if r not in state:
 state[r] = nullmerge
@@ -1332,7 +1346,7 @@
 if obsolete.isenabled(repo, obsolete.createmarkersopt):
 markers = []
 for rev, newrev in sorted(state.items()):
-if newrev >= 0:
+if newrev >= 0 and newrev != rev:
 if rev in skipped:
 succs = ()
 elif collapsedas is not None:
@@ -1343,7 +1357,8 @@
 if markers:
 obsolete.createmarkers(repo, markers)
 else:
-rebased = [rev for rev in state if state[rev] > nullmerge]
+rebased = [rev for rev in state
+   if state[rev] > nullmerge and state[rev] != rev]
 if rebased:
 stripped = []
 for root in repo.set('roots(%ld)', rebased):
diff --git a/tests/test-rebase-base.t b/tests/test-rebase-base.t
--- a/tests/test-rebase-base.t
+++ b/tests/test-rebase-base.t
@@ -298,17 +298,30 @@
   |
   o  0: M0
   
-Mixed rebasable and non-rebasable bases (unresolved, issue5422):
+Mixed rebasable and non-rebasable bases (issue5422):
 
   $ rebasewithdag -b C+D -d B <<'EOS'
-  >   D
-  >  /
+  > E
+  > |
+  > D
+  > |
   > B C
   > |/
   > A
   > EOS
-  nothing to rebase
-  [1]
+  rebasing 2:dc0947a82db8 "C" (C)
+  already rebased 3:be0ef73c17ad "D" (D)
+  already rebased 4:a6c8ab8ac0c6 "E" (E tip)
+  o  4: C
+  |
+  | o  3: E
+  | |
+  | o  2: D
+  |/
+  o  1: B
+  |
+  o  0: A
+  
 
 Disconnected graph:
 
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel