Mercurial per feature work flow, single developer - mercurial

I've read similar posts of SO, the official Hg guide, many articles and guides, and it's still unclear to me what the best Hg workflow is for developing by feature. Maybe some of the articles on the web are years old and don't include the latest features from Hg. Obviously there's also a lot of options in how to approach it.
I'm a solo developer working on a project where a request for a fix or feature will be submitted to me as a task, like "Task #546 - Change whatever". Some of these tasks take a few days, and some tasks are open for months and there's often up to a dozen going at one time. A task is shipped to the final site after it's approved by the requestor.
The Hg guide seems to recommend having a clone per feature. But having a dozen full copies of the site on my drive seems... wasteful? I'm up for trying it, but I've seen other suggestions that make more sense. Do people really have a dozen copies of each site on their dev machine at a time?
Name branches at first sound like what I'd want, where's I'd name a branch "task 546" work on it, then merge it back in when it ships. I see a lot of discussion about the permanence of the names and having so many branches (though they can be closed). Some people seem to care about that and some don't. I don't know Hg enough to know if I care or not, and what the downsides really mean.
Finally, bookmarks seem to be popular with the more recent articles and it would seem that the best way to use them would be to set a bookmark like "task 546" then when you merge it back into the main branch using a commit message that has the task number in it to keep a reference to what was being done in the work. I know you can delete bookmarks, but it's unclear if I'd need to do this after the final merge.
So my thought for a combined approach is to have:
one repo
three named branches:
"default" which holds the released version of the site
"dev" on which I do feature development
"test" which would hold all of the tasks being reviewed by the client
on the "dev" branch I would use bookmarks for each of the tasks that I'm working on, so I'd have a head for each task
My workflow for a task/feature would be to:
Update to the main line of the "dev" named branch
Start a new branch using a bookmark for the task "task #123"
Commit changes until I'm ready for the client to review
Merge "task #123" into the "test" branch
Deploy "test" to the test server
Repeat the commit, merge, deploy until ready for production
When approved, merge with the main line of the "dev" branch with a commit message that includes the task name
Merge "dev" into the "default" branch.
Deploy the "default" branch to the live server
Merge "default" into the open feature branches
Thoughts? Would I be better off just having a clone for each feature, and a "live" and "test" repo that I push to?
Edit: I see from some links that I should be doing the development off of "default" so my first change to my listed process would be to use a name "production" branch instead of a named "dev" branch.

Bookmarks-style of branching (Git-like "branches") works poorly in, at least, two common cases
Cross-tasks merges in the process of development
Time-back machine, when you'll want to see "the whole history of changes for task#123" (you can do it visually and, with some grimaces and jumping, using revsets)
While using named branches haven't such problems and, btw, workflow with named branches (and only default branch as aggregation point) will be less complex and more logical way
Default contain only mergesets from task-branches, head of default is always "stable version"
Heads of named branches are WIP; branches, merged to default - finished (and accepted by customer - see below) work
Default, merged to task-branch (after development of task, before merging task-branch to default) is equivalent of your "test": without affecting mainline you can test final state of feature, integrated into your stable app, show results to customer
Accepted work added to stable mainline by merging named branch to default
History (full history) of changes for every task in the past can be easy restored by using single, easy, short, memorable revset for log: -r "branch(TASK-ID)"

I like it. +1. This is the way I'd do it.

Related

Can't push new heads - fail to see how they would be created

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.

Sourcetree, Mercurial and creating a debug branch

I've been trying to find actual documentation for Sourcetree without much luck, so I figured I'd ask here. I'm a relative newb when it comes to version control, with my current project being my first effort. I'm using Sourcetree on Windows 7 as a frontend for Mercurial, I've got my development code on my local machine in C:\inetpub, and whenever I do a Commit I then switch Sourcetree over to the cloned repository on my backed up network drive and do a Pull of the changes I just Committed so I've got the development history backed up.
What I'm trying to wrap my head around is using Sourcetree to set up a Debug branch so I can fix bugs on the version of the code running on the production server while simultaneously doing development. Obviously a common need, but I can't grok it. I am expecting there to be two code locations, so I can pause in mid-edit on the Development branch, make changes to Debug, and them come back to my changes in Development and finish them up before merging in the changes to Debug. If that's not how it works that's presumably part of my confusion. Any suggestions on where I can find clarity? Pointers to existing tutorials and the like would be fine, I just haven't been having luck searching Google, and I haven't been able to locate any actual Sourcetree documentation.
NOTE: Based on responses I've seen to other questions I've read about Sourcetree and Mercurial, I'll state upfront I have no interest in discussing outside repository hosting unless somebody can explain why it will help with this problem.
Two things here:
You do not need to change repository to pull, you can also push from your local repository;
You do not need 2 code locations for switching from one branch to the other. It might help, for larger projects, but I suggest you get comfortable with Mercurial before doing so.
So, for number 1, there is a default source or remote repository for every local repo. It is either defined by the user or it is the source repo from where it was cloned. Whether you push or pull, it will default to that same source. You can push/pull to multiple sources as well, but this is not your case at the moment. In the normal workflow, just issue a hg push every time you commit, and your changes will be propagated to the other repo.
For number 2, a Mercurial repo, as you already know, can have multiple branches. When you commit a changeset, it is automatically done on the current branch. In SourceTree, click on the Branch button, and enter a new branch name. The next commit you'll do will be the head (and the start) of your new branch. After that, you can update back and forth between the 2 branches, and your code will change accordingly. That means that you can update at any time to the head of any branch, make some changes, commit, and then jump to another branch, and so on. So no, you do not need multiple repositories.
Normally, the proper practice is to have a default branch (default name is rarely changed!) where you have your current development source. For every issue or feature you are fixing/implementing, create a new branch from the default branch to put your new code. Once that branch has been reviewed and tested, merge it back in the default and close the former.
For your current development, if you need an additional stable and safe trunk, you can create a Production branch, which would be the stable code that will run on your server. Once you are satisfied with the default branch tests, you can then merge it in Production to include your changes up to that point.
As a convention, make sure your server is always running the code from the Production branch, for the more stable code. At least, that is what I understood from your initial question.

