Reputation: 6121
git log --first-parent
omits all but the first parent of merge commits.
Example:
$ git log --oneline --graph
* 087f5ed Master C
* 36c50a2 Merge branch 'feature'
|\
| * 98c89df Feature B
| * 89b3a7b Feature A
* | 9a95133 Master B
|/
* 766c9b0 Master A
$ git log --oneline --graph --first-parent
* 087f5ed Master C
* 36c50a2 Merge branch 'feature'
* 9a95133 Master B
* 766c9b0 Master A
Is there a Mercurial equivalent?
Upvotes: 3
Views: 2395
Reputation: 5047
hg log -r '_firstancestors(...)'
There is a direct equivalent: the hidden revset _firstancestors
follows the first-parent (p1) side of each merge. In Mercurial, like in Git, the first parent is the commit that was checked-out when hg merge [second parent]
was called.
hg log -r '_firstancestors(myfeature)'
'hidden' means that it starts with an underscore, and is not listed in the help etc., but can still be used if you know it exists. I don't know why it is hidden.
This revset alias lists all commits on a feature branch while ignoring all the ancestry whenever master
is merged into the branch to bring it up-to-date. (The shop I work prefers merging over rebasing).
[revsetalias]
feature($1) = _firstancestors($1) and not _firstancestors(master)
[alias]
f = log -r "feature($(echo $HG_ARGS| sed 's/^f //'))"
Example usage (uses my own logging template):
$ hg f myfeature
o 423 myfeature default/myfeature -- Esteis -- 2016-07-12 -- 123abc
| this
o 422 -- Esteis -- 2016-07-12 -- 123def
|\ merge master into myfeature
o ~ 421 -- Esteis -- 2016-07-12 -- 456abc
| that
o 420 -- Esteis -- 2016-07-12 -- 789def
| and the other
Upvotes: 4
Reputation: 97280
>hg glog -r 410:426 --template "{rev} - {desc|firstline|fill68}\n"
o 426 - Merge test fixes for dulwich changes and output changes.
|\
| o 425 - Merge incoming fix.
| |\
| | o 424 - getremotechanges: fix incoming support
| | |
o | | 423 - overlay: stop using deprecated tree.entries() method
| | |
| o | 422 - Fix all-version-tests.
| | |
o | | 421 - Test output format tweaks for test-outgoing.
| | |
o | | 420 - test-incoming: fixes for hg 1.7
| | |
| o | 419 - Merge fix for `hg out` failing on empty repo.
| |\ \
| | o | 418 - In some situations where a reference is being used but does not
| | | | exist in _map_git or _map_hg, silently skip the reference rather
| | | | than throwing an error. This allows hg outgoing to work on
| | | | repositories which do not contain any revisions at all.
| o | | 417 - only want heads and tags
| |/ /
| o | 416 - test-url-parsing: update expecations missed by edaadbd99074
| | |
| o | 415 - to be recognized port number in path to repository
| | |
| o | 414 - Unbreak outgoing to non-git repos with hg pre-1.9
| | |
| o | 413 - test fixes for progress cleanup
| |/
| o 412 - Fix mercurial issue2855
| |
| o 411 - Convert dulwich progress into mercurial ui.progress
|/
o 410 - test-incoming: only run on hg 1.7.x and newer
Instead of extremely degenerated case from gist, I use part of real repository DAG (hg-git repository). I hope, the selection is sufficiently indicative for the problem being solved.
Needed revset (in plain English) will be
"Range A:B without second parent and it's ancestors for mergesets"
In revset functional language (TBT!)
-r "410::426 - (p2(merge()) or ancestors(p2(merge())))"
In case of the full range of changesets as source more readable form will be something like
hg log -r "!(p2(merge()) or ancestors(p2(merge())))"
Edit 1
I tested revset, rethought about methodology (instead of excluding I want only add needed to empty set), nearest iteration for my use-case for now (have bugs, can't find solution) is
(p1(ancestors(p1(426))) or p1(426) or 426) and 410::426
which (still) include some unwanted revisions
Upvotes: 1
Reputation: 6121
hg log --follow-first
seems to do roughly the same thing, with a few provisions:
It's deprecated (with no explanation that I can find).
I can't figure out how to get it to display anything other than just the straight-line history from the current changeset (e.g. display history following the first parent from two divergent heads (the equivalent of git log --first-parent branch-a branch-b
), although this may be just because of my lack of knowledge of Mercurial.
It shows empty branch lines with hg log -G
:
$ hg log -G --template '{node|short} {desc|firstline}'
@ 51b90923fc9d Master C
|
o bb51d979fd68 Merge branch 'feature'
|\
| o a9ca2597ebbc Feature B
| |
| o d0a54af09272 Feature A
| |
o | 77ceb31100be Master B
|/
o b5a0b2c7468f Master A
$ hg log -G --template '{node|short} {desc|firstline}' --follow-first
@ 51b90923fc9d Master C
|
o bb51d979fd68 Merge branch 'feature'
|\
o | 77ceb31100be Master B
|/
o b5a0b2c7468f Master A
The above example may not seem too bad, but see https://gist.github.com/MaxNanasy/5184202 for an example in which this behavior renders unwieldy output.
This issue may not matter much if issue #2 is insurmountable, because then hg log
without -G
would be the only useful way to use --follow-first
AFAICT.
Upvotes: 0
Reputation: 6262
You can use revsets for this:
hg log -r "p1(merge())"
merge()
gets all the merge commits and p1()
gets the first parent of those commits.
Use hg help revsets
to get more information on revsets.
Upvotes: 1