I'm using Mercurial. What exactly does hg pull do and what other steps need to be in my workflow after I use it?
The main clone is called "farm". I made a clone of it called "myfarm" which I've been developing locally. Now I want to push the changes from my clone to the real clone hosted at googlecode.
So in the context of my own clone "myfarm", I run [hg incoming farm]. This seems to list all the changes that have been made to "farm" since I made my clone of it. Lists a bunch of stuff like:
changeset: 545:edfe4dadf
parent: 549:ea8e55929bcF
parent: 592:dfdf05dbcfA3
user: Some user
date: Some date
summary: Some comments
ok so then I ran [hg pull farm]. I'm left with the following at the command prompt:
pulling from https://blah.googlecode.com/hg
searching for changes
adding changesets
adding manifests
adding file changes
added 6 changesets with 3 changes to 2 files (+1 heads)
(run 'hg heads' to see heads, 'hg merge' to merge)
Questions:
Is everything merged for me already, or do I need to run hg merge farm now?
How will I know if there are conflicts? If so, I'm also not sure if I have to run:
.
hg merge farm
hg merge
I mean, I want to merge the results of the pull, but am not sure which of the above two is appropriate.
I'm used to using svn, so in this case, I would have just done:
svn update (notified of merge changes)
svn ci
Thanks
In the case you've described, you would run hg merge. pull is just a synchronization step, it doesn't modify the local working folders not add any merges or so any other real work.
Joel Spolsky has recently published a good tutorial on version control with Subversion at http://hginit.com. I would suggest having a read through this if you're still not quite up to speed with the concepts. I would recommend reading through the tutorial sequentially (rather than skipping to the "Merge" page) because the examples he uses build upon one another and will be easier to follow if you've read the previous sections.
Hg has an svnbook too.
Chapter 3 clearly explains your problem.
hg merge is indeed what I would do.
Related
I've recently started to work on an open source project which uses Mercurial.
I'm a new user to Mercurial, so I read the HG book and started working.
My goal was to write code and always pull and merge changes from the upstream
so I can stay up-to-date. The area that I am working on is also under heavy
development by others so I do want to merge my changes after a long period of
time. I cloned a repo. So, my workflow is like this:
I created a bookmark mybook
hg up mybook
Write code
3.1 hg commit -m 'new functions'
hg up default
hg pull
hg update
hg up mybook
hg merge default
Go to step 3.
In my mind this is the simplest workflow that allows me to stay up-to-date. I
also have only one HEAD because I always merge.
Since I am not a contributor yet, I am not allowed to push changes to remote
repo.
Recently I wanted to show my work to a project lead and he said send me a patch.
And this is where I am stuck. hg out shows 10 changesets. First of which
appeard already a month ago. They're numbers are 3341, 3342, 3345, 3346, 3349, 3356, 3360, 3365, 3366, 3368. The changeset numer 3368 is the tip.
I've recently read the chapter about the MQ extension. And this extensions seems to be what I need. But the problem is that I wrote code without using the MQ
extension.
So, how can I make use of the MQ extension on already created changesets so that
I can make a patch to send to the project lead so that he can apply it and see
my changes?
I've just issued hg qinit. What's next?
Issueing hg qimport -r 3341 gives
abort: revision 3341 has unmanaged children
Reading the book and googling further does not help me. I need an advice.
PS I've tried not using hg and MQ at all: simple diff -urN old/ new/ but I
want understand how to do it with the MQ.
Thank you.
Yeah, don't use MQ. It's a parallel system, meant for keeping things out of the history, and more important you don't need it.
You were asked for "a patch", not a complete history of your work, so I would recommend sending it in the form of a single before-after diff. hg export will give you a series of diffs, for all the work you've done, including the merges. I find it's far easier to read and review a single diff (before applying it). But instead of plain diff, use hg diff which knows to only look at tracked files, and has a number of other nice features (including the --git option, which provides richer metadata). This should do it:
hg up mybook
hg diff --git -r default > mywork.patch
Before sending it off, do an hg up default and apply the patch to check that it works without conflicts. And mention to the recipient which version of default you are patching against.
Edit: As you can read in the comments, #LazyBadger is a fan of the step-by-step patch generated by export. I prefer the single-step patch
since my history is usually TMI: Nobody cares about all the times I added a forgotten file, or noticed a bug too late and fixed in in the next commit, etc.
Take your pick.
I faced today my first mercurial problem. I was in my repo, I modified a file and I did a
hg commit
hg pull
followed by
hg update
hg rollback
to repair what I've done, (but actually I didn't push anything)
The problem is that when I did the pull (that I should do before the commit, the head changed and so hg heads looks like :
- Modif from yesterday
- My modif
- Modif from last week
and now I see that someone also did another modification (via the http interface). What should I do to repair my local repo, (if possible modifying my summary) and push it after the 2 others modifications.
Thanks a lot. Quiet confusing, was easier on my "one-man" repo..
Your local repo doesn't need "repairing". This is a very standard case that you will see often if you use Mercurial a lot.
The issue is multiple heads.
You can either merge your heads, assuming your working directory is your version and there is only the other head:
hg merge
This will result in a merge changeset (same as if you were merging across branches).
Or you can enable the rebase extension to re-base your version onto the tip of the branch (the other head):
hg rebase --source<YourVersionNumber> --dest<TipVersionNumber>
This will not result in a merge changeset, and will simply transplant your changes on top of the changeset you specify as if they were born of that changeset all along (hence rebase or "new"basing).
Multiple heads is a funny sort of inner-branch branching... you can continue checking stuff in against your own head and change between heads using hg update. We block multiple heads per branch on our server, so our push would fail. I'd advise keeping multiple heads local as they are less clear-cut than branches.
I tend to work with Mercurial in one of two ways:
If the work is large in scale I will branch it off and follow Continuous Integration practices (constantly merging the main branch into my own etc). I then re-merge back into main when I am happy with the end result.
If the work is small in scale I will simply work against main branch and "merge" heads every so often. I say "merge" as I usually use rebase. Re-basing works great if the changes are simple and conflicts are unlikely.
My hard and fast rule: if I can't use rebase I put it on a branch born of main.
I'm in my branch, and I do this:
hg incoming /path/to/baseline
And I get a few changesets in the output.
Now do I just merge to pull in the changsets to my branch?
hg merge /path/to/baseline
Will my history show what was merged?
As long as I didn't touch those files, it will be automatic right?
You should really try all this out yourself! Make a couple of test repositories:
hg init main
hg clone main clone
and then experiment away. It's easy and safe since you're only playing around on your own machine. (This is actually what happens "behind the scenes" when you ask a question here: I try to make sure that the advice I give really works, so I normally have to run a few tests on a new repository to double-check.)
If you ran the tests, you would see that
You cannot give hg merge a path name (or URL) as argument. It takes a revision as the only argument. You need to hg pull /path/to/baseline to copy the changesets into your local repository and then hg merge.
The history will indeed show what was merged. A merge becomes a merge commit in Mercurial. That is a changeset with two ancestor changesets — both lines of development leading up to the merge are still in the repository.
Merges are without conflicts ("automatic") if the changes made in the two branhces don't overlap. If you edit different files in the two branches then there's certainly no overlap. But you can also edit different regions within the same file and still have a merge without conflicts.
There is a fine tutorial on the wiki and I've also written a beginners guide. I hope that helps.
I find myself doing the following a lot:
C:\Code>hg pull
pulling from http://server/FogBugz/kiln/Repo/Project/Rebuild/trunk
searching for changes
adding changesets
adding manifests
adding file changes
added 2 changesets with 4 changes to 4 files (+1 heads)
(run 'hg heads' to see heads, 'hg merge' to merge)
C:\Code>hg merge
4 files updated, 0 files merged, 0 files removed, 0 files unresolved
(branch merge, dont forget to commit)
C:\Code>hg commit -m "Merged"
C:\Code>hg push
pushing to http://server/FogBugz/kiln/Repo/Project/Rebuild/trunk
searching for changes
remote: kiln: successfully pushed 2 changesets
My question is, what is a better/more useful commit message to use after merging a pull from the repository. Are there any best practices that people use in distributed version control systems for this sort of thing?
If you use the fetch extension it automates the pull,merge step into one step, fetch. The message it auto-generates is something along the lines of "automatic merge". The hg developers seem to think this is reasonable as the extension is now distributed with the base.
Merge messages don't seem to be contain a particularly high amount of information. Your message seems reasonable.
[[ offtopic, we sometimes use them as an opportunity for a pun on the word merge]]
There is no one way so here is what I have tried to adhere to.
On commit messages:
Jus remember that those messages are the only strings that would connect you to some one who is try to decipher the reasons for the commit.
Key is to provide a description that is going to be a useful commentary on code development.
So when some one uses hg log , he has a nice commentary on how the software is being developed.
Some good practices:
Link it with your bug management system:
fixes #3456, new feature #2435 etc
or a more descriptive one of what changes it is bringing in the repo
Give credits
In fact, what I do mostly is. Look at
the current state of "hg log" and see
what useful message would mean a
logical progression in understanding the latest commit.
As long as "merg" is in the message somehow, we've had fun using the opportunity to fill our mercurial logs with hilarity. For example, we've used merge messages such as "real-estate mergage loans are at an all time low" or "a Merge Griffin television production."
You can collect all the newly added changesets' commit messages into a file by
$ hg log --rev 'reverse(p2():ancestor(p1(),p2())-ancestor(p1(),p2()))' \
--template '{desc}\n' \
> commit-message.txt
then manually edit commit-message.txt, and finally use it as the log message:
$ hg commit -l commit-message.txt
You could use the rebase extension, so hg pull --rebase would rebase your repo to the central repo's tip. This negates the need for merging after a pull.
I added an alias for it:
[alias]
pure = pull -u --rebase
Works well for us.
More details are at the RebaseProject page.
For mundane merges, where you're only working with one repository, I think just "merge" is fine. Usually you don't even know everything that got merged in because it's all other people's changes anyway.
The one time I would suggest being more verbose would be when you're working with more than one repository. If you have a devel repo and a stable repo, and you're pulling bug fixes in from stable, I would just mention that in the merge: "merging with stable". Those merges tend to be bigger, so it helps explain them to people who come along later.
I've been using Mercurial for a few weeks now and don't understand why when Mercurial comes to merge committed changes from two repositories it does it in the working copy?
Surely the merge could happen without the use of the working copy removing the need to shelf changes etc.
It just doesn't seem necessary to involve the working copy. Am I missing something?
There is only one working copy per repository, by definition:
The working directory is the top-level directory in a repository, in which
the plain versions of files are available to read, edit and build.
Unless your file system descends from Schrödinger's cat, you cannot have two versions of the same file at the same time, thus you cannot have two working copies.
Nevertheless, it's indeed theoretically possible to use something like a ephemeral clone (per #Ry4an) to act as the working copy of a merge, resolve conflicts there, commit, then make it disappear. You'd get a beautiful merge changeset and your intact working copy.
I can think of several ways to achieve this:
Petition hg team to do it in core
Write an extension to implement the ephemeral clone or some other way
Shelve with a temporary changeset
Shelve with MQ
I would strongly recommend #4, as I would for almost all workflow scenarios. It took me a few good days to grok MQ, but once I did I've never had to turn back.
In an MQ workflow, your working copy is always the current patch. So for the merge situation you would do:
hg qrefresh
hg qpop -a
hg update -r<merge first parent>
hg merge [-r<merge second parent>]
hg commit
hg update qparent
hg qgo <working copy patch>
You don't have to pop all patches in #2. I always do that whenever I need to deal with real changesets to avoid mixing them up with patches.
Solution #3 is really the same as #4, since a patch is a temporary changeset by definition (this is really the only thing you need for understanding MQ). It's just different commands:
hg commit -A
hg update -r<merge first parent>
hg merge [-r<merge second parent>]
hg commit
hg update -r<working copy changeset parent>
hg revert -a -r<working copy changeset>
hg strip <working copy changeset>
If you want to keep the working copy changeset and continue to commit, simply update to it in #5.
From your question it seems like you already know #4 but don't like shelving. I think shelving is good because merging is a fundamentally different task than coding (changing working copy), and shelving makes the context switch explicit and safe.
I didn't write Mercurial, so I can't say why they did it that way, but here are some of the positive results of that decision:
you can look over the results of the merge before you commit it
you can edit the results of the merge before you commit it
you're encouraged to commit frequently
If you really want to do a merge and have stuff in your working dir that you can't bear to commit don't bother with shelve just do:
cd ..
hg clone myrepo myrepo-mergeclone
hg -R myrepo-mergeclone merge
hg -R myrepo-mergeclone push myrepo
On the same file system clone is near instantaneous and uses hardlinks under the covers so it takes up almost no space past that of the temporary working copy.
As mentioned in the chapter "Merge" of HgInit:
The merge command, hg merge, took the two heads and combined them.
Then it left the result in my working directory.
It did not commit it. That gives me a chance to check that the merge is correct.
Such check can include conflicts in merge, that the user has to review:
In KDiff3, you see four panes
The top left is the original file.
Top center shows Rose her version.
Top right shows Rose my version.
The bottom pane is an editor where Rose constructs a merged file with the conflicts resolved.
So you need a working directory (a view for the merge) in order to resolve fully a merge.