After I pull a new head into my repository, I want to see what files are touched by the new head. Like an hg status but without changing over to it. I don't want the whole diff, just an overview.
Which I expect is a specific version of the more general question: how do i see a summary of the changes in a specific revision?
This is on the commandline, I don't want to fire up TortoiseHG or some other GUI.
The status command shows you which files are changed. Use
hg status --rev .:tip
to compare the working copy parent revision (the currently checked out revision) with the tip revision.
If you've pulled more than one changeset, then this is different from
hg status --change tip
That command only shows the files touched by the tip changeset — not the combined changes between the currently checked out changeset (.) and tip.
Use the --change option to hg status, passing it the revision you're curious about. For instance,
hg status --change tip
lists the files changed in tip. I believe this flag was added in hg 1.7.
Lol. Amazing how forcing myself to ask the question makes me realise where best to look.
hg diff -r11 --stat
The --stat seems to get me what I'm after.
Related
I've recently started to work on an open source project which uses Mercurial.
I'm a new user to Mercurial, so I read the HG book and started working.
My goal was to write code and always pull and merge changes from the upstream
so I can stay up-to-date. The area that I am working on is also under heavy
development by others so I do want to merge my changes after a long period of
time. I cloned a repo. So, my workflow is like this:
I created a bookmark mybook
hg up mybook
Write code
3.1 hg commit -m 'new functions'
hg up default
hg pull
hg update
hg up mybook
hg merge default
Go to step 3.
In my mind this is the simplest workflow that allows me to stay up-to-date. I
also have only one HEAD because I always merge.
Since I am not a contributor yet, I am not allowed to push changes to remote
repo.
Recently I wanted to show my work to a project lead and he said send me a patch.
And this is where I am stuck. hg out shows 10 changesets. First of which
appeard already a month ago. They're numbers are 3341, 3342, 3345, 3346, 3349, 3356, 3360, 3365, 3366, 3368. The changeset numer 3368 is the tip.
I've recently read the chapter about the MQ extension. And this extensions seems to be what I need. But the problem is that I wrote code without using the MQ
extension.
So, how can I make use of the MQ extension on already created changesets so that
I can make a patch to send to the project lead so that he can apply it and see
my changes?
I've just issued hg qinit. What's next?
Issueing hg qimport -r 3341 gives
abort: revision 3341 has unmanaged children
Reading the book and googling further does not help me. I need an advice.
PS I've tried not using hg and MQ at all: simple diff -urN old/ new/ but I
want understand how to do it with the MQ.
Thank you.
Yeah, don't use MQ. It's a parallel system, meant for keeping things out of the history, and more important you don't need it.
You were asked for "a patch", not a complete history of your work, so I would recommend sending it in the form of a single before-after diff. hg export will give you a series of diffs, for all the work you've done, including the merges. I find it's far easier to read and review a single diff (before applying it). But instead of plain diff, use hg diff which knows to only look at tracked files, and has a number of other nice features (including the --git option, which provides richer metadata). This should do it:
hg up mybook
hg diff --git -r default > mywork.patch
Before sending it off, do an hg up default and apply the patch to check that it works without conflicts. And mention to the recipient which version of default you are patching against.
Edit: As you can read in the comments, #LazyBadger is a fan of the step-by-step patch generated by export. I prefer the single-step patch
since my history is usually TMI: Nobody cares about all the times I added a forgotten file, or noticed a bug too late and fixed in in the next commit, etc.
Take your pick.
In Mercurial, I'm wanting to build a changelog of all commit messages for revisions my stable branch. Currently, I'm using:
hg log -r <oldid>::<newid>
where is the revision id of the changeset from the last time we pushed out code, and is stable's tip. This works great for code changes that are only on the stable branch, but if I'm merging another branch (such as a new major version which had its own development branch), all those commit messages are omitted! Instead I only get the 1 commit from where it merged into stable. I would like some way (preferably w/ hg log) to see these as well.
I do NOT want to get any "unpublished" commits in this list - that is, commits on any branches which haven't been merged into stable.
Here is an example of what I'm looking for:
In this example, the last pushed revision is 540. Because of this, I don't want anything at 540 or below. There are several branches out into default and back in to stable, and I want all of these (539, 541-557 in green). However, there are some changes NOT merged back into stable (558-563) which I wish to omit. Pay special attention to Revision 539; it was NOT merged into stable when 540 was published, and therefore was not included. But now it has since been merged into stable, so I would like to include it!
Any advice you guys have would be greatly appreciated. Thanks!
Not 100% sure if this will work:
hg log -r '::stable - ::540'
I'm uncertain about it because I would have thought the command you provided would mostly be correct, except for changeset 539. You're not passing -b stable to hg log by mistake, are you?
Have a look at revsets. Kevin posted the short form of what you want - here's the long form:
hg log -r "ancestors('stable') and not ancestors(540)"
Revsets are incredibly powerful, and you can just enter them into the filter bar of TortoiseHg.
I have just been asked by a fellow developer whether they need to do anything when that merge window appears. Apparently their default course of action has been to simply close the window immediately.
Anyway, we're now in a situation where they have made minor changes to a number of files where another developer made a large number of changes. They then 'merged' them, essentially backing out all remote changes to the files, committed the code, and pushed to the central repository.
So we're in the situation that there is revision x with changes we want, revision y with changes we want, and revision z that is a merge of x+y, but actually just contains the code from y.
Is there a way now to retrospectively get back into the merge tool?
I'd like to run a command and get a meld window up to let me merge back in the changes from y into the current revision.
First, clone your repository somewhere, and test these instructions in there. I tested them on a very small repository made for the purpose, so I may have overlooked something.
hg clone yourrepo testrepo
cd testrepo
You can check out the code as of revision x, and repeat the merge. That will give you a new head. Then, if you have not made changes since, you can use hg strip to get rid of the bad one. If you don't want to risk the strip, then merge the two heads, telling hg to keep the version of the code in the good version. If you have it checked out, as you will immediately after making it, then give the argument -t internal:local to throw away the changes from the other, bad, head. It's a lot simpler to do than to explain:
hg update x
hg merge -r y
hg commit -m 'Redo the merge.'
Then either:
hg strip z
or:
hg merge -t internal:local -r z
hg commit -m 'Get rid of the bad merge.'
You can look at the state of the graph with the very useful hg view extension.
Once again, I tested this on a toy repository. Back it up first!
I want to know what changes I made, without looking at the 30 other files that other team members modified.
So when I hg out, it said the first changeset to push was 4821, so since then I have pulled, merged, and pushed a couple times. Now I want to make sure all the debugging code is removed. Is there a way to diff the current revision (4873) against revision 4821 but only for my changes?
If your changes are in different files than those of your coworkers, which is how it sounds, you can use something like this:
hg diff -r 4821 -r 4863 -I path/to/file1 -I path/to/file2
If they're mixed in the same files as other people's changes then you would have needed to keep your changes in a separate branch (which doesn't require the branch command, anonymous branching is commonly used for this sort of thing).
The following command should do the trick:
hg diff -r "4821:4873 and user(your_username)"
I don't know if you can upgrade to the recently release Mercurial 1.6 or not, but this functional query language feature they just put in is what you might be looking for.
Try this approach:
First clone your local repo to another folder
In the new clone, rebase your last changeset so that it immediately follows your the other changeset (this should create a new head from it)
Do the diff
Say, I made many changes to my code and only need to commit a few of those changes. Is there a way to do it in mercurial? I know that darcs has a feature like this one.
I know hg transplant can do this between branches, but I need something like this for committing code in the present branch and not when adding change sets from some other branch.
If you are using TortoiseHg 1.x for Windows, this feature is implemented beautifully right out of the box (no extensions required).
Run the TortoiseHg Commit Tool.
Choose a file for which you only
want to commit a subset of its
changes.
Click on the Hunk
Selection tab in the preview pane.
Double-click or use the spacebar to
toggle which change hunks should be
included in the commit.
For TortoiseHg 2.x, the Hunk Selection tab is now gone. In its place, is the Shelve tool. It has a few more features than the old hunk selection. Those new features come at the cost of some added complexity.
Note that there is no need to explicitly enable the Mercurial Shelve extension when using this feature. According to Steve Borho (lead TortoiseHg developer) in response to a different TortoiseHg question: "We have a local copy of the shelve extension and call into it directly."
For TortoiseHg 2.7+, this functionality has been improved and re-introduced. It is now built directly into the Commit tool:
Notice in the file list on the left that the top file is checked to indicate it will be included, the second file is unchecked because it will not be included, and the third file, Sample.txt, is filled (the Null checkbox indicator) because only select changes from that file will be included in the commit.
The change to Sample.txt that will be included is checked in the lower-right change selection portion of the image. The change that will be excluded is unchecked and the diff view is grayed out. Also notice that the icon for the shelve tool is still readily available.
MQ as Chad mentioned are one way. There's also more lightweight solutions:
Record extension which works roughly the same way as darcs record. It's distributed with mercurial.
Shelve extension which allows you to "shelve" certain changes, allowing you to commit only a subset of your changes (the ones that are not shelved)
I feel like I'm missing something because nobody has suggested this already.
The normal "hg commit" command can be used to selectively choose what to commit (you don't have to commit all pending changes in the local working directory).
If you have a set of changes like so:
M ext-web/docroot/WEB-INF/liferay-display.xml
M ext-web/docroot/WEB-INF/liferay-portlet-ext.xml
M ext-web/docroot/WEB-INF/portlet-ext.xml
You can commit just two of those changes with...
hg commit -m "partial commit of working dir changes" ext-web/docroot/WEB-INF/liferay-display.xml ext-web/docroot/WEB-INF/liferay-portlet-ext.xml
Not super convenient from the command line because you have to hand-type the files to selectively commit (vs a GUI check-box process like tortoise) but it's about as straightforward as it gets and requires no extensions. And file-globbing can probably help reduce typing (as it would above, both committed files uniquely share "liferay" in their pathnames.
The Mercurial Queues tutorial is terrible for this use case. All the examples I have seen assume you have yet to make a commit and you are refreshing a single patch. Most of the time this is not the case, and you have 2 or 3 commits that you want to squash together or change in some other way.
Lets say you have this sort of history:
---O---O---A---B---C
The first example is to squash commits A, B, and C. First init mq:
$ hg qinit
Now we need to "import" the commits A, B and C into the patch queue. Lets assume they are the last 3 commits. We can use the "-N" revision syntax to import them like so:
$ hg qimport -r -3:-1
That means import as patches from 3 patches back up to the last commit. You can check the status of these patches with hg qseries. It should show something like this:
$ hg qseries
101.diff
102.diff
103.diff
Where the numbers 101, 102 and 103 correspond to the local revision numbers of the commits A, B and C. Now these patches are applied, which means the changes that they describe are already in the working copy. You can get rid of the changes the working copy and remove them from the history of commits, saving them in patch form only, by using hg qpop. You can either say hg qpop; hg qpop to pop changes C and B off the stack, or specify a patch to "pop to". In this case, it would be something like this:
$ hg qpop 101.diff
now at: 101.diff
You now have the patches for commits B and C in the patch queue, but they are not applied (their changes have been "lost" - they only exist in the patch queue area). Now you can fold these patches into the last one, i.e. we create a new commit that is the equivalent of the sum of the changes A+B+C.
$ hg qfold -e 102.diff 103.diff
This will show your editor so you can change the commit message. By default the message will be the concatenation of the commit messages for the changes A, B and C, separated by asterisks. The nice thing here is that hg qfold will tab-complete the patches if you are using bash and have the hg-completion script sourced. This leaves the history like this, where A+B+C is a single commit that is the combination of the 3 patches that interest us:
---O---O---A+B+C
Another use case is if we have the same sort of history as before, but we want to drop patch B and merge A+C. This is pretty similar to above actually. When you get to the qfold step, you would simply fold in the last commit rather than the last 2 commits:
$ hg qfold -e 103.diff
This leaves the change for B in the patch queue, but it is not applied to the working copy and its commit is not in the history. You can see this by running:
$ hg qunapplied
102.diff
The history now looks like this, where A+C is a single commit that combines changes A and C:
---O---O---A+C
A final use case might be that you need to apply only commit C. You'd do this by running the qimport as above, and you would pop off all patches you didn't want:
$ hg qpop -a
The -a flag means pop off all patches. Now you can apply just the one you do want:
$ hg qpush 103.diff
This leaves you with this history:
---O---O---C
Once you are done with all this, you need to finish off the queue fiddling. This can be done with:
$ hg qfinish -a
So there we are. You can now run hg push and only commit exactly what you want, or hg email a coherent patch to the mailing list.
Some time has passed. Seems the best option now is hg commit --interactive
You can use the record extension, which is distributed with Mercurial.
You need to enable it in your ~/.hgrc file first, by adding it to the [extensions] section:
[extensions]
record=
Then, just type hg record instead of hg commit, and you will be able to select which changes to which files you want to commit.
You can also use the crecord extension which provides a nicer interface to review and select the changes. (It is not distributed with Mercurial, though, and I've seen it occasionally mess up a commit so it's not completely bug-free.)
I believe Mercurial Queues fills this role for Mercurial. There's a pretty good tutorial linked there.
Try qct (Qt Commit Tool). It has a "select changes" feature that starts up a 3-way merge tool for you to undo individual changes. After you commit, those changes you "undid" come back.
I use commit-patch. It's a script that lets you edit the diff before committing. It's really nice with Emacs's diff-mode and vc-mode.
In the past I used crecord, but it has bugs related to unicode (actually the record extension has the bugs, which crecord depends on).
First you must forget everything you ever knew about GUI's and return to the commandline. Next from the commandline do this:
hg stat > filelist.txt
This pipes all your modified files into a text file called filelist.txt
Next edit your filelist to include only the files you wish to commit.
Finally commit using the fileset sytnax:
hg commit "set: 'listfile:test.txt'"