Can I view resolved files after a merge in hg? - mercurial

I'm using mercurial and one problem I found while merging was the fact that it's hard for a single developer to merge with the default trunk after a lot of changes.
So even if the developer resolves the conflicts by hand there is always a change to miss some of the intersecting changes.
I would like to take a look at the history of a merge and see the resolved files, so other developers can review it.
Can I view resolved files after a merge in hg?

What I like to do is this workflow:
hg pull
;; assuming I'm on development branch
hg merge -r default
hg diff ;;do incoming changes look good
;; run tests
hg commit -m "merged from others, lookin' good"
hg up default -C
hg merge -r development
hg diff ;;everything look good still?
;; run tests
hg commit -m "And back to default, all tests pass"
hg push

Related

Mercurial: Switch working directory to branch without losing changes?

Let's say that I have a named branch 'B1' which I'm doing feature development on.
I am at a good stopping point before a demo though not done with the feature so I:
hg up default
hg merge B1
hg ci -m "merged in feature drop"
hg push
Now I continue working for a half an hour or so and go to commit only to realize that I forgot to update back to B1 and that my current working directory is on default - uhoh. In theory I should be able to just mark my working directory parent as the tip of B1 - is there an easy way to do this?
I could of course commit, update back to B1, and merge my changes back, but then there's an unstable changeset in default and this happens often enough to me that I would like a real solution.
Two ways. First, the obvious way:
hg diff > foo
hg up -C b1
hg import --no-commit foo
rm foo
Second, the magical way:
hg up -r 'ancestor(., b1)' # take working dir back to the fork point
hg up b1 # take it forward to the branch head
This way involves merges. Depending on how much your branches have diverged, this may be painless. Or it may be complicated, and you may make a mess of your changes that you haven't saved anywhere. Which is why even magicians like myself prefer to do it the first way.
I would use the shelve extension. I think it’s distributed along with TortoiseHg, you can also use it from the UI:
hg shelve --all
hg up B1
hg unshelve
Rebase extension allow you to change parent for any commit for wrongly commited changeset.
If you want just change branch for future commit - MQ (as mentioned) or Shelve
Typically for this sort of dynamic approach, I favor mercurial queues.
In your situation, what I would do would be to create a patch on default with the changes, pop the patch off, switch over to B1, and apply the patch.
It goes something like:
hg qnew OOPSPATCH
hg qrefresh
hg qpop
hg up B1
hg qpush
<hack hack>
hg qrefresh
hg qfinish
All you need is simple hg up -m B1
From hg up --help:
options:
…
-m --merge merge uncommitted changes
…

Make another branch default?

