Commit Graph

351 Commits

Author SHA1 Message Date
Kostia Balytskyi
69abdd68e4 rebase: turn rebaseskipobsolete on by default
Consider the following use case. User has a set of commits he wants to rebase
onto some destination. Some of the commits in the set are already rebased
and their new versions are now among the ancestors of destination. Traditional
rebase behavior would make the rebase and effectively try to apply older
versions of these commits on top of newer versions, like this:

    a` --> b --> a`

(where both 'a`' and 'a``' are rebased versions of 'a')

This is not desired since 'b' might have made changes to 'a`' which can now
result in merge conflicts. We can avoid these merge conflicts since we know
that 'a``' is an older version of 'a`', so we don't even need to put it on top
of 'b'. Rebaseskipobsolete allows us to do exactly that.

Another undesired effect of a pure rebase is that now 'a`' and 'a``' are both
successors to 'a' which is a divergence. We don't want that and not rebasing
'a' the second time allows to avoid it.

This was not enabled by default initially because we wanted to have some more
experience with it. After months of painless usages in multiple places, we are
confident enough to turn it on my default.
2016-03-09 08:08:27 -08:00
FUJIWARA Katsunori
60e9ee2742 revset: replace extpredicate by revsetpredicate of registrar
This patch consists of changes below (these can't be applied
separately).

  - replace revset.extpredicate by registrar.revsetpredicate in
    extensions

  - remove setup() on an instance named as revsetpredicate in
    uisetup()/extsetup() of each extensions

    registrar.revsetpredicate doesn't have setup() API.

  - put new entry for revsetpredicate into extraloaders in dispatch

    This causes implicit loading predicate functions at loading
    extension.

    This loading mechanism requires that an extension has an instance
    named as revsetpredicate, and this is reason why
    largefiles/__init__.py is also changed in this patch.

Before this patch, test-revset.t tests that all decorated revset
predicates are loaded by explicit setup() at once ("all or nothing").

Now, test-revset.t tests that any revset predicate isn't loaded at
failure of loading extension, because loading itself is executed by
dispatch and it can't be controlled on extension side.
2016-03-08 23:04:53 +09:00
Pierre-Yves David
0f9abc9deb rebase: remove experimental option from 'rebase' config section
Changeset 9a4b77db854b introduced a guard against case where obsolete changesets
are included in the rebase in a way this will result in divergence (because
rebase create new successors for changeset which already have successors). In
the same go a 'rebase.allowdivergence' option was introduced to control that
behavior.

We rename this config option to 'experimental.allowdivergence' for multiple
reasons:

* First this behavior is attached to changeset evolution, a feature still
 experimental.

* Second, there was no 'rebase' section in config before we introduced this
  option. I would like to avoid proliferation of micro config section and
  therefore would like to avoid the creation of this new section just for an
  experimental feature.

* Third, this guard (warning the user about a history rewriting operation that
  will create divergence) will very likely be generalised to all history
  rewriting operations, making this not rebase specific.

* Finally, because this will likely be a general guard present a bit everywhere
  in the UI we'll likely end up with something better than a config option to
  control this behavior, so having the current config option living in
  experimental will allow us make it disappear in the future.

So we banish this config option back to the experimental section where it
belongs, killing the newly born 'rebase' config section in the process.
2016-02-27 18:02:12 +01:00
Pierre-Yves David
b305efc185 rebase: choose default destination the same way as 'hg merge' (BC)
This changeset finally make 'hg rebase' choose its default destination using the
same logic as 'hg merge'. The previous default was "tipmost changeset on the
current branch", the new default is "the other head if there is only one".  This
change has multiple consequences:

- Multiple tests which were not rebasing anything (rebasing from tipmost head)
  are now rebasing on the other "lower" branch. This is the expected new
  behavior.

- A test is now explicitly aborting when there is too many heads on the branch.
  This is the expected behavior.

- We gained a better detection of the "nothing to rebase" case while performing
  'hg pull --rebase' so the message have been updated. Making clearer than an
  update was performed and why. This is beneficial side-effect.

- Rebasing from an active bookmark will behave the same as 'hg merge' from a
  bookmark.
