Commit Graph

174 Commits

Author SHA1 Message Date
Kevin Bullock
6246126341 rebase: mention phases in the help
Mention that Mercurial helps you not do what you've just been warned not
to do, with a reference to the 'phases' help topic (not the 'phase'
command help).

Thanks to Pierre-Yves David <pierre-yves.david@ens-lyon.org> for
motivating this change and Wagner Bruna
<wagner.bruna+mercurial@gmail.com> for advising on how to do it in an
i18n-friendly way.
2013-01-31 20:01:26 -06:00
Siddharth Agarwal
eb2c7139a5 rebase: delete divergent bookmarks on destination (issue3685)
Similar to merge, divergent bookmarks are only deleted when the bookmark is on
the destination parent.
2013-01-30 16:08:32 -08:00
Siddharth Agarwal
dd1e6af7ac rebase: remove bogus nullmerge check in updatebookmarks
nstate[v] is a node, not an int, and the nullmerge check was done while
building nstate anyway.
2013-01-30 17:49:54 -08:00
Pierre-Yves David
b3f0e4c581 rebase: properly handle unrebased revision between rebased one
With rebase taking multiple roots it is possible to have revision in the "rebase
domain" not rebased themself. We do not want rebased revision above them to be
detached. We want such revision to be rebased on the nearest rebased ancestors.
This allows to preserve the topology of the rebase set as much a possible

To achieve this we introduce a new state `revignored` which informs
`defineparents` of the situation.

The test in `test-rebase-obsolete.t` was actually wrote and his now fixed.
2013-01-18 23:41:48 +01:00
Pierre-Yves David
5820a2b31c rebase: lose the comparison to nullmerge
For a proper behavior of the `--rev` revision we will need another possible
state for revision ignored by rebase. We alter the comparison to `nullmerge`
to match this future lower state too.
2013-01-18 23:21:32 +01:00
Pierre-Yves David
b24e3849df rebase: do not invent successor to skipped changeset
When rebase results in an empty a changeset it is "skipped" and no related
changeset is created at all. When we added obsolescence support to rebase (in
cee0a253a56c) it seemed a good idea to use its parent successor as the
successors for such dropped changesets. (see old version of the altered test).
This option was chosen because it seems a good way to hint about were the
dropped changeset "intended" to be. Such hint would have been used by automatic
evolution mechanism to rebase potential unstable children.

However, field testing of this version are not conclusive. It very often leads
to the creation of (totally unfounded) evolution divergence. This changeset
changes this behavior and mark skipped changesets as pruned (obsolete without
successors). This prevents the issue and seems semantically better probably a
win for obsolescence reading tool.

See example bellow for details:

User Babar has five changesets of interest:
- O, its current base of development.
- U, the new upstream
- A and C, some development changesets
- B another development changeset independent from A

    O - A - B - C
      \
        U

Babar decides that B is more critical than the A and C and rebase it first

  $ hg rebase --rev B --dest U

B is now obsolete (in lower case bellow). Rebase result, B', is its
successors.(note, C is unstable)

    O - A - b - C
      \
        U - B'

Babar is now done with B', and want to rebase the rest of its history:

  $ hg rebase --source A --dest B'


hg rebase process A, B and C. B is skipped as all its changes are already contained
in B'.

    O - U - B' - A' - C'

Babar have the expected result graph wise, obsolescence marker are as follow:

    B -> B' (from first rebase)
    A -> A' (from second rebase)
    C -> C' (from second rebase)
    B -> ?? (from second rebase)

Before this changeset, the last marker is `B -> A'`. This cause two issues:

- This is semantically wrong. B have nothing to do with A'
- B has now two successors sets: (B',) and (A',). We detect a divergent
  rewriting. The B' and A' are reported as "divergent" to Babar, confusion
  ensues. In addition such divergent situation (divergent changeset are children
  to each other) is tricky to solve.

With this changeset the last marker is `B -> ø`:

