2 main branches:
stable - used for release and for hotfixes.
default - used for all other development and all features
Please see revisions 8 and 9 specifically. I added a 2 separate features in revisions 3 and 4, worked on them separately, merged them into default in revisions 7 and 8. They are not complete at this time.
My question is, did I do this correctly considering that I am not done with the features and did not close the feature branches? The connected blue and pink lines at revision 8, along with the blue extension at revision 9 are confusing me.
I'm pretty new to source control, so any explanations are appreciated.
You just have two heads on your tree, which are at revisions 8 and 9 specifically now. You could run "hg heads" on the command line in that directory to see some textual information about them both. At this point, you could update to either head, make changes and commit, then update to the other head, make changes and commit, etc. Also, you could merge your feature branch into the default and then just have one head. It depends on how long you want to keep your feature branch separate.
More interestingly, are you planning to keep using the "stable" branch? If so, I guess that you could "hg update" to r1, and then merge things from your other branches to there.
Side note: You may be interested in reading about "hg flow", and its branching model. See for example:
https://andy.mehalick.com/2011/12/24/an-introduction-to-hgflow
http://www.carl-berg.se/post/hgflow-git-flow-for-hg
Related
I'm fairly new to version control in teams. So far I've mostly used it solo.
I've read that the following workflow is recommended:
Commit locally, pull master, merge master into my branch, merge my
branch into master, push. Several times a week or even day
So that's what I tried to do. However, when I was done with my feature, and tried to push, tortoise hg told me, that this would create new remote heads.
hg help push tells me about two options:
Merge first: Did that
Use -f: I know enough not to do that.
I think I understand the concept of rebasing - which I don't think applies here, since I'm the only one who did anything in this commit tree. Of course I've pulled.
So my question is: How can I resolve this specific situation?
Also, recommendations for where to learn proper version control workflow would be nice. Everything I find tells me what the commands are, but I've failed to find clear instructions on when to use them.
I've added a picture of the project. Commit 147 was mine, and I could push it just fine. All oher commits are also made by me.
hg reports a "head" for every named branch. In your screenshot, you are needing to push rev 154, which is the head of your kjeld branch. It is an outgoing changeset because you are pushing rev 155 and you must therefore push 155's entire history as well. Others will get that branch when they pull your changes and will have a head on their version of kjeld (note that it will most likely not be numbered 154 since those numbers are repo specific). You will be fine though since that head is a close-branch changeset so it will not appear in their default list for hg heads and hg branches.
One way to avoid your current issue is to use bookmarks to temporarily note what that head represents e.g. issue-45, big-feature-2, etc. and only push when merged into mainline development.
For us, we set up a "private" repo for each dev on the server where they store/backup work in progress. It is expected that there are multiple heads, dead branches, and other gunk in these "private" repos. The dev repo, however, only ever has a single head and must pass the build and build tests.
In response to your comment about your "private" branch: When you push your tip you will also push your branch named kjeld. Others who want to work on that code must pull it to get the tip of your development. It will not be a "private" branch.
Say I do my new feature development either in default, or an entirely new branch made just for the feature for a web site project. When it comes time to push the feature out to the live website, I want to move it to the live branch, which I then hg archive to my apache directory.
Throughout everything, I want to be absolutely sure not to push other, unrelated changes that are not yet ready to be published to the live branch.
Is this even a good idea? Or should I be doing something entirely different?
If the code is in default, how do I push only the one thing I need and not everything to live? If I push just the latest changeset, is it smart enough to send the latest version of those files, or will it only do the changesets?
If the code is in an entirely new branch, do I merge the whole branch into live? How do I get those changes back to my default branch so I see them there too?
I was reading the "Task Based Management" section of the Mercurial Kick Start guide and it mentions merging default into your branch. I found this very confusing and was wondering why you'd ever do this.
Thanks for any help you guys can provide.
[edit]
I'm using TortoiseHG BTW
[/edit]
HG now has Phases. Change a phase of a changeset to secret and it will not be pushed when you use push. You can do it using TortoiseHG GUI.
In addition to that, be aware that just pushing or pulling something does not automatically change any files in the working directory. It only makes some additional changesets available. Only by using update do you actually change any files in your working dir. (unless you configure hg to update automatically).
In the example you linked, there is a bug fix in the default branch. Bob wants to have this fix in his branch too, so he merges default branch with his branch. This is just an example to see how branching works. You do not have to use it in exactly the same way. If you just begin your Mercurial adventure, then you should better use just one branch until you have a good reason to use more.
For example: 3 developers work on the same project and all of them use just one branch (default). 1 of the developers wants to do a major refactoring of the code. He wants to commit several very unstable changesets (many "in the middle of work"). Doing so in the default branch might upset other developers. That is a good reason to create a branch. After his version is stable enough he will merge his branch into default. While he is doing development in his branch, he wants to be up-to-date with other developers, so he frequently merges default into his branch. Staying in a separate branch for too long might result in difficult merges. Luckily merging is very quick in HG, so merge often.
This question already has answers here:
Mercurial: Merging one file between branches in one repo
(5 answers)
Closed 2 years ago.
Reading up on Mercurial, it seems to always branch and merge the complete repositories.
Is it possible to just merge some files from one branch to another? (For example I may only wish to merge in the files that fix a given bug.)
Likewise can I cherry pick some change sets, but still have a correct merge record, so if a complete merge is done later it is correct?
I am coming from a perforce “mindset” so may be thinking about this the wrong way.
Yes, Mercurial always branches and merges the whole tree. You don't have the "flexibility" that something like perforce gives you to select individual files for a merge. This is a good thing (trust me). Changesets are atomic (you can't split them) and immutable (you can't change them). Hence this needs a little bit of a mindset change.
Changesets should be targetted at one task, and one task only. If you're fixing a bug, nothing else goes in the changeset apart from the bug fix. You've then got a changeset which documents that bug fix, and you haven't got the problem of wanting to split it. It wouldn't make sense to want to. Half a bug fix is often worse than no bug fix.
When it comes to merging that there's a couple of options:
One school of thought says you should go back to where the bug was introduced. Fix it. Commit (making a small anonymous branch), and merge that forward onto whatever head you want it on (dev, stable, release, whatever). This isn't always practical though.
Another method is fixing the bug in the release branch, and then merging to the development branch. This normally works well.
Alternatively you could fix it at the head of your development branch, but then if you merge it onto your release branch you'll bring over all your development changes. This is where graft (new in 2.0) and the older transplant extension come into play. They allow you to "cherry-pick" a single or range of changesets from another branch and place them on another branch.
Reading up on Mercurial, it seems to always branch and merge the
complete repositories.
Yes
Is it possible to just merge some files from one branch to another? (For example I may only wish to merge in the files that fix a given bug.)
Just touch only "some files" in needed changeset and merge branch with this changeset in head with another branch or transplant in any time
Likewise can I cherry pick some change sets, but still have a correct merge record, so if I complete merge is done later it is correct?
Yes, you can transplant| any changesets to another branch, applied state will be remembered and changes will not be duplicated on final merge
We have these Mercurial repositories:
Trunk
|
|
|---------myapp_1_0_23 (created off release 1.0.23)
|
|---------myapp-newstuff (created off rel 2.0.4)
Release schedule (nothing yet released):
v1.0 from myapp_1.0.23, any add'l changes in this repo will get merged to the trunk
v2.0 from the trunk
v3.0 or v4.0 released based on a merge of myapp-newstuff and the trunk. At the time of the merge the trunk may have v2.0 code or some new features that we'll release from the trunk as v3.0
After making changes in myapp_1.0.23, we merge them to the trunk, but let's say we also need them in myapp-newstuff so we also merge them there. What then happens when we eventually merge myapp-newstuff code to the trunk?
The trunk already has changes made in myapp_1.0.23 so what happens when we merge those same changesets from myapp-newstuff back to the trunk? Will Mercurial be smart enough to know those changesets are already in the trunk?
Mercurial will handle this situation just great -- because you're using 'merge'. When you're using export/import (or transplant), cherry picking as it's called, and you have the same changesets in there multiple times with different node ids (due to different parents) then Mercurial can't know "Oh, this one's already here". However, so long as you're merging Mercurial will do a great job of saying "oh, this repo already has that changeset so I don't need to re-apply it".
The general rule of thumb is: "Make every change with as early a parent as you can and then merge down". If I have a bug that's in version one, two, and three, I fix it in one and then merge into two and then merge into three. If instead you fix it first in three, then you have to try to get it into two without bringing all the other changes in version three with it -- which is hard and often requires the very cherry picking we're trying to avoid.
The problem that I'm running into is that I have some code reviews to do, with ~10 commits per review. It's an active repo with constant commits from developers. I have TortoiseHg filtering my changesets so that I am looking only at the ones that I care about.
What I would like to see is the difference between the changeset before the first change, and the last (without all the non-related changesets showing). I simply want to see the final results of all these changes. I don't care that there was some horrible code in changeset 1, that was fixed in 3. I just want to see the diff of what ultimately got merged through all these changesets.
I feel like I'm missing the obvious, and this isn't a bright question. Nevertheless, I'm asking anyways. Anyone?
I'm not sure about 1.1.8, as I'm using the 1.9/2.0 candidate release, but I believe you could left-click on changeset1, right-click on revision3 and select visual Diff. This should open your diff tool of choice and only show you the diffs between the 2 versions.
When I did this in the newer tortoise, it opened BeyondCompare in directory compare mode, with revision1 on one side, and revision2 on the other.
Don't merge in between commits and diff off the developers clone between start and finish changesets.
Or If merges occured, update and merge everything and then take the entire codebase (or just changed files) and dump it onto a clean tip clone (make sure you are working with the same version to avoid overwriting anything). Recommit all at once.