Mercurial bookmarks - utilization for development and stable versions - mercurial

This is NOT another what are bookmarks/what are branches question - I have read all of these posts and now want to clarify some things about correct usage.
I am developing a website. I want a stable version, and a development version.
So I create two bookmarks 'stable', and 'development'.
If i want to create a new feature I update to the development bookmark, and create my feature.
If i want to correct a typo I do it directly in the stable version.
My confusion is as follows.
I have a central repository at bitbucket.
If i use hg push my bookmark data is not passed. If i do hg push -B stable or hg push -B development respectively then my bookmark data is pushed.
I then have two servers, a testing server and a live server.
If I ssh onto the server and do a hg pull from bitbucket because the bookmarks are not present on the server, what is pulled, and what then is the working copy updated to when I use hg update?
The correct usage for what I want, I believe is as follows. A local repository with my two bookmarks 'stable' and 'development'. I switch between the two as required and push them to bitbucket with hg push -B bookmark-name. Then I login to my testing/live server respectively and pull the correct bookmarked version.
Once I have tested my development bookmark I can merge it with my stable one and pull it onto the live server.
My concern and as such my question is what happens If i accidentally forget to specify the bookmark when pulling to the live server for example?
Thanks

Pulling
From Mercurial 2.3, pulling gets the remote repository's bookmarks as well. Before, you had to specify -B <bookmark> to get bookmarks as well as changesets. So your server repositories will have the right bookmarks after pulling.
If you're using an earlier version, you'll have to pull -B <bookmark> to get the bookmark as well. Of course, you can do that anyway, if you'd prefer not to pull all development changesets onto your live server.
Updating
Using hg update with no arguments will get you tip, which is always the last changeset added to the repository, whether that's stable, development or accidentally un-bookmarked (actually, it'll get you the last changeset added to the current branch, but it sounds like you're not using named branches). To get consistent results when updating, I'd recommend you be explicit about which bookmark you want each server repository to update to. If you're worried about forgetting to specify, use scripts to automate your update process.

The correct usage IMHO is to use named branch instead of bookmark.

I treat bookmarks as local tags and no more. So if I'm wanting to push tagging information then I use actual tags to mark stable releases. Every time I do a release I mark it such as "rel-2.4" for example.
Then on live I can update to the latest revision and know that that is the last good release. My "dev" is simply the head of the default branch and I keep adding new bits of development into it. This way you can just do a push and not worry about the bookmarks.
This might not be what you want or you envisage but it is a workable solution for the situation you describe.
Should we have a fix that we need to do (a typo in your example) I can update to the last release, correct the type, test and if happy tag it as the next release (rel-2.41). Merge that new branch back into default so my dev branch has the fix too. Jump on the live server and pull/update to rel-2.41
Is that any good to you?

Related

Mercurial: devs work on separate folders, why do they have to merge all the time

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.

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.

Can I work in the repository in a single user Mercurial workflow?

