-->

mercurial - see changes on the branch ignoring all

2020-07-06 06:03发布

问题:

I have a branch that was developed for a long period of time. During the development default branch was merged into that branch several times. I would like now to review all the changes done on that branch ignoring merges, to decide whether it is safe to merge it to default.

I tried

hg diff -r "branch('myBranch') - merge()"

but it still shows changes introduced by merges. Also tried following this How to show the diff specific to a named branch in mercurial but

hg diff -r "branch('myBranch') - branch('default')"

still bring changes introduced by merges.

回答1:

The problem with your commands is that when you perform a hg diff and pass it several changesets, you actually perform a diff between those changesets, hence you will see the merge result.

If you want to see just the changes made by the changesets then you could use export:

$ hg export -r "branch('mybranch') and not merge()"
// lists the changes made by each changeset

For easier reviewing, you can output these to files with names based on the revision/changeset id:

$ hg export -r "branch('mybranch') and not merge()" -o "%H.patch"

... creates a file for each non-merge changeset in mybranch, and outputs it to a file with the name "40-digit changeset id.patch". If you'd prefer the revision number (only useful for your local repository as revision id's are local), use "%R.patch".



回答2:

You have to read about revsets syntax

Your case

hg log -r "branch('myBranch') and ! merge()"



回答3:

The following uses the log command but with the --patch parameter it can show the modified lines as well:

hg log --branch my-branch --no-merges --patch

Short form:

hg log -Mpb my-branch


回答4:

That is a very good question, which I am trying to find good answer for a long time, and yet not found a good one. OK, one thing which 100% works is this:

hg status     # make sure that you don't have local changes
hg up <target_branch>
hg merge <your branch>
hg diff > merge.diff
hg up -C  # this one cleans the merge

I use this workflow all the time, but it does not satisfy me fully because it requires to switch branches (when I actually might not want to do actual merge right at this exact moment, I am just checking whats there)

I've been searching for ages for a good solution here, but so far there are none found. Tried those:

hg diff -r "branch('.') and ! merge()"  # this page
hg diff -r "default:branch('.') and not merge()"
hg diff -r "parents(branch(.)):branch('.') and not merge()"

This problem also discussed in:

  • Mercurial: how can I see only the changes introduced by a merge? which has good answer as: "so if you can define it unambiguously you might convince one of us Mercurial contributors that read SO to implement it."


回答5:

Try:

    hg diff -r"ancestor(default,my_branch)" -rmy_branch

If you haven't done any merges to the branch, then "ancestor" will pick up the original branch point. If you've done merges, then "ancestor" will pick up the latest merge point.

For example, on the graph below you'll get the diff between 520 and 519:

@  521 (default)
|
| o  520 (my_branch)
|/|
o |  519
| |
o |  518
| |
o |  517
| |
| o  516
| |
| o  515
| |
| o  514
|/
o  513

On the simpler graph below you'll get a diff between 516 and 513:

@  517 (default)
|
| o  516 (my_branch)
| |
| o  515
| |
| o  514
|/
o  513


回答6:

Per Matt Mackall what you probably want is:

hg diff -r mainbranchrev -r mywork

He writes:

You may be under the impression that "a changeset is a delta" or similar, and that this means that Mercurial can magically chain together a bunch of non-contiguous deltas to construct a bigger delta that's just your changes.

In fact, Mercurial is much simpler than that. A changeset is actually a snapshot: a complete set of complete files representing the state of the project at the time of commit. And a diff is simply the difference between these two snapshots. So when you do:

hg stat --rev '3408::3575 and user(mdiamond) and not merge()'

..status simply uses the first and last changesets of the resulting set to do its calculation.

When you do incremental merges on your development branch, you're inextricably tangling your work with mainline development, and Mercurial is not nearly smart enough to untangle it in the way you're asking. Your best bet is to compare the head of your work with the head of the main branch:

hg diff -r mainbranchrev -r mywork

..which will show all your work plus whatever merge fixups you had to do.