Commit Graph

64 Commits

Author SHA1 Message Date
Denis Laxalde
9efc7f05e3 transaction-summary: show the range of new revisions upon pull/unbundle (BC)
Upon pull or unbundle, we display a message with the range of new revisions
fetched. This revision range could readily be used after a pull to look out
what's new with 'hg log'. The algorithm takes care of filtering "obsolete"
revisions that might be present in transaction's "changes" but should not be
displayed to the end user.
2017-10-12 09:39:50 +02:00
Martin von Zweigbergk
307606e338 rebase: also include other namespaces in changeset description
This makes use of the generic method of listing bookmarks and tags, so
other extensions that add other namespaces will get their names added
too.

This does mean that bookmarks will come before tags, just like we
apparently decided to order them in the "hg log" output. It doesn't
seem like people would be parsing the rebase output anyway. We also
did 9461eb4ff93e (rebase: use _ctxdesc in one more place, 2017-08-29)
recently, so now seems like a good time.

Differential Revision: https://phab.mercurial-scm.org/D741
2017-09-19 22:06:26 -07:00
Martin von Zweigbergk
5d3d7b811c obsmarker: track operation by default
We added support for including the operation responsible for creating
the obsmarker in 44ba6434eaf4 (obsolete: add operation metadata to
rebase/amend/histedit obsmarkers, 2017-05-09). However, soon
thereafter, in 819cf35e629a (obsmarker: add an experimental flag
controlling "operation" recording, 2017-05-20), it was hidden behind a
config that was off by default. It seems unlikely that people will
manually turn it on, and obsmarkers/evolution as a whole is still
experimental anyway, so let's turn on the tracking by default.

Differential Revision: https://phab.mercurial-scm.org/D722
2017-09-15 10:42:49 -07:00
Jun Wu
9bfa16c243 rebase: use unfiltered repo when loading state
Before this patch, `rebase --abort` may fail to do the cleanup:

  $ hg rebase --abort
  rebase aborted (no revision is removed, only broken state is cleared)

The added test case makes sure `--abort` works in this case.

Differential Revision: https://phab.mercurial-scm.org/D643
2017-09-06 15:23:19 -07:00
Jun Wu
8b33f0c213 rebase: do not crash rebasing merge with a parent having hidden successor
The added test will crash with previous code.

Differential Revision: https://phab.mercurial-scm.org/D640
2017-09-06 12:40:00 -07:00
Saurabh Singh
d207bf8f86 cmdutil: remove the redundant commit during amend
There was an extra commit made during the amend operation to track the
changes to the working copy. However, this logic was written a long time back
and newer API's make this extra commit redundant. Therefore, I am removing the
extra commit. After this change, I noticed that

  - Execution time of the cmdutil.amend improved by over 40%.
  - Execution time of "hg commit --amend" improved by over 20%.

Test Plan:
I ensured that the all the hg tests passed after the change. I had
to fix a few tests which were aware of the extra commit made during the amend.

Differential Revision: https://phab.mercurial-scm.org/D636
2017-09-01 12:34:36 -07:00
Jun Wu
0bba32af82 rebase: use _ctxdesc in one more place
This simplifies the code.

Differential Revision: https://phab.mercurial-scm.org/D566
2017-08-29 17:51:54 -07:00
Jun Wu
4e250e8aa3 rebase: move working parent and bookmark for obsoleted revs (BC)
Previously, obsoleted revs with successors in destination are completely
ignored. That caused some inconvenience when working copy is obsoleted. Most
commands avoid working copy being obsoleted, but `hg pull` is an exception.

This patch makes rebase able to move bookmarks or working parent for those
obsoleted revs. It does so by keeping the obsoleted revs in `state` and
marking them as "skipped, rebased to desired destination" during run-time.

This reverts part of the behavior change of 80d53a39fbcc and D24.

Differential Revision: https://phab.mercurial-scm.org/D527
2017-08-27 02:47:47 -07:00
Jun Wu
13f8aae09c rebase: choose merge base without unwanted revisions
Previously, when there are 2 merge base candidates, we choose p1 blindly,
which may make the merge result to have "unwanted content". This patch makes
rebase smarter - choose a merge base that does not have "unwanted revs" if
possible. Since we don't really have a good solution when there are
"unwanted revs", abort in that case.

Differential Revision: https://phab.mercurial-scm.org/D340
2017-08-10 22:17:15 -07:00
Jun Wu
075caa84b6 rebase: remove messages for nullmerge and revignored (BC)
These states will be removed to make the code cleaner and more robust.
Remove their messages first to make review easier.

Differential Revision: https://phab.mercurial-scm.org/D25
2017-07-08 20:38:34 -07:00
Jun Wu
0f5023c94c rebase: remove revprecursor and revpruned states (BC)
Those states are no longer necessary for rebase to function properly. Remove
them to make the code cleaner.