2016-02-14 13:25:59 +00:00
Kostia Balytskyi
2f0e2c8635 rebase: add potential divergent commit hashes to error message (issue5086) 2016-02-17 20:31:34 +00:00
liscju
6f96ec5bd7 rebase: adds storing collapse message (issue4792)
Before this patch collapse message wasn't stored so when
you ran into the merge conflict while rebasing, running
rebase --continue didn't remember the message and
always opened editor to fill commit message.

This patch adds saving collapse message in
.hg/last-message.txt and restoring it later
when needed.
2016-02-17 22:45:01 +01:00
Pierre-Yves David
c79ad1edd6 rebase: extract rebaseset and destination computation in a function
The whole rebase function is gargantuan and this computation is almost 100 lines
long.  We extract it in a dedicated function as it is independent from the rest
of the rebase code.

Having it in its own function will make it easier to rework the default
destination logic.
2016-02-09 23:49:55 +00:00
timeless
6afbee8966 rebase: suggest the correct tool to continue (not rebase)
Suggest committing (or whatever the current activity is), via
wrongtooltocontinue which uses howtocontinue.
2016-02-04 03:46:38 +00:00
Pierre-Yves David
93af21fe85 rebase: perform update through the 'update' command
The update logic have grow more and more complicated over time (eg bookmark
movement, new destination logic, warning on other head, etc). The rebase
extension was reimplementing its own basic version of update to be used by 'hg
pull --rebase'. We remove the custom code and use a combination of higher level
functions.

A test is added to check that the update is properly warning about other branch
heads.
2016-02-14 00:45:17 +00:00
Pierre-Yves David
0e26e4a437 rebase: 'hg pull --rebase' now update only if there was nothing to rebase
I recently discovered that 'hg pull --rebase' was also running an update. And it
was running it in all cases as long as the update would move the working copy
somewhere else...

This felt wrong and it actually is. This 'update' call is introduced in
8bea699a182c. In that commit the intent is very clear. The update should happen
only when there was nothing to rebase. The implementation did not check if a
rebase was performed because, at that time, rebase would always leave you on the
top most changeset. Being on that top most changeset result in a no-op update
and the step was skipped.

However 642dc7838453d changed rebase behavior to preserve the working copy
parent, so if we are not on a head at pull time, the code performs both a rebase
and an update.

This changeset introduce a test for this case and restore the intended behavior.

There are other issues with this custom update code but they will be addressed
in later changeset (eg: own destination logic, lack of heads warning).

I'm not super happy with the explicitly comparison 'rebase(...) == 1' but a
later series will have a cleaner way to handle it anyway (while making 'rebase'
pick its default destination like 'merge').
2016-02-13 16:59:32 +00:00
Matt Mackall
fd4d3ffdae merge with stable 2016-02-07 00:49:31 -06:00
timeless
2c0eb26137 rebase: update working directory when aborting (issue5084) 2016-02-05 01:56:46 +00:00
Siddharth Agarwal
69360ef583 rebase: don't preserve most extra fields
This backs out changeset 5293d4f88aef.

See the previous patches for why.
2016-02-03 09:23:31 -08:00
Siddharth Agarwal
d6d688266e rebase: backout changeset 9b23739c41de
This is a dependency for a future backout of 5293d4f88aef.

See the previous patches for why.
2016-02-03 09:24:47 -08:00
Siddharth Agarwal
82b2cbc2ee rebase: backout changeset 9fd8e3a61d6a
This is a dependency for a future backout of 5293d4f88aef.

See the previous patches for why.
2016-02-03 09:23:52 -08:00
Martijn Pieters
9c233476de rebase: better way to detect non-detaching revisions (issue5044)
Rather than look for the lowest revision, see if the rebase state is tracking
the parents of this revision. Otherwise we can't handle multiple revisions in
one rebase that includes a merge revision.

