10

I have a big named branch with a lot of changes. Some of these changes are non-destructive so I want to pick these specific files out first, and merge them with default as soon as possible. (Then later, the destructive changes are merged as well.)

In Git I would create another branch and squash all changesets outside of the index, then I would add the specific files to the index and commit. After that, I could merge this temporary branch with master so master has a clean commit with only the non-destructive change. I don't know how to do this with Mercurial.

tshepang
  • 12,111
  • 21
  • 91
  • 136
  • Does this answer your question? [Mercurial: Merging one file between branches in one repo](https://stackoverflow.com/questions/1078881/mercurial-merging-one-file-between-branches-in-one-repo) – StayOnTarget Apr 27 '20 at 14:26

3 Answers3

6

You can use hg cat to grab the contents of a file as it exists on any particular branch, and replace the working copy version with that.

This isn't technically a merge, but since you're replacing whole files you shouldn't have too much of a bad time merging things later:

for example, to grab myfile.c form branch somefeature, and replace the working copy version, do:

hg cat path/to/myfile.c -r somefeature > path/to/myfile.c

note that this completely replaces the working copy file so make sure you have no outstanding changes first

James
  • 24,676
  • 13
  • 84
  • 130
4

I think mercurialqueues is what you want. With mq you can turn any changeset into a patch and any patch into a changeset. So taking a changeset converting it to a patch deleting the chunks out of the patch that you don't want and then applying it to whatever branch you want. This is a fairly complex operation though and requires a certain amount of discipline on your part. So I would try to nail down your workflow on a test repo before trying it on code you care about.

Tom Willis
  • 5,250
  • 23
  • 34
  • Thanks for the links, I'll check them out. For now I seem to have found the answer (see comment above). –  Jun 29 '10 at 13:30
  • it's cool. I was basically trying to lend some credibility to mizipzor's answer in regards to the mq stuff. – Tom Willis Jun 29 '10 at 19:51
2

As far as I know, Mercurial doesnt any have tools to split changesets. If youre lucky, all the changes you want are in separate changesets and then you can use the TransplantExtension. I think it can be compared to Git's cherry-pick but I havent used git much.

You can also use hg diff to manually commit the changes to a certain file to a new branch. Use the rev range to mark your entire source branch:

hg diff myfile -r startrevision:endrevision

The output can be treated as a patch. Do this for each file you want and commit them and then merge. Skipping the destructive changes. You can also, of course, do this multiple times of a destructive change is in the middle of a revision range.

Having said that what youre trying to do isnt something mercurial was built for. That hardcore history editing is more Git's area (note that its just my opinion). Keep your stable changes and destructive changes in separate changesets (and maybe even in separate branches). I use transplant, rebase and strip to move changes around. When its all done, they are merged and properly pushed.

Oh, and check MercurialQueues. I havent used it myself but Ive seen it do some crazy stuff. Maybe its capable of doing something along the lines of what you want.

John
  • 1,011
  • 11
  • 18
Mizipzor
  • 51,151
  • 22
  • 97
  • 138
  • Can I use: hg rebase --collapse --keepbranches -b -d It seems to put al the changed files in my working dir without commiting them. Are there any side effects? –  Jun 29 '10 at 12:04
  • I havent used rebase for anything but the most basic stuff, I suggest you simply read the docs and try it thoroughly on a test repos to figure out how it works. And by the way, that comment is a perfectly valid (and separate) question to ask here on Stackoverflow. =) – Mizipzor Jun 29 '10 at 15:04
  • Mercurial does have an extension for splitting changesets - it's called histedit. You just commit while editing a changeset. – Jacklynn Apr 13 '15 at 21:11