Marked as BC because in a corner case where working parent is obsoleted, and
is skipped for rebase, we no longer move working parent after rebase
completes. That is better since if working parent is obsoleted, it should be
the user moving working parent back there (after a rebase) explicitly, in
that case, we shouldn't move working parent again.

Differential Revision: https://phab.mercurial-scm.org/D24
2017-07-08 20:38:34 -07:00
Jun Wu
d763d13686 rebase: move obsoleted not rebased messages earlier (BC)
A later patch will clean up those states. This patch moves the messages
earlier.

Marked as BC since the order of message has changed.

Differential Revision: https://phab.mercurial-scm.org/D23
2017-07-08 20:14:33 -07:00
Jun Wu
7a9096496d rebase: change "result would have 3 parent" error message (BC)
The old error message "cannot use revision REV as base, result would have 3
parents" is confusing - why use REV as base? why add a new parent?.

This patch changes it to "cannot move parent", which seems better.

Differential Revision: https://phab.mercurial-scm.org/D342
2017-08-12 21:01:06 -07:00
Jun Wu
87f820de49 rebase: rewrite core algorithm (issue5578) (issue5630)
"defineparents" is the core algorithm of rebase. The old code has too many
tech debts (like outdated comments, confusing assertions, etc) and is very
error-prone to be improved. This patch rewrites "defineparents" to make the
code easier to reason about, and solve a bunch of issues, including:

  - Assertion error: no base found (demonstrated by D212, issue5578)
  - Asymmetric result (demonstrated by D211, "F with one parent")
  - Wrong new parent (demonstrated by D262, "C':A'A'")
  - "revlog index out of range" (demonstrated by D262, issue5630)
  - "nothing to merge" (demonstrated by D262)

As a side effect, merge base decision has been made more solid - rebase now
prints out explicitly what could go wrong when it cannot find a unique
suitable merge base.

.. fix:: Issue 5578, Issue 5630

   Core rebase algorithm has been rewritten to be more robust.

Differential Revision: https://phab.mercurial-scm.org/D21
2017-08-10 21:30:31 -07:00
Boris Feld
cf0c39bfeb revset: remane divergent into contentdivergent
Don't touch divergent volatile set name, only the revset name. The volatile
set name will be updated in a later patch.

The renaming is done according to
https://www.mercurial-scm.org/wiki/CEDVocabulary.

Differential Revision: https://phab.mercurial-scm.org/D251
2017-08-03 14:01:51 +02:00
Boris Feld
c886c86073 test: update evolution config
evolution* config has been rewritten in stabilization* in the previous patch,
update tests file to use the new names.

Differential Revision: https://phab.mercurial-scm.org/D249
2017-08-04 18:41:16 +02:00
Boris Feld
aad1c3543a evolution: rename divergent to content-divergent
Rename divergent to content-divergent in all external user-facing output. Only
update user-facing output for the moment, variables names, templates keyword
and potentially configuration would be done in later series.

The renaming is done according to
https://www.mercurial-scm.org/wiki/CEDVocabulary.

Differential Revision: https://phab.mercurial-scm.org/D215
2017-08-01 17:58:20 +02:00
Martin von Zweigbergk
0b77fdd183 tests: demonstrate crash when trying to rebase merge without its parents
As the test case shows, when "hg rebase -d G -r 'B + D + F'" is run on
the following graph, we crash with traceback. It's reasonable to fail
because we can not easily produce a correct rebased F. The problem is
what diff to apply to either the rebased B or the rebased D. We could
potentially produce the result by e.g. applying the (F-D) diff to the
rebased B and then applying the reverse (E-D) diff on top, but that
could result in merge conflicts in each of those steps, which we don't
have a way of dealing with. So for now, let's just add a test case to
demonstrate that we crash (i.e. the AssertionError is clearly
incorrect since the user can run into it).

  F
 /|
C E
| |
B D G
 \|/
  A

Differential Revision: https://phab.mercurial-scm.org/D212
2017-07-14 14:30:55 -07:00
Martin von Zweigbergk
fa505ca948 tests: demonstrate broken rebase of merge with p1's successor in dest
The fix in c97497e78a9b (rebase: handle successor targets (issue5198),
2016-04-11) only fixed the case where p2's successor was in the
destination, and only when the successor was exactly the destination
(i.e. not when the successor was an ancestor of it). This patch adds a
test case for when p1's successor is in the destination. It adds
another one for when the successor is an ancestor of the
destination. To do that simply, it also rewrites the test case using
drawdag.

Differential Revision: https://phab.mercurial-scm.org/D211
2017-07-16 23:17:41 -07:00
Boris Feld
10f4bd6001 evolution: rename unstable to orphan
Rename unstable to orphan in all external user-facing output. Only update
user-facing output for the moment, variables names, templates keyword and
potentially configuration would be done in later series.

