Tagging

With tagging you can more easily go back to a point in time or specific version of your code. While tagging is not required for this, it makes it much easier. Without labeling, a developer would have to read through logs and possibly source control changes to ascertain what version they need to go back to. Instead, tag. Make it easy on yourself or anyone coming behind you.

When is it a good time to tag. Every commit? I prescribe to substantial events in the code. At the very least, every time you release to production. That way if a release goes bad you can go back to the old codebase very easily. Other times to consider tagging would be:

Large updates.

Logical updates such as Feature A, Feature B, Bug A, Bug B.

Anytime you believe going back to the current code may be of use.

Tagging could be seen as a tool to document the code but good commit messages are better for that in general. Tagging serves as a great way to document the timeline of important events of your codebase.

Wrap Up

I hope you found this series helpful. I enjoyed putting it together and learned a few things along the way. Mercurial is lesser known than Git but still a great tool. Hopefully, you’ll find that using Mercurial is very easy. Give it a shot.

This is the seventh post in this series. In the third post we discussed the various branching scenarios and some ideas as to when to branch. We settled on branch as needed approach as our default work process but now we are going to show how to branch when you decide you need to.

When should I branch?

With Mercurial and Git this isn’t nearly as painful as non-dvcs systems and can be /encouraged to be used more often now.

Here’s my choices of when to branch.

1. When a feature / bug fix is big enough (subjective).

This makes it easier to clean up if you decide the code is getting too unwieldy or you can't seem to get it working.

2. When you may need to work on a feature that could take some time to develop.

This makes sure that if something needs to be done in default without your changes than they could be done. Think, hotfix or a quick update.

3. When you know there may be other work going on with code that you will be working on as well.

This allows them to work on the code without you or them worrying about your work. Worry is not exactly the best choice. You will have to worry about it when you need to merge.

4. When you need to ensure the work you are doing does not effect the default line in anyway until you are absolutely ready.

5. If you are really unsure of your work ahead or you want to try/spike some code that you may not keep.

You can get rid of a branch but you might also want to consider doing the Branch with a Clone method.

Named branch scenario

First, as usual we'll check the state of our repo with hg stat and clean up anything we need to.

Create the branch by typing hg branch "BranchName".

After creating the branch, run hg branches to list out the branches that are currently open. Interesting, our branch doesn't show up? That's because it hasn't been committed yet. Commit it.

Now run hg branches again and it will show:

To see what branch you are currently in run hg branch:

Now that you are in the correct branch you can develop as usual. Committing as you go until you are satisfied you are ready to close the branch and merge it back in to the main branch/line (default).

The repo remembers what branch you are in between sessions but it's always a good idea to check what branch you are in by running hg branch before working just like it is running hg stat to ensure everything is the way you expected it.

Closing the loop

After you have completed all your work on this branch, you’ll need to close out the branch.

Always check your status and what branch your in:

Now close out the branch by committing it with the --close-branch option. Type hg commit --close-branch '-m "Your message".

If you were to run hg branches (lists all active branches) now, you’ll see your branch is gone. If you type hg branch again though you might be a bit confused. It still shows your in the branch you just closed?

You need to move back into the default / main branch with the hg update command.

Now running hg branch will show you in the right branch.

Your almost done. You’ve closed the branch and move back into default but if you were to look at default you won’t find your code from your closed branch. That’s because you haven’t brought in your work from it. We’ll do this now with the hg merge "Branch name to merge" command.

The merge command will give you statistics for the merge. As with other steps you need to commit the merge to finalize it. The merge even warns you to not forget to commit.

If you look at the repository in the Hg Workbench (Tortoise) you'll see graphically the branch & merge.

hg branches - now will not show your new branch as it hasn't been commited yet.

hg commit -m "Initial commit for branch"

hg branches - now shows your branch.

hg branch - confirm you are in your new branch.

Work as normal. Committing as you need/desire.

hg commit --close-branch -m "Finished Branch"