- This is semantically better.
- B has a single successors set (B',)

This scenario is added to the tests suite.
2013-01-18 14:15:32 +01:00
Pierre-Yves David
7e632ae757 rebase: support multiple roots for rebaseset
We have all the necessary mechanism to rebase a set with multiple roots, we only
needed a proper handling of this case we preparing and concluding the rebase.
This changeset des that.

Rebase set with multiple root allows some awesome usage of rebase like:

- rebase all your draft on lastest upstream

  hg rebase --dest @ --rev 'draft()'

- exclusion of specific changeset during rebase

  hg rebase --rev '42:: - author(Babar)'

-  rebase a set of revision were multiple roots are later merged

  hg rebase --rev '(18+42)::'
2013-01-17 00:35:01 +01:00
Mads Kiilerich
dd30593de7 refactoring: use unlinkpath with ignoremissing 2013-01-15 23:30:10 +01:00
Pierre-Yves David
d23fadbe9a clfilter: drop unnecessary explicit filtering on rebase
Hidden changeset filtering is now done at repo level. The rebaseset
computation will not include any (unless you add --hidden).
2012-12-04 14:58:19 +01:00
Pierre-Yves David
5fe6f9df7f rebase: allow non-head rebase-set when obsolete is enabled
Obsolescence markers can represent this situation just fine. Rebased
revisions are marked as precursors of the ones create by
rebase. Unrebased descendants becomes "unstable".

If obsolescence is not enabled we keep the current behavior of
aborting. This new behavior only applies when obsolete is
enabled and is subject to future discussion and changes.
2012-12-31 17:45:52 -06:00
Siddharth Agarwal
e01899aaca rebase: use lazy ancestor membership testing
For a repository with over 400,000 commits, rebasing one revision near tip,
this avoids one walk up the DAG, speeding the operation up by around 0.8
seconds.
2012-12-17 20:51:21 -08:00
Augie Fackler
99efe2586b Merge with stable. 2012-11-29 11:44:22 -06:00
Pierre-Yves David
39909ce228 rebase: fix pull --rev options clashing with --rebase (issue3619)
Rebase also have a plain `--rev` option used to select the rebase set (as
`--base` or `--source` would). But the content of the --rev option was intended
for the remote repo and is irrelevant for the local rebase operation. We expect
`hg pull --rebase` to stick with the default behavior here:

    hg rebase --base . --dest tip(branch(.))

The `rev` option is dropped from the option passed to rebase.
2012-11-29 16:37:15 +01:00
Siddharth Agarwal
765063c1b4 rebase: use revlog.findmissingrevs to compute detach set 2012-11-27 16:24:21 -08:00
Augie Fackler
9766845689 bookmarks: introduce a bmstore to manage bookmark persistence
Bookmarks persistence still showed a fair amount of its legacy as a
monkeypatching extension. This encapsulates all bookmarks
serialization and parsing in a single class, and offers a single
location where other bookmarks storage engines can be substituted
in. As a result, many files no longer import the bookmarks module,
which strikes me as an encapsulation win.

This doesn't do anything to the current bookmark state yet, but I'm
hoping put that in the bmstore class as well.
2012-11-07 16:21:39 -06:00
Pierre-Yves David
7a06ce262e rebase: ensure rebase does not revive extinct revision
Here, we exclude hidden changesets from a rebase operation. If we
don't, a rewritten version of the hidden changesets will be created
by rebase. Those rewritten versions won't be hidden and will likely
conflict with other rewriting or revive pruned changeset. Moreover,
rewriting hidden revisions will surprise the user.

This change would not be necessary if changelog filtering were
already in core. But it's fairly cheap and helps to increase the
test-suite for such filtering.

Once changelog level filtering is added, hidden changes will be
automatically excluded or included according to the global --hidden
flags. Plain ignoring them is good enough for now.
2012-09-18 23:32:42 +02:00
Pierre-Yves David
6fa51bbd6d rebase: remove useless list around repo.revs
As repo.revs already returns a list.
2012-09-18 23:29:05 +02:00
Pierre-Yves David
4e2a2d8f61 rebase: properly handle --collapse when creating obsolescence marker
In collapse mode, that content of state is not suitable to compute obsolescence
markers. We explicitly pass the resulting revision instead and use it as the
successors for all elements of the rebased set.
2012-09-18 23:42:27 +02:00
Pierre-Yves David
be6378e49d rebase: allow creation obsolescence relation instead of stripping
When obsolescence feature is enabled we now create markers from the rebased
set to the resulting set instead of stripping. The "state" mapping built by
rebase holds all necessary data.

Changesets "deleted" by the rebase are marked "succeeded" by the changeset they
would be rebased one. That the best guess of "successors" we have. Getting a
successors as meaningful as possible is important for automatic resolution of
obsolescence troubles. In other word, emptied changeset will looks collapsed
with their former parents. (see "empty changeset" section of the test if you are
still confused)
2012-09-18 23:13:31 +02:00
Pierre-Yves David
f0bddab386 rebase: extract final changesets cleanup logic in a dedicated function
At the end of the rebase, rebased changesets are currently stripped. This
behavior will be eventually dropped in favor of obsolescence marker creation.

The main rebase function is already big and branchy enough. This changeset move
the clean-up logic in a dedicated function before we make it more complex.
2012-09-18 22:58:12 +02:00
Patrick Mezard
7584dc0071 rebase: remove second broken synopsis line (issue3172)
Displaying multiple synopsis in online help has been broken since Matt
RST refactoring, around 54e90eb99cfa. Rebase help is apparently the only
one using this trick, just drop the second synopsis and assume people
will understand as with graft help.
2012-07-31 18:18:26 +02:00
Matt Mackall
61aa1f42b8 merge with stable 2012-06-29 00:40:52 -05:00
David Schleimer
de4c701f51 bookmarks: correctly update current bookmarks on rebase (issue2277)
When you rebased with a currently active bookmark, that bookmark would
always point at the new tip, regardless of what revision it pointed at
before the rebase.

All bookmarks will now point at the equivalent post-rebase commit.
However, the currently active bookmark will cease to be active unless
it points at the new tip post-rebase.  Rebase will always leave the
new tip as the working copy parent, which is incompatible with having
an active bookmark that points at some other revision.  The common
case should be that the active bookmark will point at the new tip
post-rebase.
2012-06-22 11:40:31 -07:00
Matt Mackall
36aa7282e4 merge with crew 2012-06-21 17:37:02 -05:00
Martin Geisler
d22efb8f52 merge with stable 2012-06-21 15:10:01 +02:00
Dan Villiom Podlaski Christiansen
4bc99faa5e rebase: improve error message on improper phases
The previous error message had two issues: The first issue was that it
wasn't, in fact, an error but a warning, even though it described a
fatal error condition preventing the successful completion of the
command. The second was that it didn't mention the immutable
changesets, leaving the user guessing at the true cause of the error.

The main downside to this change is that we now get an 'abort: can't
abort...' message which technically contradicts itself. In this case,
I blame that on the two uses we have for the word; if it weren't for
backwards compatibility, we could make util.Abort print out 'error:
<whatever>'.
2012-06-18 11:16:24 +02:00
Bryan O'Sullivan
141bd09daa revlog: descendants(*revs) becomes descendants(revs) (API)
Once again making the API more rational, as with ancestors.
2012-06-01 12:45:16 -07:00
Bryan O'Sullivan
6ba97b40c1 revlog: ancestors(*revs) becomes ancestors(revs) (API)
Accepting a variable number of arguments as the old API did is
deeply ugly, particularly as it means the API can't be extended
with new arguments.  Partly as a result, we have at least three
different implementations of the same ancestors algorithm (!?).

Most callers were forced to call ancestors(*somelist), adding to
both inefficiency and ugliness.
2012-06-01 12:37:18 -07:00
Pierre-Yves David
aa99ac6df5 rebase: do not add second parent to rebased changeset (drop detach option) (BC)
Rebase now behaves as if --detach was always passed. Non-merges are
rebased as non-merges, regardless of their parent being an ancestor of
the destination. Merges will usually be rebased as merges unless both of
their parents are ancestors of the destination, or one of their parents
is pruned when rebased.

This only alters the behavior of rebase when using the --source/--rev
options. --detach option is deprecated.

All test changes were carefully validated.
2012-06-20 20:08:57 +02:00
Augie Fackler
96d44b39f7 hgext: mark all first-party extensions as such 2012-05-15 14:37:49 -05:00
Patrick Mezard
d99bfab018 rebase: allow collapsing branches in place (issue3111)
We allow rebase plus collapse, but not collapse only? I imagine people would
rebase first then collapse once they are sure the rebase is correct and it is
the right time to finish it.

I was reluctant to submit this patch for reasons detailed below, but it
improves rebase --collapse usefulness so much it is worth the ugliness.

The fix is ugly because we should be fixing the collapse code path rather than
the merge. Collapsing by merging changesets repeatedly is inefficient compared
to what commit --amend does: commitctx(), update, strip. The problem with the
latter is, to generate the synthetic changeset, copy records are gathered with
copies.pathcopies(). copies.pathcopies() is still implemented with merging in
mind and discards information like file replaced by the copy of another,
criss-cross copies and so forth. I believe this information should not be lost,
even if we decide not to interpret it fully later, at merge time.

The second issue with improving rebase --collapse is the option should not be
there to begin with. Rebasing and collapsing are orthogonal and a dedicated
command would probably enable a better, simpler ui. We should avoid advertizing
rebase --collapse, but with this fix it becomes the best shipped solution to
collapse changesets.

And for the record, available techniques are:
- revert + commit + strip: lose copies
- mq/qfold: repeated patching() (mostly correct, fragile)
- rebase: repeated merges (mostly correct, fragile)
- collapse: revert + tag rewriting wizardry, lose copies
- histedit: repeated patching() (mostly correct, fragile)
- amend: copies.pathcopies() + commitctx() + update + strip
2012-05-03 15:14:58 +02:00
Patrick Mezard
47c2d10d02 rebase: make --dest understand revsets 2012-05-01 10:14:35 +02:00
Patrick Mezard
6780f50e59 rebase: add missing EOL to debug strings 2012-05-02 11:43:12 +02:00
Patrick Mezard
2c65c226cf localrepo: add setparents() to adjust dirstate copies (issue3407)
The fix introduced in 3509b9cf8f86 was only partially successful. It is correct
to turn dirstate 'm' merge records into normal/dirty ones but copy records are
lost in the process. To adjust them as well, we need to look in the first
parent manifest to know which files were added and preserve only related
records. But the dirstate does not have access to changesets, the logic has to
moved at another level, in localrepo.
2012-04-29 22:25:55 +02:00
Patrick Mezard
8cd56689d6 rebase: preserve mq series order, guarded patches (issue2849)
The previous code was rebasing an applied series like:

  patch1 +guarded
  patch2
  patch3 +guarded
  patch4
  patch5 +guarded

into:

  patch2
  patch4
  patch1 +guarded
  patch3 +guarded
  patch5 +guarded

Reported by Lars Westerhoff <lars.westerhoff@newtec.eu>

Also rename mq.series_dirty into mq.seriesdirty, missed by 9bcf8cbb1bcf, and
without effect since mq.qimport() was setting it already.
2012-04-25 17:04:18 +02:00
Matt Mackall
352b46cf1d rebase: properly calculate descendant set when aborting (issue3332)
Checking for descendants of target being public was also wrong.
2012-03-22 17:47:00 -05:00
Matt Mackall
39e25f975a rebase: move bookmarks as needed with pull --rebase (issue3285) 2012-03-04 17:12:12 -06:00
Wagner Bruna
32e015e05a rebase: drop uppercase in abort message 2012-01-20 12:04:45 -02:00
Matt Mackall
87405b610a rebase: only advance phase on successful commit 2012-01-18 18:14:55 -06:00
Alain Leufroy
fd923bd6e3 rebase: fix phases movement
Rebase now try to keep the phases of source changesets.
2012-01-17 09:12:14 +01:00
Mads Kiilerich
5c283321a0 rebase: write series file without removed mq patches
Rebase will remove empty changesets and will also completely remove the mq
patch file for rebased empty patches.

Starting with f64ab644b39f (1.9) it would preserve guards by writing the old
series file back. That would however also reintroduce removed patch files in
the series file and the inconsistency would make qpop + qpush fail.

This patch backs out most of f64ab644b39f and makes sure guards are preserved
without reintroducing removed patches.
2012-01-17 02:55:55 +01:00
Mads Kiilerich
afbab5a2e4 rebase: take locks in the right order
repo.lock was taken before repo.wlock - that could in principle cause a deadlock.
2012-01-13 01:19:07 +01:00
Matt Mackall
0fb748c56c merge with stable 2012-01-09 20:16:57 -06:00
Steven Brown
51a1bd2f20 rebase: reinstate old-style rev spec support for the source and base (issue3181)
As of 1ffaca626da1 (first released as part of Mercurial 2.0), the rebase command
accepted ONLY revsets for the source and base arguments and no longer accepted
old-style revision specifications. As a result, some revision names were no
longer recognised, e.g.

hg rebase --base br-anch
abort: unknown revision 'br'!

These arguments are now interpreted first as old-style revision specifications,
then as revsets when no matching revision is found. This restores backwards
compatibility with releases prior to 2.0.
2012-01-08 23:09:35 +08:00
Matt Mackall
dea868ff61 cmdutil: simplify duplicatecopies 2012-01-05 20:35:10 -06:00
Pierre-Yves David
7e4f710bf6 phases: prevent rebase to rebase immutable changeset. 2011-12-27 00:11:22 +01:00
Pierre-Yves David
84e54fd93c rebase: add a "D" short option for detach
Detach is usually what I want when I use --source or (in particular) --rev.
Having a shorter option make it less an hassle to use it.
2011-12-27 21:12:09 +01:00
Pierre-Yves David
30c8f3e74a rebase: allow --detach when --rev is used
--rev is only a more specific --source and there is no reason to refuse to use
detach with it.
2011-12-27 20:45:46 +01:00
Stefano Tortarolo
b157d6deb9 rebase: ensure target is not taken as external (issue3085)
This could happen in specific situations in which 'target'
was selected as external and used for p1 _and_ p2.
2011-11-08 17:09:48 +01:00
Stefano Tortarolo
822926675c rebase: treat nullmerge as a special case in rebasestate (issue3046)
When storing/restoring a nullmerge (-2), a 'standard' conversion was made
and an existing changeset was wrongly used.
Nullmerge should instead be treated as a special case.
2011-11-06 23:35:33 +01:00