Welcome back KungFooMasta! haven't seen you in a while!
As an old timer SVN user that learned to love Hg after roughly half a year of swearing:
In SVN you're used to have "one timeline" (the history log). You checkout, and commit. If there were changes, you may have to merge or even resolve conflicts after the checkout and before the commit.
The big disadvantage of this model is that you risk losing your changes if you make a mistake while merging. Additionally, if you're working on a particular feature that isn't ready yet, you can't commit otherwise you'll break everything for everybody.
In Hg... you have "multiple timelines" think of them as parallel universes. You made a change, then commit. Now you pull other timelines. Someone made changes. Let's call him Bob. So there are two different timelines: yours and Bob's. This is known as having two heads. You made one commit, Bob made also one commit. But both have the same parent.
Your first instinct will be to collapse both timelines into one. So that they look like one (and will appear cleaner, more SVN like). Either Bob's commit should come before yours, or yours should come before Bob's. DON'T. You can try to do this using patches or the rebase extensions. But stop fighting it. Hg is not meant to work like that.
Instead, you have to make a third commit: In this commit, both timelines will merge into one, and you'll have the chance of resolving the conflicts. Graphically, the log looks like a street that gets split in two and then joins back. May look ugly to you at first, but you'll get used to it and at some point wonder how you couldn't live without it (it has a lot of small advantages).
Now, patches usually fail at merges since they can't handle it very well, so that "HUNK failed" is probably that. There must be a merge in the middle of your patch.
Something that saves you a lot of time that wasn't obvious to me: When you want (i.e.) to merge two commits, you have to update to one of the commits, and then select the other commit that will be merged into the current active one. i.e. You can't be using commit C, and select A & B so they get merged as 'D'. You first have to be using either 'A' or 'B', and select the other one to start the merge.
KungFooMasta wrote:Is it possible Mercurial is quite a bit more complex to use compared to SVN? I remember TortoiseSVN being very easy to use for my personal projects. TortoiseHg feels like it has so many options, pulling, pushing, commit, import, export, tip, working directory.. the "task" approach they're using doesn't seem to help me accomplish any tasks..
At first it's overwhelming:
- pulling: Grab the other timelines (alternate universes!) that were pushed by everyone else
- pushing: Send your timeline's changes so that everyone else sees them and can pull them
- Commit: Commit
- Import / Export: Don't use this. They have a few uses. But seriously, for now forget them.
- Tip: useless jargon (it's the last commit that was pushed)
- Heads: How many alternate timelines there are that weren't merged. Public repos should avoid having more than one head, because there is no "true" choice. Both could be working. In your universe, D3D11 was improved. In Bob's universe D3D9 was improved. Which one is correct? Both! So if they merge, they'll create a single timeline again where both D3D9 & D3D11 are improved.
Everyone's workflow is this: Commit, Push, Merge, Pull.
The reason you see more options is when you want to start manipulating the history. Which is always nasty unfortunately. But that's a maintainer's job.
When you create a fork, you create an online clone of Ogre but where you have write access. You then commit your changes, push them. And then through a pull request... you request our repo to pull your changes and merge them.
The problem with SVN was that if you had changed 10 files, and Bob changed them too, then there was a high chance for you to screw up when you merge during your commit and end up with a broken repo (or worse, a repo that compiles but now manifests a bug that wasn't in Bob's version nor in yours).
In Hg, we can check that the bug doesn't manifest in your parallel universe nor in Bob's, but it does manifest after the merge. Thus we'll be able to identify that it wasn't your changes nor Bob's, but rather the merge process.
There are also other benefits: you can make multiple commits without having to worry about merging for a while, or commit even if internet is gone.
The disadvantage is that once you've pushed your changes, stripping them if you made a mistake is as easy as asking every torrent pirate to delete their mp4 video they obtained illegaly (practically unfeasable!). If you commit a 0.5GB file by accident and push it, God save us all (unless you're quick enough to strip it before anyone pulls, or agree with everyone to strip them from their repo as well).
Also, since there are parallel universes, revision numbers don't really make sense outside the local repo: To Bob, his commit was made first. Then when he pulled, he saw your changes and your merge. Bob's could be rev 2000, yours 2001, and the merge 2002.
To you however, your changes came first: Yours is 2000, Bob's is 2001, and the merge 2002.
This is why commits are best referred to using their hash (which is unique and the same for everyone)