I've committed several changesets and am now thinking that it might have been better on a new branch. I haven't pushed changes yet so they're still in the draft phase. Is there some mercurial way (that doesn't involve re-cloning) that I can just change these over to a branch?
Update to the parent of first improperly (to the wrong branch) committed changeset
Create needed branch (hg branch ... + hg commit ...)
Rebase changesets to the new parent (starting changeset of branch)
Related
I stated working by creating a new branch (say) new-feature and done all the changes ( a lot of files has been changed).
And I wrongly merged it with a branch say 'my-client' branch where every one works and pushed the code to the repository. I want to remove the merge I've done.
No other developers currently working on branch 'my-client'.
I have tried
hg backout <REV> // rev of the bad merge
abort: cannot backout a merge changeset.
Is there any way to fix it?
We are using Mercurial. I think there is a problem with a changeset. To make sure, I want to go back to the state before that changeset.
How do i do that ?
You can use hg up {REVISION}~1 to update your working copy to the state before the problematic changeset.
When you don't already have published the changeset, you can use hg strip to remove the changeset (warning: strip is a destructive operation).
If the changeset is already published, you can use hg backout at the top of the branch to get mercurial to reverse-apply the changes of the problematic changeset.
I know Rebase is a (bundled) extension, while Graft is a core feature (that replaced the Transplant (bundled) extension).
graft is documented as:
copy changes from other branches onto the current branch
This command uses Mercurial's merge logic to copy individual changes from other branches without merging branches in the history graph. This is sometimes known as 'backporting' or 'cherry-picking'.
rebase is documented as:
Rebase allows moving commits around in Mercurial's history (using a series of internal merges). This has many uses:
moving changesets between branches
"linearizing" history
reordering changesets
collapsing multiple changes into one changeset
Both seem to use merging to move or copy changesets between branches.
Graft copies. Rebase moves. But rebase --keep copies.
So often it seems I can accomplish my goal of copying a changeset either way.
Does it matter which one I use? When should I prefer one over the other?
E.g. should graft only be used when copying to a different named branch? Or only when there's just a single changeset?
Edit: Could it be that rebase is a potentially unsafe superset of graft, but can only be used with draft changesets during development for editing local history, while graft is a safe subset of rebase that can be used with public changesets during maintenance for backporting?
hg graft allows "cherry-picking," as you noted in your question. For example, you can run hg graft -D "2085::2093 and not 2091" to copy only some changes from another revision. By comparison, hg rebase (with or without --keep) will grab whatever changeset you specify and all of its decendant changes.
Also, rebase allows you to collapse changesets (with --collapse). As far as I can tell, graft does not.
One more difference I have noticed: hg graft --edit 123 lets you graft revision 123 to the working directory and edit the commit message. I can't find an hg rebase equivalent. I should point out, though, that hg histedit also allows for editing the commit message while rebasing.
There are probably other differences that I am not thinking of. SO community: feel free to point those out in the comments, and I will happily revise this answer to make it more complete.
See the graft documentation and the Rebase Extension documentation for more details.
I was working in branch-a when I found an unrelated bug that should be fixed in the default branch. So, I'd like commit some of my changes to default, then merge default into the current branch, and keep working.
As far as I know, Mercurial doesn't allow committing directly into another branch, so I would have to switch to the default branch first. The problem is, I can't simply checkout the default branch, because the other changes would cause conflicts. One workflow I can think of is to shelve, checkout default, unshelve only the files that relate to the fix, commit, checkout branch-a, merge default, and finally, unshelve the rest of the files. Is there an easier way to accomplish this?
Commit only subset of files, related to branch-a changes (use additionally power of Record Extension, if bugfix's and branch-a's changes happens in some file(s) - commit only needed hunks of file) as changeset A
If you haven't MQ Extension:
Commit the rest of changes into branch-a as changeset B (child of A)
Rebase B (with Rebase Extension) changeset into default branch with --keep option in oder to have B in original location also
If you have MQ extension
Create new patch with working-dir changes
Unapply MQ-patch
Update to default
Apply patch
Test, test...
Finish patch (convert to permanent changeset)
Graft this changeset only into branch-a branch
I'm trying to rebase some changes I pulled in to my local machine. I'm getting the error:
abort: can't rebase immutable changeset 110e73ed65a4
(see hg help phases for details)
And I get the same error even after I change the phase on the changesets that I'm rebaseing (and the phase change seems to be successful). using:
hg phase -f -d REV
I'm wondering if there's a changeset in the history that I'm missing and is still immutable, and if so, if there is a way that I can change all of the changesets in a changeset's history to be mutable with a single command.
Or, is there a way to force rebase, even with the immutable changesets?
Rebasing changes that are public is considered a very bad idea. You shouldn't change any history that's been pushed -- the point of phases is to track what changes haven't been pushed yet (so they're able to be modified), and what changes have been pushed (so they're immutable). From the rebase documentation:
You should not rebase changesets that have already been shared with others. Doing so will force everybody else to perform the same rebase or they will end up with duplicated changesets after pulling in your rebased changesets.
It's better to either merge in your changes or graft them in. Graft (also known as cherry-picking) takes one or more changesets and copies them to your current branch.