Using Mercurial local clones for branched development?

I'm an ex SVN user trying to work out the best way to do branched development in hg. My project is fairly new currently has no branches. A friend of mine suggested that making a local clone of the repos. then working in that was better than using a named branch.
So if I use this model, would the workflow be:
[say original project has been cloned to be in c:\projects\sk\tracker]
hg clone https:[url of repos] tracker_featurex [to be issued from c:\projects\sk]
change to subdir tracker_featurex
checkin and push as per normal
[optional, how do I pull changes from the main repos. into this one?]
[final step, how do I get changes from this clone back into the main trunk?]
I need help on whether this workflow is correct and what the exact commands would be for the two steps in the [] braces.
Thanks a great deal to anyone who can help,
Fred
I would recommend you take a look at Steve Losh's post on branching in Mercurial: http://stevelosh.com/blog/2009/08/a-guide-to-branching-in-mercurial/
He goes over various types of branches (clones, bookmarks, named branches, anonymous branches) as well as the commands you would run for each. There are pros and cons to all of them. Local clones are ok if you are the only developer but they are not as useful in a workflow where more than one developer needs to work on a branch. The claim that clones are universally better than named branches is a myth. You should find a branching model that fits your workflow.
Update:
If you do want to do local clones you can move you changes using hg push from the new workspace (Assuming you have a Projects folder and a repo named test):
Projects> hg clone test test-new-feature
Projects> cd test-new-feature
Projects/test-new-feature> <do some work>
Projects/test-new-feature> hg commit -m "Work is done."
Projects/test> <Might need a pull/merge here>
Projects/test-new-feature> hg push
If there are changes in the test repo you need to pull/merge them before pushing.
You can also hg pull from the original workspace:
Projects> hg clone test test-new-feature
Projects> cd test-new-feature
Projects/test-new-feature> <do some work>
Projects/test-new-feature> hg commit -m "Work is done."
Projects/test-new-feature> cd ../test
Projects/test> hg pull ../test-new-feature
This might create multiple heads in the test repo and you would need to merge/commit.
Projects/test> hg merge
Projects/test> hg commit -m "Merged in new-feature."
Either are good options. I might recommend pulling rather than pushing. The main difference to me is the location of the merge step. I think pulling from the feature repo makes the history a little more readable.
I am fledgling to Hg, so take what I say with a word of caution :-)
I love having named branches, but use them very judiciously! There are downsides to the approach I use below, but it works well for my current environment which is a small shop. I don't mind preserving history forever and I'm not concerned with reducing the number of commits (but Mq/record/etc can address this latter bit).
This is how I use branches in the code I work on:
Default branch.
This is built on the build server.
This should only have one head.
This should always compile.
This should always be the "best effort" at completing bugs/features.
"Workbench" branch.
This can have multiple heads.
Anonymous branches are encouraged. Shared bookmarks used to "name" active anonymous branches.
The state should be almost always compilable, but it is not a requirement.
Represents "work in progress".
Okay, so this is what my process might look like this: (I've excluded pull/push/merge-theirs steps).
I get a bug report in.
I switch to "workbench" tip (or whatever revision is appropriate).
I fix the bug, possibly committing several times. (I really should learn to use queues or record, etc.)
(If I am interrupted in the above process, e.g. have to work on a different bug, or am otherwise side-tracked I will create a new head above where #2, or as appropriate. I may give the current anonymous branch tip a name with a bookmark, or I may not.)
Once complete, I merge the relevant branch/changes into "default" and hopefully the build server still loves me :-)
I think the best thing to do is forget about how branches in SVN worked. They are not liked named branches at all and anyone who says otherwise is latching onto the fact they both have "names" and not much more. Every branch in Hg is part of a "named branch" (that is, has a name associated with it, be it "default" or "workbench" or otherwise). But it doesn't matter, except for organization: a branch is a branch and it doesn't matter if it's referring to the "tip" of an anonymous branch or the tip of the only head (really an anonymous branch itself) in a named branch.
Try a few things, use what works best :)
making a local clone of the repos. then working in that was better than using a named branch.
Overly dramatic and ambitious statement in common. When you clone-per-feature, you have only one branch (named branch) per repo, but nothing more (practically, briefly speaking).
When feature is finished, you have to "push to parent"|"pull from clone" in order to return changes back. At this stage, if some work was done in parent repo after clone, anonymous branch will appear (+1 head) and merge is a must (same as for work in named brach in one repo), but, it named brach can tells something fast later (you use good names, isn't it?), anonymous branch tells almost nothing without additional tricks (bookmarks, f.e). Part of my repo below as example of work in clone with intermediate pulls and must-merges after pulls/ (sorry, russian commit-messages) and even I can't recall now, why I had repo cloned for editorials - maybe I just play with Clones-Workflow

how does QA test code and merge with a stable branch in mercurial?

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.

Moving from Subversion to Mercurial - how to adapt the workflow and staging/integration systems?

We got all psyched about from from svn to hg and as the development workflow is more or less flushed out, here remains the most difficult part - staging and integration system.
Hopefully this question goes a bit further then your common 'how do I move from xxx to Mercurial'. Please forgive long and probably poorly written question :)
We are web shop that does a lot of projects(mainly PHP and Zend), so we have one huge svn repo, with like 100+ folders, each representing a project with it's own tags,branches and trunk of course. On our integration and testing server(where QA and clients look at work results and test stuff) everything is pretty much automated - Apache is set to pick up new projects automatically creating vhost for each project/trunk; mysql migration scripts right there in trunk too and developers can apply them through simple web-interface. Long story short our workflow is this now:
Checkout code, do work, commit
Run update on the server via web interface(this basically does svn up on server on a particular project and also run db-migration script if needed)
QA changes on the server
This approach is certainly suboptimal for large projects when we have 2+ developers working on the same code. Branching in svn was only causing more headaches, well, hence moving to Mercurial. And here is where the question lies - how does one organize efficient staging/integration/testing server for this type of work(where you have many projects, say single developer could be working on 3 different projects in 1 day).
We decided to have 'default' branch tracking production essentially and then make all changes in individual branches. In this case though how can we automate staging updates for each branch? If earlier for one project we almost always were working on trunk, so we needed one DB, one vhost, etc. now we potentially talking about N-databases per project, N-vhost configs and etc. Then what about CI stuff(such as running phpDocumentor and/or unit tests)? Should it only be done on the 'default'? On branches?
I wonder how other teams solve this issue, perhaps some best practices that we're not using or overlooking?
Additional notes:
Probably worth mentioning that we've picked Kiln as a repo hosting service(mostly since we're using FogBugz anyway)
This is by no means the complete answer you'll eventually pick, but here are some tools that will likely factor into it:
repositories without working directories -- if you clone -U or hg update null you get a repository with no working directory (only the .hg). They're better on the server because they take up less room and no one is tempted to edit there
changegroup hooks
For that last one the changegroup hook runs whenever one or more changesets arrive via push or pull and you can have it do some interesting things such as:
push the changesets on to another repo depending on what has arrived
update the receiving repo's working directory
For example one could automate something like this using only the tools described above:
developer pushes five changesets to central-repo/project1/main
last changeset is on branch 'my-experiment' so csets are automatually re-pushed to optionally created repo central-repo/project1/my-experiment
central-repo/project1/my-experiment automatically does hg update tip which is certain to be on the my-expiriment branch
central-repo/project1/my-experiment automatically runs tests in its working dir and if they pass does a 'make dist' that deploys, which might set up database and vhost too
The biggie, and chapter 10 in the mercurial book covers this, is to not have the user waiting on that process. You want the user to push to a repo that contains possibly-okay-code and the automated processed do the CI and deploy work, which if it passes ends up being a likely-okay repo.
In the largest mercurial setup in which I've worked (20 or so developers) we got to the point where our CI system (Hudson) was pulling from the maybe-ok repos for each periodically then building and testing, and handling each branch separately.
Bottom line: all the tools you need to setup whatever you'd like probably already exist, but gluing them together will be one-off sort of work.
What you need to remember is that DVCS (vs. CVCS) introduces another dimension to versioning:
You don't have to rely anymore only on branching (and get a staging workspace from the right branch)
You now have with DVCS the publication workflow (push/pull between repo)
Meaning your staging environment is now a repo (with the full history of the project), checked out at a certain branch:
Many developers can push many different branches to that staging repo: the reconciliation process can be done in isolation within that repo, in a "main" branch of your choice.
Or they can pull that staging branch in their repo and test things out before pushing back.
From Joel's tutorial on Mercurial HgInit
A developer don't necessary have to commit for other to see: the publication process in a DVCS allows for him/her to pull the staging branch first, reconcile any conflict locally, and then push to the staging repo.