Fixes issue5044.
2016-02-01 15:41:43 +00:00
FUJIWARA Katsunori
4c1f8febc6 doc: use correct indentation for enumeration
This creates hg.1.html as expected.
2016-02-01 22:14:06 +09:00
FUJIWARA Katsunori
901d78d859 doc: prevent non-literal text block from being treated as literal one
This creates hg.1.html as expected.
2016-02-01 22:06:35 +09:00
timeless
872605f329 rebase: document that tool does not apply to deleted files 2016-02-04 23:29:32 +00:00
timeless
295a0b400c rebase: mention help merge-tools in help 2016-02-04 22:14:53 +00:00
timeless
09414997c3 rebase: restore help for rebase w/o args (issue5059)
Restoring documentation accidentally removed in 0feae227228d.
2016-01-22 20:32:47 +00:00
Bryan O'Sullivan
cc14be3d13 with: use context manager for transaction in rebase 2016-01-15 13:14:48 -08:00
Laurent Charignon
d72e8db6ef rebase: small refactoring to allow better extensibility from extensions
Inhibit, one of evolve's extension, would like to change the way rebase works
with obsolete changesets. During a rebase with inhibit, the inhibition of the
obsolescence markers should be lifted for the rebase.
With this small refactoring, inhibit and can wrap the _filterobsoleterevs
function to lift inhibition cleanly and at the same time this change makes
rebases' code more legible.
2016-01-14 11:50:28 -08:00
Laurent Charignon
0faf1a71c4 rebase: prevent creating divergence
Before this patch rebase would create divergence when you were rebasing obsolete
changesets on a destination not containing one of its successors.
This patch introduces rebase.allowdivergence to explicitly allow
divergence creation with rebase.
2016-01-12 13:43:41 -08:00
Laurent Charignon
83309d717a rebase: create a new variable to make the next patch more legible 2016-01-06 12:55:56 -08:00
Laurent Charignon
9d840a1d82 rebase: minor refactoring of _computeobsoletenotrebased
This patch is a refactoring of the code skipping obsolete changesets already
present in destination. It makes the following patches more legible.
Instead of passing all the revs to be rebased to _computeobsoletenotrebased,
we only pass the obsolete revisions of the rebaseset.
2016-01-06 12:55:56 -08:00
timeless
b2b9fb00e6 rebase: hook afterresolvedstates 2015-12-24 20:41:40 +00:00
FUJIWARA Katsunori
4d06739a86 revset: use delayregistrar to register predicate in extension easily
Previous patch introduced 'revset.predicate' decorator to register
revset predicate function easily.

But it shouldn't be used in extension directly, because it registers
specified function immediately. Registration itself can't be restored,
even if extension loading fails after that.

Therefore, registration should be delayed until 'uisetup()' or so.

This patch uses 'extpredicate' decorator derived from 'delayregistrar'
to register predicate in extension easily.

This patch also tests whether 'registrar.delayregistrar' avoids
function registration if 'setup()' isn't invoked on it, because
'extpredicate' is the first user of it.
2015-12-29 23:58:30 +09:00
Laurent Charignon
901d6a2088 rebase: better error message when rebased changes are all in destination
Before this patch, when rebasing a set of obsolete revisions that were plain
pruned or already present in the destination, we were displaying:

abort: no matching revisions

This was not very helpful to understand what was going on, instead we replace
the error message by:

