I have run into an interesting situation that I do not know how to describe. So I here is a screenshot of it (note that two programmers are working here with a central repository that both synchronize with):
The image on the left is updated to the other programmer's core (which is now the head) and the image on the right is updated to my core before the merge to dev.
As you can see, I have one Core branch #372 merging into Dev. The other programmer forgot to merge with my changes at #372 (which I had already pushed to the central repository before this changes from 375 and onwards) and continued on.
So now I have a core branch that merged into dev, and is sort of left headless. The other programmer's core is now going to be the one I am going to start with. That is not an issue. What is an issue is seeing two cores and the messy tree with confusing branching.
What can I do to end up with one core branch only? Or is this ok to have?
As you can see, I have one Core branch #372 merging into Dev. The other programmer forgot to merge with my changes at #372 (which I had already pushed to the central repository before this changes from 375 and onwards) and continued on.
That's not what I see. #372 is a parent of #373 on both sides. Both graphs, if you remove #381+ and #372+, are the same. They've been drawn differently just because the parent of the current working copy is different.
Granted, it looks a little odd, but there's no issue here. After #372+ is committed, it will need to be merged with #381 (or whatever the current Core head is by then) at some point, but that's nothing exceptional.
Right now, Core actually has 0 topological heads since changesets 381 and 372 were both merged with dev. On your graph you see that long line extending from changeset 372 because your working directory is on that changeset right now. The line is indicating that any commits you make will be children of 372. The other programmer's working directory is on changeset 381, which is why his graph looks different. Once you update to 381 your graph will look the same as the other one.
So to answer your question, this won't be an issue since Core's branch heads have all been merged into dev. Also if you did end up with multiple topological heads on Core, mercurial would warn you about it when you pulled in the new head.
Related
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
My dev team is just starting out with Mercurial and we're confused on the following point:
We are a php webdev team.
We have 3 developers. Most of what we are doing now is bugfixes on a very new product. Also doing some new feature development.
We have 2 QA people. Every bugfix and feature must be tested before it is allowed to go live.
So far, each developer has his own repository. We have a central sever called WebDev with it's own repo. A developer pulls from WebDev, then makes some changes (ie, fixes a bug), and pushes to Webdev. Then a QA tester will test the code on the central server (so testing on the code in WebDev) and if it works, he will push that code to our production server.
This does not work well, because... what happens when Developer-1 (dev-1) fixes a bug, and pushes to WebDev. At the same time, dev-2 fixes a different bug and pushes to WebDev. the QA person tests the code there, and approves the second bugfix but not the first. How would he push the second changeset to production without the first one as well? We seem to be losing all the advantages of a version control system.
I've read up a lot on branching, but I cannot figure out how to make this work for us... do we create a new branch for every bugfix and new feature, and the only after it is tested, QA will merge into the default branch on WebDev? Is that the best way, or is there something I am missing?
Thanks!!
----UPDATE----
thanks to everyone who answered so far. here is where i am holding now... i can think of two solutions.
1) dev-1 fixes a bug for bug-101. he pulls from webdev, merges and commits locally. he sets it in-testing. QA pulls directly from his repository, and test locally. if it passes, QA will pull from webdev ->merge -> push to webdev (and if its a big change, can review again there to make sure it is fine). so we are only testing one thing at a time, WebDev only contains changes that have been tested locally by the testers and is always stable.
2) create branches for everything. dev-1 creates branch "bugfix-101" then pushes to webdev without merging it. QA can test the branched code, and if it's approved, merge it with the default branch. I have four questions on this method - (a) is it possible to push an open branch to a remote repository? (b) if QA merges and closes the branch on webdev, the next time i pull, will my local repo also close and merge the branch? and (c) how do you test from the branched code? when i run the web app in the browser, how do i test from the branch?? (d) are there performance issues with creating so many named branches (assuming that most of them will get closed quickly)?
Thanks again.
Folow up to Bassam:
Your team is obviously missing the (really easy) branching and merging in Mercurial and working with a monolitic (?) default branch.
Just change your thinking and workflow slightly and you will see a big difference:
Each QA-member has a permanent clone of the repo and only pulls a developer's repo on request (it's faster, pulled changes are more visible); maybe branch QA also have sense
Use a separate branch for each and every big change (feature or bugfix)
When a dev has a changeset X in branch "Bugfix Y" in his repo finished and ready to test, he asks QA to "pull and test changeset X"
QA does that, maybe merges "Bugfix Y" to the "QA" branch in his repo (as a "test passed" sign?) and merges the "QA" branch to mainline ("Stable" or "default" branch), and finally pushes the results to needed destinations (WebDev and Prod?)
On every next request step 4 must n\be repeated
This way you never mix in one approve-cycle more than one development action
This is a good place to use tags. Have either the dev or qa person tag the release containing only the changes they want, and then the qa person can clone the repository at the tag level (or update the repository to the tagged changeset if that fits better for you... your preference). Then do the test using the tagged version of the code.
As a side note, it would be worth looking into these two answers on the Kiln stackexchange site to see Fog Creek's repository strategies (see how they eat their own dog food):
http://kiln.stackexchange.com/questions/354/release-repo-suggestions/355#355
http://kiln.stackexchange.com/questions/500/should-i-use-more-than-one-repository/504#504
Update
There is a good description in this post about why it is better to fix bugs in a stable branch and push them back to dev, while using a dev branch for features (which get pushed back to the stable branch as well... two way pushing/pulling). This is how we do it as well. It is not directly answering your question, but is related enough that I thought I'd include it.
Creating branches with Mercurial is a breeze, use that :) I would create separate branches for different feature and different bugs and have the QA person merge them to the main branch whenever the ensure that a bug is fixed.
Another alternative is to use named branches which is essentially the same thing but instead of seperate branches, your named branches is going side by side with the default branch until they are ready to be merged in.
Note: We have been alternating between both strategies at my work place.
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
My development env: Windows 7, TortoiseHg, ASP.NET 4.0/MVC3
Test branch: code on test server
Prod branch: code on production server
This is my current branching model. The reason to branch out every task (feature) is because some features go to live slower. So in above graph, task 1 finished earlier (changeset #5), and merge into test branch for testing. However, due to bug or modification of original request, changesets #10, #12 have been made. While task 2 has finished testing #8 and pushed to live #9 already.
My problem is every time when modifying task branch (like #10, #12), I have to do another merge to test branch (#11, #13), this makes the graph very messy.
Is there any way to solve this issue? Or any better branching model?
It really sounds like you are trying to implement a feature branching strategy. However, based on your diagram, I think you're missing a few steps and/or are merging the wrong branches. In essence, you should probably have more like 4 lines of development there, plus 1 representing all feature branches. Unfortunately, I have not been able to find a nice diagram, except for one talking about Git and a workable branching strategy here. The diagram, though, better explains what you are looking for, even if you are using a different DVCS like Mercurial (my fav). Using Steve Losh's Guide to Branching in Mercurial and the Hg Book, you should be able to implement a good feature branching strategy that works for you. Steve's got pros/cons for each approach.
And, no, you don't need to clone to branch properly. Mercurial has named branches that allow you to switch between branches easily if you are commonly working on multiple unfinished items and/or performing code reviews/testing for other developers. With any kind of Web-based development with IIS, named branches are easier to work with as things don't move and different version can continue to work with the same configuration under IIS.
I must say, though, that feature branching or whatever name you give it is almost always a bad idea as branches that run too long (say, a year, which I have seen with disastrous results) can be almost impossible to merge back in unless you are frequently (daily) managing synchronization between the feature branch and its parent. This type of maintenance overhead is not worth the trouble and you're better off sticking to trunk-based development with release branches for bug fixes and fix your code to abstract code that is production-used and unfinished work.
When you want to work on a new feature, you better make clone from test repo. Branches in mercurial are supposed to stay unrelated... Imagine that you made a release v1.0 and going to work on v2.0 of your application (default branch). You will create branch v1.0 to keep it updated with bug fixes.
You can use separate repositories for each branch instead. Then rebase the changes on the latest changeset. This could reduce the number of merges.
I'm going through Bitbucket and I can't seem to find any Mercurial repositories that look like what I suspect our repository would look like, provided we switch to Mercurial.
As such, I'm wondering, is there a workflow that we're not considering here?
The thing I'm talking about is that I did a small automated test. We're 14 people that work on the same project, split into 4 scrum teams. To simulate 14 (I picked 10, round number) people working in parallel on the code, using Mercurial DVCS, pushing to the same central master repository, I wrote a script.
I created a new "master" repository, and then cloned it for 10 virtual people
I then ran a 1000 iteration loop, picking a random clone, and doing one of the following:
10% of the time, do a pull from master, merge, commit merge, and push
90% of the time, do a local change and commit
Note that I ensured that there would never be merge conflicts by simply making each virtual person work on his own file.
This would simulate people working locally by doing 1+ commits before pulling, merging, and pushing (to avoid 2+ heads in the master repo). It might be that this workflow is wrong.
This is a sample of what the repository now looks like (screenshot + link to repo):
The repository can be found here: http://hg.vkarlsen.no/hgweb.cgi/parallel_test/graph. Unfortunately this repository is no longer available and I no longer have a copy of the code due to an unfortunate backup incident, but this was just an example for people to visit, it should not be important any more
This looks awfully messy, and as I said, I can't seem to find any repositories that have similar history. By "messy", I mean that it looks like older history of the project will almost always have 10 parallel branches. Close to the top, it tapers off of course, but it will expand as people that are currently working in their local repository pushes to the master.
So I have two questions:
Can anyone show me a repository that has similar history? Since I can't seem to find any, I'm starting to wonder about what kind of conclusions I can draw from that...
Is there something wrong with our workflow (that is, the workflow I've laid out here)? Should we rebase/squash/transplant, delegate push responsibility to one person, other things, instead of the way it was done here?
Impressive preparation!
It always looks messy if you go back a bit and look at all old commits at the same time. It always tapers of, even looking at a small bit old history. See http://hg.intevation.org/mercurial/crew/graph/12402?revcount=120 for instance. This is not the most recent commit, but shows all history up to that commit.
Rebase helps quite a lot, especially if persons are working on separate areas. (I usually check the incoming commits to see if there are potential file or functionality conflicts, and if not, I do rebase.)
Rebase is not fool-proof though, so merge is the preferred "safe" action, but it leaves more "garbage" in the history. A trade-off.
Rebase is sort-of like the bog standard SVN update. The existing stuff is made baseline and your changes go on top, cross your fingers it still works. It's useful, but there are times when you feel safer having yours, theirs and the merge as separate commits in the history.
There is also commit-squashing as an option (histedit extension maybe), which squashes all in-between commits to one. This is useful when you're about to push and want to transferring many partials commits in your own repo as a single commit to the main.
I have 12 developers working in the same Mercurial repository at work, and our history looks nothing like that. There are occasional merge commits, but most merges are from merging actual branches, i.e there might be a merge in our main development branch bringing in changes from a bugfix release made on the production/release branch.
This is very easy to achieve, developers hack and commit to their local repository and when they have something stable enough to share with the rest of the team they push.
If nothing has been committed since they started committing the push goes through without problems.
If someone else has committed a change, Mercurial complains that the push will create remote heads. The developer then does a hg pull --rebase and retries the push. The push goes through and everyone is happy.
If you are using continuous integration with developers regularly pushing to a shared repository, this is the way to go. Knowing whether you have pushed changes or not is easy and you avoid lots of useless merge commits cluttering up your history.