I want to be able to get a "hg log" of every changeset that appears in the graph between
changeset1 and changeset2. I cannot find a way to do it without either
a) omitting nodes on named branches that ARE merged between changeset1:changset2
or b) including nodes on named branches that ARE NOT ancestors of changeset2
Here's a "hg glog" of a simple example with 2 named branches plus the default branch. One named branch gets merged and so its nodes are relevant, the other is irrelevant:
# changeset: 5:e384fe418e9b
|\ tag: tip
| | parent: 2:7dc7af503071
| | parent: 3:0a9be59d576e
| | summary: merge somefeature branch into default
| |
| | o changeset: 4:4e8c9ca127c9
| | | branch: unmerged_feature
| | | parent: 1:ef98ad136fa8
| | | summary: change that is not merged into ending changeset
| | |
| o | changeset: 3:0a9be59d576e
| |/ branch: somefeature
| | parent: 1:ef98ad136fa8
| | summary: changed b.txt
| |
o | changeset: 2:7dc7af503071
| summary: changed a.txt
|
o changeset: 1:ef98ad136fa8
| summary: added b.txt
|
o changeset: 0:271b22b4ad30
summary: added a.txt
I want a log command that will give me all the nodes that are descendent of rev 0 and ancestors of rev 5. This is everything except rev 4.
I can get too much info:
hg log -r 0:5 --template "{rev}:branch={branches},desc={desc}\n"
This gives me a log entry for rev 4, which is not an ancestor of rev 5:
0:branch=,desc=added a.txt
1:branch=,desc=added b.txt
2:branch=,desc=changed a.txt
3:branch=somefeature,desc=changed b.txt
4:branch=unmerged_feature,desc=change that is not merged into ending changeset
5:branch=,desc=merge somefeature branch into default
I can get too little info:
hg log -b default -r 0:5 --template "{rev}:branch={branches},desc={desc}\n"
omits rev 3, which is a descendent of rev 0 and ancestor of rev 5
0:branch=,desc=added a.txt
1:branch=,desc=added b.txt
2:branch=,desc=changed a.txt
5:branch=,desc=merge somefeature branch into default
If you're using a newer version of Mercurial (1.6.0 or higher), you can use the revsets feature. In this case, you need the ancestors() operator:
hg log --rev ancestors(5)
See hg help revsets for more information.
Related
Currently I am struggling with the Mercurial (v. 2.6.2) log feature. For creation of a change log of our software I have to collect the following set of changeset:
|
O A First interested revision on default
|
O B start of branch
|\
| \
| O C Commit on branch
O | D commit on default
| /
|/
O E Merge from branch to default
|
|
O F start of release branch
|\
| \
O | G on-going development on default
| O H Patch fix on release branch
| |
So what I try to get is a collection of changeset that contain A,(B),(C),D,E,(F),H.
The changesets in brackets would not harm if they are part of the log, but they would not be necessary. The changeset G must not be part of the log.
$ hg help revsets
$ hg log -r A::H
My repo is currently as follows:
O 7: default
|
O 6: default
|
| O 5: default
| |
| O 4: default
| |
| O 3: default
| /
O 2: default
|
O 1: default
I would like to move 6 and 7 to a new branch, how can I do it?
You can use the rebase extension for this. It needs to be enabled but that link has the information on how to do it.
The commands would be:
hg update 2
hg branch newbranch
hg commit -m "Creating new branch"
hg rebase -s 6 -d 8
This creates the new branch, commits it (which would create revision 8 in your example) and then moves revision 6 and its descendants onto the new branch. Obviously, you'd need to look up the actual revision numbers for your repository.
You could also do it with the mq extension but I think that rebase is easier to use in this instance.
Depends how you define the term "branch". If you're talking about named branches then Steve Kaye's answer is fine.
If you're talking about a branch like 5 & 6 are on a branch in your diagram, then you don't need to do anything. 6 & 7 are already on their own branch. You can leave them alone, and move back to revision 2 to continue work there.
hg update 2
<continue work>
hg commit -m "New Stuff"
That will leave you with a graph like this:
o 8: default
|
| O 7: default
| |
| O 6: default
| |
| | O 5: default
| | |
| | O 4: default
| | |
| | O 3: default
\ | /
O 2: default
|
O 1: default
If you want to assign a name to each of those tips, take a look at bookmarks.
hg bookmark -r 8 stable
hg bookmark -r 7 experimental-stuff
hg bookmark -r 5 some-feature
... and then you can change between them by name.
I have 2 repositories A and B. I make 5 changes to A, but only 2 of them should also appear in B. So this is what I tried:
Pushed the 5 changes to repo A
Changed the path of repo B to that of repo A
Clicked the "Check for incoming changesets" button for repo B
Now I see the 5 changes I made for repo A. This is where I am stuck, how can I only get 2 of the 5 changesets now? I tried "Pull to here", but this does not work in my case, it gets all changesets below the one I selected.
How can I get for example the first and third changeset from the list? Possible at all?
Thanks! :)
When you pull changesets between repositories you cannot skip changesets in between. If a changeset has different parents in two repositories, it is not the same changeset.
You can accomplish what you are after by exporting patches of the changesets you want and then import them into the other repository. That way, you have the changes you want from repo A in B, but the changesets will not have the same nodeid in the two repositories.
It sounds like A and B were clones of the same repository. If that is the case, branching is probably what you need. If you have a history where A contains:
C:\example>hg glog --template "rev{rev}:{desc}\r\n"
# rev6:change7
|
o rev5:change6
|
o rev4:change5
|
o rev3:change4
|
o rev2:change3
|
o rev1:change2
|
o rev0:change1
If your B was originally just rev0 and rev1 and you wanted rev3 and rev5 added to it, you can just update to rev1 and graft rev3 and rev5 onto it:
C:\example>hg update 1
0 files updated, 0 files merged, 5 files removed, 0 files unresolved
C:\example>hg glog --template "rev{rev}:{desc}\r\n"
o rev6:change7
|
o rev5:change6
|
o rev4:change5
|
o rev3:change4
|
o rev2:change3
|
# rev1:change2
|
o rev0:change1
C:\example>hg graft 3 5
grafting revision 3
grafting revision 5
C:\example>hg glog --template "rev{rev}:{desc}\r\n"
# rev8:change6 <--- contains change 1, 2, 4, 6
|
o rev7:change4
|
| o rev6:change7 <--- contains changes 1-7.
| |
| o rev5:change6
| |
| o rev4:change5
| |
| o rev3:change4
| |
| o rev2:change3
|/
o rev1:change2
|
o rev0:change1
To avoid duplication of changesets and a little pre-planning, the changes that need to be on both A and B branches can be checked into B and merged into A, whereas changesets that only belong on A can be directly checked into A:
C:\example>hg glog --template "rev{rev}:{branch}:{desc}\r\n"
# rev8:A:change7 <--- contains changes 1-7.
|
o rev7:A:Merge
|\
| o rev6:B:change6 <--- contains change 1, 2, 4, 6
| |
o | rev5:A:change5
| |
o | rev4:A:Merge
|\|
| o rev3:B:change4
| |
o | rev2:A:change3
|/
o rev1:default:change2
|
o rev0:default:change1
Is it possible to, instead of merging one branch into another existing branch, merge 2 branches into a 3rd new branch?
Just merge your 2 existing branches and consider the merge as the tip of the 3rd new branch and the previous heads of the merged branches as your 1st and 2nd branch:
o changeset: 3:92692c4a6b12
|\ bookmark: masala
| | summary: merge salt and pepper
| |
| o changeset: 2:a5f955adf03d
| | bookmark: pepper
| | summary: add some pepper
| |
o | changeset: 1:2b56f2dc115f
|/ bookmark: salt
| summary: add some salt
|
o changeset: 0:e992ce7dd508
summary: initial
Here bookmarks have been used to mark different lines in development. So if you want to work in the new 3rd branch, update to masala, if you want to work on your 1st branch, update to salt, and similar for the 2nd branch update to pepper before you continue to work and commit.
If you prefer working with named branches (instead of bookmarks), just issue a hg branch masala before you commit the merge of revision 2 and 1.
The basic message is that although the graph only has one head, you are free to interpret it as 3 different lines of development.
Now, let's say you want to continue the work in the 2nd branch, pepper:
$ hg up pepper
... hack ...
$ hg ci -m "need more pepper"
And then you have some ideas for the salt thing:
$ hg up salt
... hack ...
$ hg ci -m "less salt please"
Now the history graph shows your 3 branches more clearly:
o changeset: 5:d1f8eb72119a
| bookmark: salt
| summary: less salt please
|
| o changeset: 4:acc9b01f584f
| | bookmark: pepper
| | summary: need more pepper
| |
+---o changeset: 3:92692c4a6b12
| |/ bookmark: masala
| | summary: merge salt and pepper
| |
| o changeset: 2:a5f955adf03d
| | summary: add some pepper
| |
o | changeset: 1:2b56f2dc115f
|/ summary: add some salt
|
o changeset: 0:e992ce7dd508
summary: initial
An alternative to bookmarks and named branches is to use different clones for individual branches. That is you clone your repo with the unmerged branches and merge them in the clone. Which approach is best, depends on your specific workflow and personal preferences.
In a mercurial repo I can run hg up {revision} to change the revision of my working directory, but what command can I run to discover what revision I'm looking at?
This command:
hg parent
In addition to hg parents, you can use hg summary to get the most important summary information about your current state. It looks like this:
% hg summary
parent: 13051:120eccaaa522 tip
encoding: fix typo in variable name
branch: default
commit: 2 unknown (clean)
update: (current)
mq: 20 unapplied
and tells me at a glance that I'm at revision 13051, that I'm on the default branch with a clean working copy (though there are 2 untracked files). This is the tip revision in my repository, so an update wont do anything. Finally, I have 20 unapplied MQ patches.
hg identify (or hg id for short) will print the (shortened 12-character identifier of) the parent hashes, and a + if there are any uncommitted modifications in your working copy.
To get the full hashes, you can use hg identify --debug instead.
Another option is to enable the graphlog extension, then run hg glog. You'll see output like this (bear in mind I use a template to change the output):
o changeset: 200:c8c281cf0a6d
|\ branch: craig-aspinall
| | tag: tip
| | parent: 199:1a692f3b9134
| | parent: 187:2d0e0ed9d31c
| | user: Craig Aspinall
| | date: Tue Nov 23 21:36:30 2010 +1000
| | summary: Merged latest changes
| |
| o changeset: 199:1a692f3b9134
| | branch: craig-aspinall
| | parent: 123:1dc90c9b7ede
| | user: Craig Aspinall
| | date: Tue Nov 23 21:35:22 2010 +1000
| | summary: Final solutions to L04
| |
| | # changeset: 198:78b488c2607d <==== This is where I am currently.
| | |\ branch: OJ
| | | | parent: 119:70ec3d9e4d3a
| | | | parent: 197:44bac809d37d
| | | | user: OJ Reeves
| | | | date: Tue Nov 23 20:19:07 2010 +1000
| | | | summary: Merged with the mainline
| | | |
| | | o changeset: 197:44bac809d37d
| | | | user: Tony Morris
| | | | date: Tue Nov 23 18:40:03 2010 +1000
| | | | summary: Started parallel anagrams
| | | |
| | | o changeset: 196:92241b51970b
| | | | user: Tony Morris
| | | | date: Tue Nov 23 17:52:32 2010 +1000
| | | | summary: Started parallel anagrams
| | | |
The node/revision with the # symbol is where you are.
The most specific non-DEPRECATED command which due to the presence of --template can print only revision information if that conciseness is required (as implied by the question):
hg log -l 1 -b . -T '{rev}:{node|short}\n'
Or:
hg log -l 1 -b . -T '{rev}\n'
Or:
hg log -l 1 -r . -T '{rev}\n'
Or for unique long form of hash:
hg log -l 1 -r . -T '{node}\n'
The -b . or branch(.) (dot for branch name) means the current working directory branch and -r . means the current working directory revision, which is documented in hg help revsets and hg help revisions.
Note if there is an uncommitted merge, the . (dot) only displays the first parent of two parents of the working group.
This will also helpful,
hg log -v -r `hg id -i`