The renaming is done according to
https://www.mercurial-scm.org/wiki/CEDVocabulary.

Differential Revision: https://phab.mercurial-scm.org/D214
2017-08-01 17:53:48 +02:00
Boris Feld
b989852f8f debugobsolete: also report the number of obsoleted changesets
This seems useful to have the number of obsoleted changesets when calling
debugobsolete.
2017-07-16 02:33:14 +02:00
Jun Wu
936199e02d rebase: use scmutil.cleanupnodes (issue5606) (BC)
This patch migrates rebase to use scmutil.cleanupnodes API. It simplifies
the code and makes rebase code reusable inside a transaction.

This is a BC because the backup file is no longer strip-backup/*-backup.hg,
but strip-backup/*-rebase.hg. The latter looks more reasonable since the
directory name is "strip-backup" so there is no need to repeat "backup".

I think the backup file name change is probably fine as a BC, since we have
changed it before (2e51c9a7a08f) and didn't get complains. The end result
of this series will be a much more consistent and unified backup names:

  command  | old backup file suffix       | new backup file suffix
  -------------------------------------------------------------------
  amend    | amend-backup.hg              | amend.hg
  histedit | backup.hg (could be 2 files) | histedit.hg (single file)
  rebase   | backup.hg                    | rebase.hg
  strip    | backup.hg                    | backup.hg

(note: backup files are under .hg/strip-backup)

It also fixes issue5606 as a side effect because the new "delayedstrip" code
path will carefully examine nodes (safestriproots) to make sure orphaned
changesets won't get stripped by accident.

Some warning messages are changed to the new "warning: orphaned descendants
detected, not stripping HASHES", which provides more information about
exactly what changesets are left behind.

Another minor behavior change is when there is an obsoleted changeset with a
successor in the destination branch, bookmarks pointing to that obsoleted
changeset will not be moved. I have commented in test-rebase-obsolete.t
explaining why that is more desirable.
2017-07-07 18:51:46 -07:00
Boris Feld
389d0518ad test: prepare tests for removing date aliases
In the next patch, I'm gonna removing the global command aliases that force
the epoch date but some tests either fail or their output change after that.
Instead I'm copying the needed aliases in the test files that will otherwise
change.

Update test-rebase-obsolete.t because a revision hash is based on the epoch
date after a 'commit --amend' and the output will change after removing date
aliases.

Update test-subrepo-git.t as the git subrepo doesn't use traditional date
mechanisms. I'm not sure that updating the git subrepo to support default-date
make sense. Add the commit alias to the test in order for making it pass after
removing the date aliases globally.
2017-05-22 19:28:47 +02:00
Pierre-Yves David
1d69629fff obsmarker: add an experimental flag controlling "operation" recording
It seems better to introduce the experiment behind a flag for now as there are
multiple concerns around the feature:

 * Storing operation increase the size of obsolescence markers significantly
   (+10-20%).

 * It performs poorly when exchanging markers (cannot combine command names,
   command name might be unknown remotely, etc)
2017-05-20 03:10:23 +02:00
Durham Goode
77dcefda06 obsolete: add operation metadata to rebase/amend/histedit obsmarkers
By recording what operation created the obsmarker, we can show very intuitive
messages to the user in various UIs. For instance, log output could have
messages like "Amended as XXX" to show why a commit is old and has an 'x' on it.

     @  ac28e3  durham
    /   First commit
   |
   | o  d4afe7 durham
   | |  Second commit
   | |
   | x  8e9a5d (Amended as ac28e3)  durham
   |/   First commit
   |
2017-05-09 16:29:31 -07:00
Martin von Zweigbergk
df689070f8 rebase: unhide original working directory node as well (issue5219)
By including the working directory revision at the start of rebase in
the repo._rebaseset, we make sure it's not hidden when we update back
to it at the end of the rebase.

This feels like abusing the set a bit given its name (_rebaseset), but
I couldn't think of another name that's clearly better.
2017-03-10 23:07:20 -08:00
Martin von Zweigbergk
95e6286750 tests: demonstrate broken rebase from obsolete commit
This shows the bug I reported in issue 5219.
2017-02-01 09:18:44 -08:00
Denis Laxalde
5e3ca8d1ab summary: add evolution "troubles" information to summary output
Extend the "parent: " lines in summary with the list of evolution "troubles"
in parentheses, when the parent is troubled.
2017-01-06 14:35:22 +01:00
Xidorn Quan
a5b2da437e rebase: rebase changesets in topo order (issue5370) (BC)
There are two reasons that rebase should be done this way:
1. This would make rebasing faster because it would minimize the total
   number of files to be checked out in the process, as it don't need
   to switch back and forth between branches.
2. It makes resolving conflicts easier as user has a better context.

This commit changes the behavior in "Test multiple root handling" of
test-rebase-obsolete.t. It is an expected change which reflects the new
behavior that commits in a branch are grouped together when rebased.
2016-09-17 17:02:56 +10:00
Kostia Balytskyi
305d79a43c rebase: do not abort if all changesets have equivalents in the destination 2016-06-17 16:59:08 +01:00
timeless
95228c418a rebase: handle successor targets (issue5198)
When a parent has a successor (indicated by revprecursor in state),
we need to use it.
2016-04-11 21:33:07 +00:00
Laurent Charignon
374c190d53 rebase: fix crash when rebase aborts while rebasing obsolete revisions
Before this patch, rebase --continue would crash when trying to resume a rebase
of obsolete revisions whose successors were in the destination.
This patch adds logic to recompute the mapping when rebase is resumed. This
patch also adds a test that showcased the crash before the code change.
2016-03-29 11:50:41 -07:00
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
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
Kostia Balytskyi
2f0e2c8635 rebase: add potential divergent commit hashes to error message (issue5086) 2016-02-17 20:31:34 +00:00
Siddharth Agarwal
08f24f1f67 graft: don't preserve most extra fields
This backs out changeset 9aa13e9feec8.

See the previous patch for why we're doing this.
2016-02-03 09:06:52 -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
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
Mike Edgar
35c5515acc graft: copy extra (except branch) when copying changesets 2015-11-28 04:11:38 -05: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
Laurent Charignon
3bbe7ac5d7 rebase: fix a typo in test-rebase-obsolete
We had left a lonely single quote where it shouldn't be!
2015-11-18 13:46:42 -08:00
Matt Harbison
09960eddd1 rebase: preserve the 'intermediate-source' attribute of grafts
Preserving the 'source' attribute of grafts started with 091a7dd3c7d0, which
predates the introduction of 'intermediate-source' in 7fbf0ef28408 by a year and
a half.  It looks like not preserving this was an oversight.

On a related note, notice how the source value of 32af76 is no longer visible in
the graph above this test.  Is it reasonable to import the sha1 translation from
evolve.py:relocate() into scmutil or similar, and use that to fixup these
attributes as well as the commit message?  (I realize that evolve is still
experimental, but I don't see a way to do this from the evolve extension.)
2015-11-08 17:56:48 -05: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
Pierre-Yves David
d7f7b508bd rebase: properly handle chains of markers with missing nodes
As obsolescence markers can contains unknown nodes and 'allsuccessors' returns
them, we have to protect again that when looking for successors of the rebase
set in the destination.

Test have been expanded to catch that.
2015-10-15 00:32:20 +01:00
Laurent Charignon
1cb3086e23 rebase: don't rebase obsolete commit whose successor is already rebased
This patch avoids unnecessary conflicts to resolve during rebase for the users
of changeset evolution.

This patch modifies rebase to skip obsolete commits if they are being rebased on
their successors.
It introduces a new rebase state 'revprecursor' 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:
not rebasing 14:9ad579b4a5de "I", already in destination as 17:fc37a630c901 "K"
2015-09-14 17:31:48 -07:00
Pierre-Yves David
3e6abb6494 rebase: ensure rebase revision remains visible (issue4504)
Before this changeset rebase was getting very confused if any revision in the
rebase set became hidden. This was fairly easy to achieve if a rebased revision
was made visible by the working copy location. The rebase process would update
somewhere else and the revision would become hidden.

To work around this issue, we ensure rebased revisions remain visible for the
whole process.

This is a simple change suitable for stable. More subtle usage of unfiltered
repository in rebase may solve this issue more cleanly.
2015-01-27 12:33:56 +00:00
Mads Kiilerich
046399e6dc rebase: show warning when rebase creates no changes to commit
Similar to graft:
  note: rebase of 6:eea13746799a created no changes to commit
2014-12-10 06:20:35 +01:00
Mads Kiilerich
0419ad5c23 rebase: show more useful status information while rebasing
Show status messages while rebasing, similar to what graft do:
  rebasing 12:2647734878ef "fork" (tip)

This gives more context for the user when resolving conflicts.
2014-12-09 03:45:26 +01:00
Mads Kiilerich
d138d31de7 graft: show more useful status information while grafting
Show status messages with first line of commit description and names, like
  grafting 12:2647734878ef "fork" (tip)

This gives more context for the user when resolving conflicts.
2014-12-09 03:38:23 +01:00
Durham Goode
312ed291dd obsolete: update tests to use obsolete options
The obsolete._enabled flag has become a config option. This updates all but one
of the tests to use the minimal number of flags necessary for them to pass.  For
most tests this is just 'createmarkers', for a couple tests it's
'allowunstable', and for even fewer it's 'exchange'.
2014-10-14 13:34:25 -07:00