is there an easy way to export last n commits into a new mq queue and strip the commits from the real repository?
I do often start out developing a new feature, later realising I did something wrong/would want to use MQ to fold patches.
I am currently doing:
Export last n commits as single patches
Strip last n commits
create new mq
import all patches in reverse order
It's simple (as long as there are no merges):
hg qimport -r base:tip
And voilĂ .
Related
I am currently using Mercurial for sub-version control in my project. Now I am suppose to work on a new branch 2.7 but I confuse to work with branch 2.6, I have developed the new feature which the feature on 2.7 but I build on 2.6. And now I want to move this feature to branch 2.7 properly but I don't know how can I move it properly. Is there any way?
I would recommend using hg graft, which copies changes from one branch to another and unlike hg rebase is not destructive (relevant if you're doing this for the first time and may be making mistakes or if you need the feature to be present on both branches).
To copy changes to a branch dest-branch, do the following. First update to the branch you want to copy the changes to:
hg update dest-branch
Then, use graft to copy the revisions you want from the original branch, e.g.:
hg graft -r start..end
where start is the first revision you want to graft from the source branch and end is the last revision.
You may encounter conflicts if they can't be merged cleanly, which you have to resolve them (as you'd do in a merge), then use hg graft --continue to graft the remaining revisions.
The magic word is RTFM - hg help rebase
I want to submit a sequence of changesets as one changeset (patch) into Review Board. How to do that?
The technical term for combining multiple patches into one is "folding". If you want to truly fold a series of commits into one (changing history), then the HistEdit extension provides a way as do Mercurial Queues.
If you're just interested in generating a patch, then you have a few options. You can use hg export (but this will not fold the patches together, but rather dumps a series of patches to console) or you can use hg diff to generate a diff. More precisely,
hg diff -r start:end > summary.patch
will generate a single diff for all the changes in the range start to end. You can replace end with tip to get all changes starting with start. This should even work if there are merge changesets in between. (hg export produces odd output if there are merge changesets in there.)
I would suggest that since you need to submit a sequence of changes in as a single item for review you should diff your final result with either the point that you started making changes or with the latest version of the code - creating a patch. Then attach the patch, details of the version that you diffed with, etc., to the Request for Review form.
My coworker accidentally made two commits in the default branch instead of creating new his own development branch.
How can I change this situation and moves these two commits to a new branch?
Imagine the following scenario:
D
|
C
| "I want to move C and D here"
B/
|
A
Steps:
hg update B
hg branch "mybranch"
hg commit --message "Create my branch"
hg update mybranch
hg graft -r C
hg graft -r D
hg strip -r C (this should be the revision C had originally)
The strip command is provided by an extension that you need to enable. You can follow a guide on how to enable it on the Mercurial Wiki.
hg update default
A major question
Have the accidental commits reached other repositories or is it just in his own? If so, you can skip to the section below 'Maybe the cat is still in the bag' otherwise you may have a fair bit of work to do.
You are not alone
See here for more discussion on how to correct the problem elsewhere on Stack Overflow. What is described is the 'proper' way to to it
export a patch
create the branch
import the patch
delete the earlier commits.
Maybe the cat is still in the bag
If the changes are only in the local copy, then a simpler solution is to
create the new branch
switch to it
merge the changes onto that either with your fav merge tool (go Meld) or with hg graft
use the hg strip command to delete the changes on the old brach
push the changes to the world
pretend like nothing ever happened, whistle a happy tune ...
The two answers above are both correct but, assuming one has not yet pushed the commits, there's a third way.
I just successfully used the rebase command to move a string of commits to a topic branch I had forgotten to create in the first place.
I first updated to the revision from which I wanted to create the branch on which my commmits were supposed to be, then I rebased the earliest of my commits from the wrong branch on this new one and ta-da, done.
Takes more time to explain it than to do it with TortoiseHg or even the command line, really.
In my repo, I have the revisions 1 to 10. I've pushed up to 5 (so the next hg push would publish revisions 6-10).
But I have to interrupt my work now and the result isn't 100% complete. So I'd like to move the revisions 6-10 into a new "experimental" branch to allow someone else to complete the work without disrupting the sources for everyone.
How can I add a branch to a non-tip revision (in my case: Starting with revision 6)? Or should I use a completely different approach?
You cannot apply a branch name after the fact without modifying your history.
The most simple approach is to ask the other users to use revision 5 as the parent for any changes they create. For example, the other users would:
hg clone <your repo> or even hg clone --rev 5
hg update -r 5
work, work, work
hg commit
When they commit a change, it will create a second head on the default branch, but that should not create any problems. You will simply need to merge the two heads together once your experimental changes are complete.
That being said, moving your changesets onto a branch can be accomplished using Mercurial Queues (MQ). The following sequence shows how it be done:
hg qinit (Create a new patch queue)
hg qimport --rev 6:10 (import r6-10 into a new patch queue)
hg qpop -a (remove all patches from your working copy)
hg branch <branch name> (create your new experimental branch)
hg qpush -a (apply all the patches to your branch)
hg qfinish -a (convert all patches to permanent changesets)
Tim already has good suggestions. Additionally you could push your experimental changes into a distinct experimental clone on your central server (I guess you use one). This clone could also be used by other developers to push their not-yet-finished work in order to let others review or continue it. It is also clear that this clone's code is not ready to be used. Once some task is finished, the corresponding changesets can be pushed to the stable repository.
Actually named branches are a good idea for your case, but the fact that their names are burned into history mostly is more a problem than a feature. IMHO Git's branch names are more practically. However, to some extend you could also handle your case with bookmarks, which are pushable since Mercurial 1.7 (not sure here). That is you bookmark revision 5 with something like stable (or whatever you agree on in your team) and revision 10 gets bookmarked with something like Aarons-not-finished-work. The other developers would then just pull stable, except your colleague who is supposed to continue your work, who would pull the other bookmark. However, personally I did not use a such workflow yet, so I cannot say if it performs well in practice.
In my setup I have a central Hg repo to which I'm pushing my local changes. Say in my local clone I have a series of local commits and then I want to push the changes to the central repo. How can I push only the final state without including all of the "small" local commits that I made?
I want this because sometimes I dont want to pollute the central repo's history with all of the small local commits that I made.
Why would you want to do that? Committing small changes makes it easy to revert something. If you collect everything in one big commit, reverting a small change might not be as easy.
I agree with bjorn (and I'm upvoting his answer), what you're doing isn't a great idea -- meaningful history is a good thing. If you can't be talked out of it then what you're trying to do isn't just push the last changeset but a new changeset that is a combination of all those changesets. The easiest way to do that is to use the collapse extension, though mq or even export/import can do it. The key there is that in collapsing multiple changesets into one you're rewriting history and you're going to remove your existing changesets and replace them with that new combined changeset. Doing so violates the immutability of history that makes Mercurial so trust worthy.
How to do this without any extensions is explained in the mercurial wiki page ConcatenatingChangesets.
That page also links to a few alternative approaches with hg extensions, like the CollapseExtension.
It is possible to rewrite your history using the mq extension. Suppose the revisions you want to collapse are revs, 5,6,7 with 7 being the tip. You would accomplish this via:
# Import the revs you want to collapse into mq
# mq will create patches for each revision from 5:tip, with the name
# <local rev number>.diff
hg qimport -r5:tip
# Goto the first commit
hg qgoto 5.diff
# Fold in the other commits successively. Aside from shell magic, there is
# no command line way to specify multiple patches at once.
hg qfold 6.diff
hg qfold 7.diff
# Commit the new mq patch as a changeset of its own
hg qfinish 5.diff
Now, your repository contains only a rev 5 with the contents of what was previously revisions 5, 6, and 7.