hg branches - won't show your branch in the list

hg branch - still show you are in the branch

hg update default - go back

hg merge "Branch Name To Merge"

hg commit -m "Commit Message"

It can get more complicated than this but for a small team or one person operation this will be the majority.

Switching branches

In case you need to switch around and work in other branches, run hg update "branch name" to move between branches.

Updating branch with new code from default

The second most common scenario even for a small team is needing to update a branch with code from another branch.

Let's say you have been working on a new feature for quite some time on a branch. In the middle of this a nasty bug is found in the currently live system.

You can't fix it in the branch you are on as it's not ready. What do you do? Switch to the main line/default branch and fix the bug. Deploy the update and everyone's happy.

In this case, you could just keep developing and merge as usual when you are ready BUT let's say for this situation you want to bring in the fix from main to your branch to make sure everything will continue to work fine and if not, fix it now instead of later.

In your branch run:

hg incoming - tells you if you will get anything from the main repository.*

If you have anything incoming then run hg pull. *

hg merge

hg commit -m "Merge in from default"

* - In a one man team operation this is likely not needed since your local repo is highly likely up to date. However, for safety and for a small team your teammates will have to pull. Pulling won't hurt you if there isn't anything to get so it's a good habit to at least check.

You don’t get any message but now if you take a look at what you have in your directory you’ll see two files. Not perhaps what one would expect. Mercurial doesn’t delete or overwrite the file with what is in the repository. Instead it adds the .orig extension to the file you don’t want.

This is just for extra safety. However, you can override this by adding --no-backup to the command (hg revert --no-backup Index.cshtml).

If you do this in Tortoise Hg, it automatically runs with the --no-backup option. You can change that by unchecking the checkbox "do not save backup files" in the lower left hand corner.

To finish up you can delete the Index.cshtml.org and run hg stat to see that your back in order.

If you edited this in Visual Studio, you’ll get prompted by VS to reload the project.

Selecting yes, you’ll see your changes gone and back to what it is in the repository.

To review, the steps to revert a file that hasn’t been committed yet are:

Undoing a commit

Already committed your work? Let’s undo this mishap now. Now being the keyword. With hg rollback you can roll back the last commit in the repository.

Going back to our above sample, let’s make a change to a file and commit it.

I ran hg stat, after my commit just to make sure we are clear of any other changes. I also ran a new command called hg tip to show that my last commit is indeed the one I’m targeting to revert.

If we are confident this is the commit we want to revert we are ready to rollback.

Type hg rollback

It gives a message back that the tip has been rolled back and the working directory is back to our revision number for the last commit. However, we are not done. If you type hg stat you’ll notice our file is in a modified state.

The file is in the state we left it with our changes before we committed it. We’ll need to revert our work.

This time I used the --no-backup option on the revert to avoid having to delete the .orig file.

Undo an older Commit?

So what if you have to undo a commit that is more than one revision back. Well, that’s a more advanced topic than what I’m covering. Take a look at Chapter 9. Finding and fixing mistakes in Mercurial: The Definitive Guide.

For our purposes, small team development, the majority of the time will be spent developing right in default. This is by far the simplest approach and for a small team is very doable with no major side-effects. However, it’s not without it’s own downsides. For that we’ll cover branching in a later article.

Let’s get started.

Open a command prompt by selecting your project's root folder and while pressing the Shift key, right-click the mouse and select open command window here

In a team scenario where you are working on the same code base you will want to look at pulling and updating your local repo with their changes. In our case, this is the abnormal case. For us we will almost always be working on the code base by ourselves. If your team is needing to be more collaborative then working in default will likely not fit your needs well. You’ll want to look more into developing in branches like the stable & default workflow outlined by Steve Losh.

With that in mind we can always start with checking the status of our code base.

Type hg stat.

hg stat will return a list (if there is any) of files that have either been added, deleted or changed since your last commit.