I have a Mercurial repo at Bitbucket and on my local machine, both are mirrors, up to date. I created a feature branch, reflected in both repos. I did all my work in the feature branch.
The feature branch is now complete and I want to now make it the default for the main repo and my local copy. I don't really care about the default branch, enough work has gone into the feature branch that all I want to do is designate it as the new default.
I don't think I want to merge nor should I? How can I do this so both local and remote don't get confused?
Just merge feature-branch into default then close feature-branch:
$ hg checkout default
$ hg merge feature-branch
$ hg commit
$ hg checkout feature-branch
$ hg commit --close-branch
There is no more clean and sensible way (that I'm aware of) to “make feature-branch the default”.
One thing that wouldn't be as nice, but you could do, is to make a commit to default on top of feature-branch:
$ hg checkout feature-branch
$ hg branch default
$ hg commit
But this would leave two heads in the default branch, which is suboptimal.
Since Mercurial 2.4, you can create an bookmark called # and Mercurial will checkout that revision new clones.
However, I would still try to stick with using default as the branch where the main development takes place. Doing so will cause the least amount of surprise for developers already used to Mercurial — the wiki describes the standard way to use branches in Mercurial.
If you follow the conventional advice of using default as the main branch for development, then you should close your feature branch before you merge it back:
$ hg update feature-branch
$ hg commit --close-branch -m "Feature done, merging into default branch"
$ hg update default
$ hg merge feature-branch
$ hg commit
If you haven't done any work at all on the default branch since your started the feature branch, then this merge will be trivial and have no conflicts. Otherwise you'll have to resolve conflicts. If you're sure you want to keep everything from the feature branch, then you can do
$ hg merge --noninteractive --tool internal:local feature-branch
$ hg revert --all --rev feature-branch
instead of just hg merge above. That will make sure that the new commit on default look exactly like the last commit on feature-branch.
I succeded without merging by closing the default branch.
in my development repository working directory:
$ hg update default
$ hg commit --close
then my development branch became the new default branch.
But i do not know the rules for why my development branch was choosen
as the new default.
i think it is because it was my tip ?
(or maybe last changed branch? (tip?))
I also think that you have to repeat that next time.
Because i think my chosen branch name was "overwritten" by the 'default' name.
It would be nice to have branch name.
dev-projectname-version.x=default
regards
I wanted to do just what you described and hunted around until I found an answer which uses the revert command to do just what you describe. Here is the code I used:
hg revert --all --rev ${1}
hg commit -m "Restoring branch ${1} as default"
where ${1} is the number of the revision or the name of the branch. These two lines are actually part of a bash script, but they work fine on their own if you want to do it manually.
This is useful if you need to add a hot fix to a release branch, but need to build from default (until we get our CI tools right and able to build from branches and later do away with release branches as well).

mercurial -- "merge" by abandoning one changeset

I have two heads, let's call them "A" (the good head) and "B" (the bad head). I want to merge them by taking everything from A and nothing from B. Basically, my merge of A and B is A.
When I try hg merge, it starts asking me about this file and that, and inevitably I get into trouble. I don't want any of that! How can I tell it to merge them and end up with A, preferably without any intermediate steps?
From the Mercurial tips at section 22. Keep "My" or "Their" files when doing a merge.
https://www.mercurial-scm.org/wiki/TipsAndTricks
Occasionally you want to merge two heads, but you want to throw away all changes from one of the heads, a so-called dummy merge. You can override the merge by using the ui.merge configuration entry:
$ hg --config ui.merge=internal:local merge #keep my files
$ hg --config ui.merge=internal:other merge #keep their files
Here local means parent of working directory, other is the head you want to merge with. This will leave out updates from the other head.
To merge X into the current revision without letting any of the changes from X come through, do:
hg --config ui.merge=internal:fail merge X
hg revert --all --rev .
The other approach is mentioned in : https://www.mercurial-scm.org/wiki/PruningDeadBranches
$ hg update -C tip # jump to one head
$ hg merge otherhead # merge in the other head
$ hg revert -a -r tip # undo all the changes from the merge
$ hg commit -m "eliminate other head" # create new tip identical to the old
One thing I came across and started using recently on some personal repos was just using the close-branch switch with commit. e.g.
$ hg update B
$ hg commit --close-branch -m "Abandoning branch"
In my reasoning, if you're blowing away one branch in favor of the other entirely, it's simply not a merge and it's silly to call it that. I'm relatively new to hg myself, and I seem to recall that --close-branch has not been around since the beginning and maybe that's why it doesn't have as much traction as the merging gyrations I usually see.

Can't branch a single file with Mercurial?

is this possible with Mercurial? and which Version Control system can do this besides Clearcase?
David is correct that you can't have a branch that exists on only a single file, but it's worth pointing out that people often have branches that alter only a single file. Since the branch metadata is stored in the changeset, and since the changeset contains only a delta (change), having a branch that alters only a single files is nearly instantanous to create, update, commit, and merge, plus it takes up almost no space on disk.
Resultingly, it's a very common way to handle per-customer configurations. Keep the tiny change for them in a branch, and merge from main, where development happened, into that branch, whenever you want to update their deployment.
How you could use MQ:
$ hg qnew -m "Changes for client0" client0
... change the file ...
$ hg qref # update the client0 patch with the changes
$ hg qpop # pop the changes off the queue stack
... develop like normal ...
... client0 asks for a build ...
$ hg qpu # apply client0's patch
$ make release
$ hg qpop
It would get a bit finicky if you've got to deal with a lot of clients… But it may be worth considering.
The other thing you could do, of course, is just commit a bunch of .diff files:
... make changes for client 0 ...
$ hg diff > client0.diff
$ hg revert --all
$ hg add client0.diff
$ hg ci -m "Adding client0 changes"
... develop ...
... client0 asks for a build ...
$ patch -p1 < client0.diff
$ make release
$ hg revert --all
No, it's not possible. A branch in Mercurial is a snapshot of the entire repository state.
You could do it with CVS, though, as CVS tracks changes on a per-file basis :)

How to repeatedly merge branches in Mercurial

We're using Mercurial where I work and I want to have a setup similar to how I used SVN:
Trunk
Tags
Production
Branches
Since Mercurial supports branches natively, I know how to create a named branch, but I can't find any documentation on how to repeatedly merge 'Trunk' with 'Production'.
Quite simply, I want to have a development branch for normal work and a production branch that I routinely pull changes from the development branch into. How do I do this with Mercurial?
As the previous poster mentioned, the transplant extension can be used for cherry-picking individual changes from one branch to another. If, however, you always want to pull all the latest changes, the hg merge command will get you there.
The simplest case is when you're using clones to implement branching (since that's the use case Mercurial is designed around). Assuming you've turned on the built-in fetch extension in your .hgrc / Mercurial.ini:
cd ~/src/development
# hack hack hack
hg commit -m "Made some changes"
cd ../production
hg fetch ../development
If you're using local branches:
hg update -C development
# hack hack hack
hg commit -m "Made some changes"
hg update -C production
hg merge development
hg commit -m "Merged from development"
Something like hg transplant? That's what we use on our dev and prod branches.