I use Mercurial in a single-user workflow to have the option to roll back changes if my coding or writing goes horribly wrong (I primarily use the Stata and R statistics packages and LaTeX). While working only locally, this has been easy since all I have is the main repo.
Recently I have started ssh-ing into a Linux server for more computational power. So far I have been manually copying files back and forth and using Mercurial only locally, but I would like to use Mercurial to take care of this and keep these two workflows synchronized. Also, I like the ability to code both locally (on my laptop or desktop) and on the server.
Do I need to work on a clone of the main repo on the server and keep the main repo untouched? Or can I work directly in the main repo when I am on the server? In this question #gizmo points to this workflow guide; the "single developer" discussion is helpful, but it's still not clear to me that I can work in the main repo while I'm on the server without causing some major problem that I don't yet understand.
Thanks!
Edit: I should add that I have worked through Joel Spolsky's HgInit.com tutorial and I'm comfortable pushing/pulling/cloning/etc over ssh, but I am still not sure if I can work in the main repo without causing heartache later. Or maybe this is more a philosophical question? Thanks!
Mercurial is DVCS, it means - in each location you have both: local working copy and local repository
Mercurial is DVCS, it means - you can freely exchange (pull|push) data between repos (if they provide remote-access methods).
If you
comfortable pushing/pulling/cloning/etc over ssh
and don't forget perform pull|push cycle around your work at home (in order to don't run hg serve at home-host and sync from server as source) you don't get any headache at all with perfect linear aggregated history on each place. And even you forget to sync repo sometimes, you get in worst case two heads later, which you'll be able to merge easy (doesn't know formats of Stata and R data-files, but LaTeX, as text, is mergeable)
There is no problem with working directly in the repository on your server. From Mercurial's point of view, the "main" repository is just another random repository — Mercurial doesn't consider it to be special.
You don't say this directly, but one thing that people ask is "What happens when I push to the server?" The answer is that hg push only sends data into the repository (the .hg/ folder). The working copy is not touched on the server when you push to it. Since you push new changesets to the server, you might need to run hg update the next time you work on the server. This is just like if you had run hg pull on the server — there you'll also merge or update afterwards.
I have this situation all the time: I create a repository at home and clone it to my computer at work. I change files in either location and push/pull between the two repositories. If I need to share my work with others, then I make a repository at Bitbucket and push the code there. That way Bitbucket serves as a nice canonical repository for the code and I typically change the default path to Bitbucket in the repositories at home and at work. So at home I would have:
[paths]
default = httsp://bitbucket.org/mg/<repo>/
work = ssh://mg#work/<repo>
so that I can do hg push to send things to Bitbucket and hg pull work to grab things directly from work (in case I forgot to push to Bitbucket before leaving).

Using mercurial, can I push just one revision with all the content?(Push and Collapse)

I am writing a open source project, I did all the work at my machine and now I want to push the project do Codeplex.com, but I dont want to send all the old history.
Its possible to push all files in just one revision to Codeplex and continue with my history locally? Something like a Push And Collapse
No - a DVCS relies on the fact that you synchronise all history between members in the distribution set.
If you want to get rid of the history though, prior to pushing to Codeplex you can do the following:
Clone your local repository to a revision before the history you want "removed". We'll call the clone "Repository B".
Update repository A to the tip that you want to apply. Grab the changes, and copy the files to your cloned repository B. You can greate a bundle or patch, but for brevity here I'm just going with the quick and dirty :)
On repository B, commit a single changeset with all those changes.
From now on, repository B is your master. Push this to Codeplex.
As you can see, you can't have historical changeset data on one clone that partakes in a synchronisation with another, but before you've pushed to Codeplex, you can mush all those changes into a single commit - so long as you're happy to lose the history locally too.
An alternative is to use Mercurial Queues to "fold" history, but it needs to be done before you push to Codeplex - check out this wiki page for more information.
Check out the CollapseExtension.

Mercurial and code reviews; good workflow?

I'm in a small distributed team using Mercurial for a central repository. We each clone it via ssh onto our own linux boxes. Our intent is to review each others' work before pushing changes up to the central repository, to help keep central's tip clean. What is a good way to share code between developers on different linux boxes? I'm new to Mercurial. The options I can think of (through reading, not experience) are:
1: Author commits all local changes and updates working clone with central's tip. Author uses hg bundle, if there's a way to specify which local revs to include in the bundle. (an experiment showed me "bundle" only grabs uncommited changes, even if there are previous local commits that central doesn't know about) Author gets bundle file to reviewer. Reviewer creates a new clean clone from central's tip, and imports the bundle into that clone.
or,
2: After both author and reviewer fetch from central's tip, author uses patch and reviewer imports the patch.
or,
3: Author pushes to reviewer or reviewer pulls from author (but how, exactly? What I read is only about pushing and pulling to/from the original served repository, and/or on the same box instead of between different linux boxes.)
4: Forget reviewing the code prior to pushing to central; go ahead and push, using tags to identify what's been reviewed or not, and use Hudson (already working) to tag the latest safe build so team members can know which one to pull from.
If your team uses Mercurial and does code reviews, how do you do get the reviewer to see your changes?
Most of these are possible, some are more tedious than others.
You can use bundle by specifying the tip of the central repo as the --base:
hg bundle --base 4a3b2c1d review.bundle
Might as well just use bundle. That way, the changeset data is also included.
You can push (and pull) to (from) any repository that has a common ancestor(s). If you want to pull from one of your colleagues, they just need to run hg serve on their machine, and you will be able to pull.
This also works, but you will have to maintain multiple heads and be careful about merging. If you don't, it can become easy to base a stable change on top of an unreviewed changeset, which will make it hard to undo if you need to fix that unreviewed changeset later.
Of the options you presented, #1 and #3 are probably easiest, just depending on whether or not you can reach each other's boxes.
On a related note: This is the question that got my colleague and I started on developing Kiln, our (Fog Creek's) Mercurial hosting and code review tool. Our plan, and the initial prototype, would keep multiple repositories around, one "central" repository, and a bunch of "review" repositories. The review process would be started by cloning the central repo into a review repo on the server, and then running a full repo diff between the two, with a simple web interface for getting and viewing the diffs.
We've evolved that workflow quite a bit, but the general idea, having a branch repo to push unreviewed changes to and an interface to review them before you push them into the central repo, is still the same. I don't want to advertise here, but I do recommend giving it a try.
Half answer to this question is using ReviewBoard with Mercurial extention. It allows to push certain revisions for review by issuing the following command
hg postreview tip
I'll add a 5th option - do all development work on named branches, preferably one per task. Allow anything to be committed to a "development" named branch, whether it's in working state or not.
Push to the central repository, have reviewer pull the branch. Perform the review on the branch.
When the review has passed, merge the development work into the appropriate feature branch.
This workflow, which is (to me) surprisingly unpopular, has many advantages:
All work gets committed - you do not have to wait for a review to be done before committing.
You will not build off the wrong version. You only ever build from the feature branch.
In-progress work does not interfere with other developers.
From the development branch, you can either look at the latest changes (e.g. the changesets addressing review comments), compare with the branch point, or compare with the latest feature branch - all of which can give useful information.