If it returns nothing then the repository is up to date (locally). This doesn't mean it's up to date with the Server (Bitbucket). However, in our simple case the Server / Bitbucket is used as central backup and retrieval. If your working on a new feature then running hg stat locally will be an indicator if you haven't committed in your latest changes locally.

Below is a sample session of a work in progress:

M - The file has been modified.

! - The file has been deleted.

? - The file is new.

Let's say we are done with these changes and we are ready to commit them.

Typing hg addremove would give us:

This marks all new files as added to the repository and marks removes/deletes files from the repository.

There are separate commands hg add & hg remove with options to add/remove only some files if desired.

However, the files have only been marked. They haven't actually been committed yet.

Note that the first two files that reported M are not in the list. That's because they don't need to be marked since they are already under source control.

Typing hg commit -m "commit message" would commit the changes to the repository.

You should get back a prompt without any messages. Looks like everything committed.

Typing hg stat (again) should report nothing. Your local repository is up to date with your latest changes on this machine.

Next steps?

You could keep on developing or push your changes up to Bitbucket. I like to do this often. Let’s update Bitbucket now.

Updating Bitbucket

First create a repository in Bitbucket for your project.

Login to Bitbucket and create a repository.

Select your new repository from the Repositories drop down and copy the text after hg clone. Since we are going to do this from the Tortoise Client instead of the command line we leave off the hg clone.

It should look something like https://username@bitbucket.org/username/repositoryname.

We are using HTTPS to connect but you can also use SSH although I won’t be covering that here. If your interested in using SSH instead, Atlassian has a great write up.

Select the local item in the dropdown list below the icons and paste in the repository address.

Then select the push icon.

You should be prompted for your password and possibly your username.

Getting code from Bitbucket

To get code from Bitbucket, we’ll do the same process as a push except now when we are in the Sync screen, we’ll use the pull icon instead.

Recommended process

I like to commit early and often. I try and break down the feature/bug I am working on into small chunks of logical work. When I get a logical chunk done I commit the work. If the feature or bug is small enough then I do it all in one commit.

I like breaking it up because this allows me to more easily go back to an early version if something goes wrong. It's easier to go back, start over if you will, than try and undo the mess I got myself into.The larger the feature, the more I try and work in logical chunks. For a large enough feature I also will use a branch.

I like to push my changes to Bitbucket often. At least once a day and perhaps more. On rare occasions I will not push my changes in a day. Usually this is when I am hammering out an idea and the code is unstable still. I try to live by “the code shouldn’t break the build” as a general rule of thumb for deciding if I should push it up. If you are working in small enough chunks this should be a rare occurrence.

As a general guideline I push changes to Bitbucket when I have completed a feature/bug fix. However, this is not a hard and fast rule and I try hard to push my changes at least at the end of the day.

When more than one developer is working on a codebase the general guideline is to push when you have completed and tested the feature along with everyone else's submitted work. In a team someone else could have pushed up a change. You’ll need to bring their work down (hg pull and hg up or hg merge) and test it with your code to ensure your changes continue to work as well as your teammates. If you need some more information on working in this kind of scenario please check out HgInit’s setting up for a team. SecretGeek also published a nice workflow sample based off of HgInit’s explanation.

At my current job and my last I either worked solo often on projects or in very small overlapping efforts of a few team members. In both of these jobs the team used Visual SourceSafe (VSS) and it was working well enough but no longer supported. Jumping to TFS felt like overkill for a team on VSS and not affordable.

MS has announced TFS Express which might go a long way in changing this. However, I have found the world of Distributed Version Control Systems (DVCS) with Git and Mercurial to be game changers.

As I have been learning more and more about DVCS I found a need to work up a new process that I can hand over to my team members or a new employee to help them get up to speed fast. Teams of larger size or even code bases of much larger complexity require sophisticated workflows. In my last two jobs I haven’t fallen into this category.