abort: all requested changesets have equivalents or were marked as obsolete
(to force the rebase, set the config experimental.rebaseskipobsolete to False)
2015-12-29 15:32:12 -08:00
timeless
32124ab7e3 rebase: mention conflict in documentation instead of merge 2015-12-18 18:32:15 +00:00
timeless
a11d42f514 rebase: simplify documentation about heads 2015-12-18 18:31:45 +00:00
timeless
99e9c1b2d0 rebase: simplify documentation about --keep
Also include a warning about bookmarks
2015-12-18 18:22:03 +00:00
timeless
30016e92bc rebase: simplify documentation about selecting commits to rebase 2015-12-18 18:24:41 +00:00
timeless
16c4277abb rebase: simplify documentation about public commits
add reference to graft
2015-12-18 18:06:43 +00:00
Augie Fackler
0a19647501 merge: have merge.update use a matcher instead of partial fn
This is relatively rarely used functionality, but migrating this to a
matcher will make future work on narrow clones more feasible.
2015-12-14 18:54:03 -05:00
Yuya Nishihara
a588ddbc95 rebase: remove extra "if" from check of collapsing named branches 2015-12-05 23:50:13 +09:00
Yuya Nishihara
d1c7989b16 rebase: drop redundant functions to keep branch and graft source explicitly
All entries in extra dict are propagated by default since 5293d4f88aef.
2015-12-05 23:48:22 +09:00
Laurent Charignon
c7dc44265f rebase: only clear rebase status after the rebase transaction has completed
In 6e6b18aab8b2, I made the mistake of moving the step "clearing the status
after a rebase" to inside the rebase transaction.
This was wrong, since we don't want to clear the status (and the rebase state)
if something went wrong during the transaction: if something goes wrong we
want to keep the rebase state to be able to abort.
It broke rebase with evolve + inhibit.
2015-12-03 08:31:20 -08:00
Augie Fackler
840125d439 commands: inline definition of localrepo.parents() and drop the method (API)
localrepo.parents() has relatively few users, and most of those were
actually implicitly looking at the wctx, which is now made explicit
via repo[None].
2015-11-11 20:07:15 -05:00
Mike Edgar
8d4be9cc8f rebase: propagate extra dict from rebase source changeset
This corrects extra propagation for the rebase command and the shelve command.
2015-11-28 04:11:14 -05:00
Laurent Charignon
b6a3739c99 rebase: use bookmarks.recordchange instead of bookmarks.write
Before this patch we were using the old api bookmarks.write instead of
bookmarks.recordchange at the end of rebase operations.
We move clearstatus within the transaction to make it easier for extensions
that wrap transactions operations.
2015-11-20 14:06:31 -08:00
Laurent Charignon
bd889a16a7 rebase: indentation change to make the next patch more legible
We put the code to be indented in the next patch in a "if True:" block to make
it easier to review.
2015-11-20 11:36:05 -08:00
Laurent Charignon
4840174abf rebase: refactoring to avoid repetition of expression
This patch removes the repetition of "(revignored, revprecursor, revpruned)"
and replaces its occurences with the more legible "revskipped".
2015-11-18 15:58:06 -08:00
Laurent Charignon
550f1e2875 rebase: remove an unused todo
Since we handled skipping obsolete revs when it is relevant, this todo is no
longer useful. We replace the comment with two useful comments.
2015-11-18 16:06:00 -08:00
Laurent Charignon
e24d860326 rebase: don't rebase obsolete commits with no successor
This patch avoids unnecessary conflicts to resolve during rebase for the users
of changeset evolution.

This patch modifies rebase to skip obsolete commits with no successor.
It introduces a new rebase state 'revpruned' for these revisions that are
being skipped and a new message to inform the user of what is happening.
This feature is gated behind the config flag experimental.rebaseskipobsolete

When an obsolete commit is skipped, the output is:
note: not rebasing 7:360bbaa7d3ce "O", it has no successor
2015-11-18 13:44:29 -08:00
Matt Mackall
a20ef0162d merge with stable 2015-11-18 20:59:17 -06:00
liscju
ab17d6f05d rebase: add returning value from pullrebase function
So far pullrebase function has always returned None value, no matter
what orig function returned. This behaviour made impossible for
pull to change returned value from mercurial process (it has always
ended with 0 value by default). This patch makes pullrebase returning
with returned value from orig.
2015-11-15 22:18:48 +01:00
Mads Kiilerich
58681faacf rebase: fix wrong 'no changes to commit' when using --collapse
--collapse will do that rebase doesn't commit until the final commit. The lack
of a new commit would make it look like the rebase didn't contribute any
changes.

Instead, only warn about no commits when not using --collapse.
2015-10-19 16:29:35 +02:00
Mads Kiilerich
09567db49a spelling: trivial spell checking 2015-10-17 00:58:46 +02:00
FUJIWARA Katsunori
106983607a dirstate: make dirstate.write() callers pass transaction object to it
Now, 'dirstate.write(tr)' delays writing in-memory changes out, if a
transaction is running.

This may cause treating this revision as "the first bad one" at
bisecting in some cases using external hook process inside transaction
scope, because some external hooks and editor process are still
invoked without HG_PENDING and pending changes aren't visible to them.

'dirstate.write()' callers below in localrepo.py explicitly use 'None'
as 'tr', because they can assume that no transaction is running:

  - just before starting transaction
  - at closing transaction, or
  - at unlocking wlock
2015-10-17 01:15:34 +09:00