I have 2 branches in my Mercurial repository. 'default' and 'other'
default branch A - B - C - D
other branch E - F
I need to move B changeset to other branch.
So it will look like this:
default branch A - C - D
other branch E - F - B
Is it possible?
Thanks in advance!
Graft-based solution
Graft (hg help graft) B to target branch
Remove (histed extension) B from source branch (graft only make copy of changeset, without removing original)
Rebase-based solution
Rebase B to other branch
Because rebase move also descendants of rebased changeset - rebase C back to default
The following solution doesn't require enabling any extensions. It does assume the existence of the patch utility, though.
On default:
$ hg diff -c B > diff.out
$ hg backout --merge -r B
$ hg merge
$ hg ci
On other branch:
$ patch -p1 < diff.out
$ hg ci
Related
My revision graph looks like:
F
|
E
|\
| |
C |
| D
| |
B |
| |
|/
|
A
I want to collapse all commits from B to F into a single one. A is not mine, and I don't want to touch it. I'd like to have in the end:
X
|
A
Is this possible ? I've tried various collapse and rebase commands but could not achieve this.
You can accomplish this with the mq extension for the patch queue. You will need to remove the merge changeset (since I don't think you can qimport a merge) and reorder the patches (which may require some hand merging of the patch file).
hg qimport --rev F --name F
hg qpop
hg strip -r tip -- this removes the merge changeset
hg qimport -r C -n C
hg qpop
hg qimport -r B -n B
hg qpop
hg qimport -r D -n D -- now you have all 4 changes (D, B, C, F) in the patch queue
At this point you can hg qpush --all to apply all the patches and you will need to resolve all the conflicts that result in rejected patches. This is to manually redo the work that the merge changeset E had previously accomplished. Once that is completed via editing and hg qref commands, qpop all the patches except for D.
hg qfold B C F -- this will merge the B, C, and F patches into patch D
hg qfin D -- this will convert patch D into a finalized changeset
A few more notes:
As always, back up your work before you start (a copy of the folder is fine). You can also use your diff tools after the steps to compare the original and the result to ensure that you didn't miss anything.
If you have pushed any of those changesets to another repo, you will need to delete them there (either with hg strip or changing their phase to secret).
If the merge changeset E did a lot of work (i.e. there were conflicts between B+C and D) the extra step between 9. and 10. will be messy since your typical merge tools are not available.
The follow up question I have for you though: Why? What do you hope to accomplish? Branching and merging with smaller changesets is standard operating procedure with DVCS. After a few more changes, all those changes will scroll into history and never come up again. Worrying about a perfect history graph is really unnecessary.
Is there any way to force merge branch A in branch B where all possible conflicts will be resolved in favor of branch B?
In any words how to push last branch B revision in branch A without vanity around conflicts?
You can decide to take all of one branch over another by using hg merge --tool internal:other or hg merge --tool internal:local
I'm not sure which way you want to merge but if you want to merge A into B taking all changes from B then you would do the following:
> hg update B
> hg merge A --tool internal:local
> hg commit -m "Merge"
The internal:local merge tool will take the changes in the current revision (which is B because of the hg update B) over the changes in the other revision, internal:other would take all changes from A.
For more info use the following commands: hg help merge and hg help merge-tools
If you have changesets A, B, C, D, E in your repo and you execute hg update -c D, how can you confirm that your repo is currently 'active' with changeset D? If we run hg tip or hg head, HG lists E and not D.
There are several ways to find this out:
hg summary
hg identify
hg log -r .
Note that hg update actually changes the revision of your working copy, so you definitely should not use that.
hg update develop --clean
remote: conq: repository does not exist.
abort: no suitable response from remote hg!
I would like to be able to switch to my develop branch, to undo my last 2 commits and merge the develop branch with tip or close it!
OR
just close and rename the branch, but since I can not update to it I don't know what to do.
I would like to: overwrite branch x with branch y:
hg update x
hg commit --close-branch -m 'closing branch x, will be overwriten with branch y'
hg update y
hg branch -f x
hg ci
but i can't update to x. How to fix/force this?
I used the MQ extension:
hg qinit
hg qimport -r 4:tip
hg qpop -a
hg qdelete 4.diff
hg qpush -a
hg qfinish -a
That worked but after a pull the removed stuff was back in..
But, I just created a new Branch one from tip using -f with the same name.
that works good enough for me. Can't remove the 'wrong' branch it since it is 'out of the bottle' published.
I want to move a changeset from one branch to another. Basically, I currently have:
A -> B -> C -> D # default branch
And I want:
A # default branch
\-> B -> C -> D # some_new_branch
Where some_new_branch does not exist yet. I am used to git, so I guess there is a simple "mercurial" way I am missing.
One way is to export a patch for B,C,D; update to A; branch; apply patch:
hg export -o patch B C D
hg update A
hg branch branchname
hg import patch
To remove B,C,D from the default branch, use the mq extension's strip command.
Sounds a bit like a cherry-pick operation in git. The Transplant Extension may be what you're looking for.
With Mercurial Queue:
# mark revisions as draft in case they were already shared
#hg phase --draft --force B:D
# make changesets a patch queue commits
# (patches are stored .hg/patches)
hg qimport -r B:D
# pop changesets from current branch
hg qpop -a
#
hg branch some_new_branch
# push changesets to new branch
hg qpush -a
# and make them commits
hg qfinish -a
Without comments:
hg qimport -r B:D
hg qpop -a
hg branch some_new_branch
hg qpush -a
hg qfinish -a
Alternative to transplant or patch, you could use graft.
hg update A
hg branch branchname
hg graft -D "B:D"
hg strip B
Note that changing history is bad practice. You should strip only if you haven't pushed yet. Otherwise, you could still backout your changes.