Fairly new to using mercurial and a little confused as to a good approach to take for seperating live code from dev code. I come from using PureCM where everything was divided into Streams and you could simply merge one Stream to another. My goal is to set something up in mercurial that behaves similarly.
Ideally, whatever avenue I take would also include a path for easily merging dev code to live code while maintaining the change set history.
What approaches are available and any documentation on how it is done?
Branches are what you want. You can make a stable branch and a dev branch (and any other branches you might want) and merge any changes from the dev branch into stable when you see fit.
For example, say you have a repo with no branches (besides the default) and you want a dev branch and a stable branch. First thing you do is make the dev branch
hg branch dev
Now your working copy is on branch dev and any commits you make will be on dev. If you type hg branches now it should say
dev
default
To switch back to the default branch type hg up default
And finally, if you want to merge changes from the dev branch to default you would type
hg up default # update to the default branch
hg merge dev # merge changes from dev into working copy (default in this case)
If your repository is published using hgweb you can also see a nice graph of the commits and branches on there.
Disclaimer: I've never used PureCM, but googling it I find that it's not a distributed model. So I'm coming at my answer from that direction.
It sounds as if you might be struggling more with how distributed version control works. This is one of the fundamental differences between distributed and non-distributed source control (and in my opinion, one of the big wins that it gives you).
Since you are not bound to a central repository, your 'live' code is just another clone of any particular repository. Technically speaking, all clones that you make of any code that you have of a distributed source control system count as a 'branch' (which may or may not be like streams from PureCM, though I have a feeling they're similar). That said, if you have a central repository that all your developers pull from, all you need to do is just clone a copy of your code at whatever point you're going live with it, and that's your live 'branch'. That way your developers keep working with the most recent code, and keep merging with the most recent, and you have an entire repository that is just the code you've got live.
So long story made long, it's just another clone. That make sense?
As a side note/example, the way that my current workflow goes with one of my projects, we use our 'central' DVCS repository as the place where the extra clone goes. So we have our primary "app" that everyone pulls from, and then we have "app-release-1-1-11" (which includes the date it went live). So that the released code is also available on the central repo. Hope that helps!
Check out the hginit.com tutorial - this covers some standard strategies.
What we do is have separate repositories, we'll have a prod support repository and a dev repository. Maintenance changes to prod support get merged back into dev.
Related
I have four devs working in four separate source folders in a mercurial repo. Why do they have to merge all the time and pollute the repo with merge changesets? It annoys them and it annoys me.
Is there a better way to do this?
Assuming the changes really don't conflict, you can use the rebase extension in lieu of merging.
First, put this in your .hgrc file:
[extensions]
rebase =
Now, instead of merging, just do hg rebase. It will "detach" your local changesets and move them to be descendants of the public tip. You can also pass various arguments to modify what gets rebased.
Again, this is not a good idea if your developers are going to encounter physical merge conflicts, or logical conflicts (e.g. Alice changed a feature in file A at the same time as Bob altered related functionality in file B). In those cases, you should probably use a real merge in order to properly represent the relevant history. hg rebase can be easily aborted if physical conflicts are encountered, but it's a good idea to check for logical conflicts by hand, since the extension cannot detect those automatically.
Your development team are committing little and often; this is just what you want so you don't want to change that habit for the sake of a clean line of commits.
#Kevin has described using the rebase extension and I agree that can work fine. However, you'll also see all the work sequence of each developer squished together in a single line of commits. If you're working on a stable code base and just submitting quick single-commit fixes then that may be fine - if you have ongoing lines of development then you might not won't want to lose the continuity of a developer's commits.
Another option is to split your repository into smaller self-contained repositories.
If your developers are always working in 4 separate folders, perhaps the contents of these folders can be modularised and stored as separate Mercurial repositories. You could then have a separate master repository that brought all these smaller repositories together within the sub-repository framework.
Mercurial is distributed, it means that if you have a central repository, every developer also has a private repository on his/her workstation, and also a working copy of course.
So now let's suppose that they make a change and commit it, i.e., to their private repository. When they want to hg push two things can happen:
either they are the first one to push a new changeset on the central server, then no merge will be required, or
either somebody else, starting from the same version, has committed and pushed before them. We can see that there is a fork here: from the same starting point Mercurial has two different directions, thus a merge is required, even if there is no conflict, because we do not want four different divergent contexts on the central server (which by the way is possible with Mercurial, they are called heads and you can force the push without merge, but you still have the divergence, no magic, and this is probably not what you want because you want to be able to checkout the sum of all the contributions..).
Now how to avoid performing merges is quite simple: you need to tell your developers to integrate others changes before committing their own changes:
$ hg pull
$ hg update
$ hg commit -m"..."
$ hg push
When the commit is made against the latest central version, no merge should be required.
If they where working on the same code, after pull and update some running of tests would be required as well to ensure that what was working in isolation still works when other developers work have been integrated. Taking others contributions frequently and pushing our own changes also frequently is called continuous integration and ensures that integration issues are discovered quickly.
Hope it'll help.
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.
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.
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.
Subversion shop considering switching to Mercurial, trying to figure out in advance what all the complaints from developers are going to be. There's one fairly common use case here that I can't see how to handle.
I'm working on some largish feature, and I have a significant part of the code -- or possibly several significant parts of the code -- in pieces all over the garage floor, totally unsuitable for checkin, maybe not even compiling.
An urgent bugfix request comes in. The fix is nice and local and doesn't touch any of the code I've been working on.
I make the fix in my working copy.
Now what?
I've looked at "Mercurial cherry picking changes for commit" and "best practices in mercurial: branch vs. clone, and partial merges?" and all the suggestions seem to be extensions of varying complexity, from Record and Shelve to Queues.
The fact that there apparently isn't any core functionality for this makes me suspect that in some sense this working style is Doing It Wrong. What would a Mercurial-like solution to this use case look like?
Edited to add: git, by contrast, seems designed for this workflow: git add the bugfix files, don't git add anything else (or git reset HEAD anything you might have already added), git commit.
Here's how I would handle the case:
have a dev branch
have feature branches
have a personal branch
have a stable branch.
In your scenario, I would be committing frequently to my branch off the feature branch.
When the request came in, I would hg up -r XYZ where XYZ is the rev number that they are running, then branch a new feature branch off of that(or up branchname, whatever).
Perform work, then merge into the stable branch after the work is tested.
Switch back to my work and merge up from the top feature branch commit node, thus integrating the two streams of effort.
Lots of useful functionality for Mercurial is provided in the form of extensions -- don't be afraid to use them.
As for your question, record provides what you call partial commits (it allows you to select which hunks of changes you want to commit). On the other hand, shelve allows to temporarily make your working copy clean, while keeping the changes locally. Once you commit the bug fix, you can unshelve the changes and continue working.
The canonical way to go around this (i.e. using only core) would probably be to make a clone (note that local clones are cheap as hardlinks are created instead of copies).
You would clone the repository (i.e. create a bug-fix branch in SVN terms) and do the fix from there.
Alternatively if it really is a quick fix you can use the -I option on commit to explicitly check-in individual files.
Like any DVCS, branching is your friend. Branching a repository multiple ways is the bread and butter of these system. Here's a git model you might consider adopting that works quite well with Mercurial, also.
In addition to what Santa said about branching being your friend...
Small-granularity commits are your friend. Rather than making lots of code changes in a single commit, make each logically self-contained code change in its own commit. Then it will be a lot easier to cherry-pick changes to merge between branches.
Don't use Mercurial without using the Mq Extension (it comes pre-packaged in the default installation). In addition to solving your specific problem, it solves a lot of other general problems and really should be the default way that you work (especially if you're using an IDE that doesn't integrate directly with Hg, making switching branches on the fly a difficult way to work).