This series reviews the process I have put together for a small team (1-5 members) with less complex code bases. I’m not a Mercurial or Git expert by any stretch of the mind but I have found a flow that is working great. I welcome any thoughts and suggestions for improvement from the more seasoned DVCS pro’s.

I’m first going to mention using the command line and Nuget Package Restore.

To command line or not. That is the question...

First time users, especially Windows heavy users such as myself have likely used Tortoise* at some point in our development to interact with a repository. I started with TortoiseHg to help get the basics down but after Rob's challenge I gave the command line a shot and discovered two things.

I was faster

I understood Mercurial much better and what Tortoise was doing for me.

I still use Tortoise for a few things but for the most part I use the command line now for most operations. If you think this is the way for you have a look at posh-hg to add even more productivity.

Nuget Package Restore

Feel free to move on to the next section if your not using .Net.

Dependencies are something we must deal with in our version control story. Nuget eases a developer’s life for managing dependencies but with Nuget Package Restore we can more cleanly keep our dependencies out of the source control but have an automated way of getting them into your project.

Without Package Restore we would have to put the dependent libraries (dll's) in source control. Usually one would create a library folder and have everything in this folder source controlled.

With Package Restore we source control the configuration settings of the dependent libraries we are using with Nuget. When we pull down a repository for the first time and build it Nuget will read the configuration and download all of the libraries in use. We get a source control environment with the knowledge of what libraries we need but we don’t have to store the libraries in the source tree.

To use it we’ll need to tell Mercurial to ignore the packages folder. The last item in the hgignore file in the third post has this covered.

If you don’t like this idea, no problem. You don’t have to use it.

Setting up a repository on your local machine

I do this with Tortoise although you can use the hg init command at the command line.

Since we are using Nuget Package Restore we have to add the Nuget.exe to the repository. Normally we don't want to save Dll's and/or Exe's to the repository. The ignore file specifies this as the default. As such we have to add it manually. The same is true if down the line you need to use a 3rd party library that isn't available on NuGet. In this case I would create a lib folder in the root of the project and place my library files in this folder. From this folder I would add it to the repository and add a reference in VS.

In a small team often the workflow process is not something that has to be complex. There are a few different workflow techniques that make sense in this case. Even in a 1 person team branching and tagging may seem unnecessary butthey can come in handy.

The name may seem a little deceiving but essentially the recommended approach is to not worry about branches in general. Development on the main line / default branch should work a lot of the time for a small team. Often when you are working in small team’s you don’t have to worry about features others are working on since you are likely the only one. In the small cases as well where a few are working it is often in a way that they can develop features that are completely part of a different area of the code than you are working on. You often don’t have to worry about updating the code base for a "hotfix" either which if you were developing off the default branch could present a problem should this be needed.

The reality is even in a small team you will want to think about these possibilities and plan for them if they will be an issue. Hence, "Branch as needed". If you don’t need it, then don’t worry about it.

Even for small teams or code bases, branches offer some great advantages and should be considered a part of your process. Branches offer a way for you to create a separate isolated area for you to develop a feature or bug fix. This isolation allows us to fully develop the feature or bug fix without touching the default line.

This gives us the flexibility to get rid of the branch if we decide it’s not working or work a fix in on the default line while we are still developing the feature on it’s own. If we were not using a branch and a serious bug is found the feature code may stop you from being able to issue a fix for it until you’ve completed the feature.

I tend to use branches for features that I deem larger than a week to work on or if I am really unsure of how I want to accomplish it that way I can get rid of my work easily if I decide to scrap it and start over.

There are several ways to create branches in Mercurial. Were going to use the Branching with Named Branches process. Branching with clones is also a great option if you are really unsure of your work and think you might need to trash it. This is the simplest for trashing but requires a bit more work if you like it and want to merge it back into the original codebase.

There's several settings you can set per repo and/or globally on the machine. The first of these to set is your username.

To set this at the computer level on a windows machine, find the mercurial.ini file in the Windows System UserProfile folder.

Add the following:

[ui] username = Your Name <your_email_address>

You can also set it per the project by editing the hrgc file in the .hg directory for your repository.

Ignore File

The ignore file (.hgignore) tells Mercurial what files to not source control by default. You can add anything manually in the list yourself but Mercurial won't automatically look for the patterns in this file. There are several examples out there. Below is the sample I am using at the moment and have found it to work well.

DVCS offer many advantages over traditional systems such as Subversion. Most agree that branching and merging are much easier, the operations are usually much faster and the reason I like the most – their distributed.

Distributed

Every developer has a copy of the repository on their drive and can work on this copy however they like. This results in much faster operations as well as a new freedom for a developer to work on code locally WITH source control operations and not having to worry about what it is doing to the server version or other users. Commit 50 times, add two branches, delete a branch, etc.... No more having to worry about checking in to the central server. Work how you need to complete the task with local source control support! When your ready you can get an update for the "central" server and check your work/build locally. Then commit and since merging is so much more powerful and intelligent this isn't as scary as before. A developer can get your changes from the central repository OR EVEN YOUR repo (if setup) when they want to their repository.

Both are great, so why Mercurial? My decision came down to three reasons.

Mercurial has better tooling on Windows. I am sure Git will change this but today this is the case.

As of this week, Git released a Windows client. This may change the game but I haven’t had a look at it yet.

Mercurial is a little simpler to use. Think of Mercurial as less options but not hobbled and Git as the option full, can easily shoot yourself if you don't know what you are doing option.

They both are great!!!! In fact I recommend a developer learn both. #3 is listed below.

Bitbucket vs. Github vs. Self-Hosting

The final reason for Mercurial is not based on Mercurial. The cloud hosting service Bitbucket offers a free plan that includes unlimited private repositories for up to five users. Github offers free to open source.

Bitbucket offers both Mercurial and Git hosting so choosing which DVCS is a little easier as it can be changed fairly easily. Bitbucket offers repo conversion tools as well.

Self-Hosting? - Yes, it's possible but setting up a Mercurial server at this time seemed more work and maintenance than it's worth compared to cloud hosting.

The team making stack exchange (stack overflow sites) also use Mercurial and have created a terrific tutorial.

Security with the Cloud

Worried about your source? Bitbucket is secured by HTTPS and requires a login with access to the repositories and / or SSH Keys per machine accessing the repository. A repository is owned by an account and that account can grant access to other accounts. Ownership of a repository can be transferred to another but only by contacting Bitbucket support.

While this is secure, dillegence in coding & backup practices should still be followed such as avoiding storing passwords where possible and backing up our source.

Secure Code

Storing the connection string in the clear in the web.config is a risk that can be mitigated. You can encrypt your connection string information and other sections that might contain sensitive information. You could have a connection string configuration file on each machine/server you use at a specified location and just have your web.config point to it to keep it completely out of source control.

Backup

Relying solely on any cloud vendor as your source code backup strategy is a nightmare waiting to happen. The cloud never goes down or looses data. Don't kid yourself. Don't play the fool and leave it all up to the cloud.

Going down for a little while using a DVCS is not that big of a deal. You can keep working and there are ways to get work from another peer box (hg serve).

DVCS being distributed by nature can make small outages very tenable. When you pull down a repo from the "central" repo, which in DVCS can change but for our purposes will always be considered Bitbucket, you are getting the entire repo UNLESS you purposefully choose different. This means your local repo is a copy/backup. That does not mean you should entirely rely on this in a disaster BUT it is an extra layer.

I recommend backing up the Bitbucket repositories on a regular interval and store them elsewhere.

Currently, there are two ways to do this.

Log into bitbucket and download the source for each repo in a zip file. This has one major drawback. The zipped version will not include any version control history.

Use https://bitbucket.org/christianspecht/bitbucket-backup script. This script will download all repo's with version information. The script is actually cloning all repo's to a destination directory. The script requires Mercurial to be installed on the machine running it and login information.