 So, both branch names and tags are simply tools for organizing your change sets for keeping track of things. Some people like to include them in their workflow, other people don't. Perhaps though the most important decision about your workflow is whether you choose to manage separate branches within the same repo or in separate repos. If you and your team decide not to separate branches out into separate repos, your workflow probably looks something like this. The team members each have all just their own one repository and when it comes time to sync, they all go through a central repository. So any two changes between members are not exchanged directly between their repos, they're pushed up to the central repository where they can be pulled by the other users. When it comes time to work on a separate branch, users just make those branches in the one repository they use and they push them up to the central repository where they can be pulled down by the other members, just like they do with the mainline branch. So in this workflow when you have separate open branches, that is branches that were created and yet haven't yet been merged in with mainline, then you're simply keeping it around multiple heads in each repo. The alternative workflow and the one perhaps more commonly used in Mercurial is to keep separate branches in separate repositories. That is when you decide, hey, I want to have a new branch here, first you clone off a new repository and then you make the commits in that new repository. So say in this example, the four team members are pushing their separate branches of development into separate repositories. Bug fixes for existing features get pushed up to the bug fix repo but work on some new feature X is pushed up to a separate repository. And then the changes in those repositories get pulled up into the dev repo where the two branches get merged and when it comes time to make a stable release, someone on the team pushes that stable version from the dev repo up to stable. Now what's not pictured here is that the individual users, Mike, Gene, Allen and Kim, they might keep their new feature work and their bug fix work in separate repositories as well. So they don't necessarily each have just one repository, they may have many, which act as their separate branches. That decision though can actually be left up to the individual users. So what you see here is actually just one variant of keeping branches in separate repos. There's tons of different ways you can go about it and you don't have to take a pure approach. You can have some branches mixed together in the same repo and you can keep other branches separate in separate repos. Understand though that what it really means to keep a single branch in a single repository is that within that repository, you generally maintain just one head. The only time you have multiple heads is when you're just pulling in some other branch to merge in that repository. So having multiple heads in that repository is just a very temporary state while you do your merge. As soon as you keep around the multiple heads in the same repository, well, that one repo really no longer represents just one branch. Again though, which style of workflow to use, that's a matter of preference. One will argue very strongly for doing things one way and then just as many people will argue for doing things the other way. The last thing we'll cover is that we've already seen some number of informative commands. That is commands which don't really modify the repo at all. They just display information about the repo. We've seen HG status, we've seen HG log, we've HG parents and HG tags, but there's also HG heads, diff, identity, tip, outgoing, incoming, and help. The heads command simply displays the current heads in the repository. That is all chain sets without any children. The diff command will print out a diff between the working directory and its parent, or between the working directory and some other chain set, or between any other two chain sets. The identity command prints out the ID, the change set ID of the working directory's parent, or any other change set that you specify, and what makes it more useful than the other commands would do the same thing is that ID can be used on remote repositories. So I can query another repository and ask it, say, what is the ID of the current head of such and such branch? That's the sort of thing you can do with Identify. The tip command simply prints out the change set, which is the current tip in your repository, and then the outgoing and incoming commands respectively list the change sets which have yet to be pushed to another repository, or of which yet to be pulled from another repository. So if you want to know what change sets will get copied in a pusher pull without actually doing the pusher pull, you can use outgoing and incoming. And finally, the help command is effectively the manual for Mercurial. If you want to know more about a specific command like, say, the diff command, you type hg help diff, and that reports the help on the diff command. So you'll probably end up using the help command quite a bit, especially early on. We'll end now by briefly going over a list of things we didn't cover about Mercurial, first off of which is network access. How do you make your repository accessible in the network? Whether over SSH or HTTP, in practice, this is an important topic, but we won't go into it because it's quite involved. We also didn't discuss file path syntax, meaning when you specify a file path in a Mercurial command or in one of the config files, how does that match up with an actual file path? Because Mercurial actually uses a pattern matching syntax very similar to the regx syntax used by the Unix find command. So for example, if I want to add to the working directory manifest all files ending in .zip, there is a syntax I can use to specify all files ending in .zip without having to specify them all by name. This file matching syntax is used not just in commands, but also in this file called .hgignore, which is a file in your .hg directory. Which lists files in your working directory which Mercurial should ignore. It's quite common in your working directory to have a number of files which you need to be there, but you don't want to have them version tracked. Like for example, when you build your project, you may end up with a bunch of compiled code files in your working directory, but you don't want those version tracked. You only want your source files tracked. And while it's the case that Mercurial will not track files which you don't explicitly add with the .hgadd command, it becomes really bothersome to have all these files in your working directory, which still show up, say, in an .hgstatus command. They'll show up with a question mark, meaning that it's present in the working directory, but is not included in the manifest. The files can also be bothersome because it's quite easy to add them on accident. In fact, if you invoke .hgadd without any arguments, as we saw, it will actually add all files in the working directory that aren't currently tracked. So to make sure that doesn't happen, and to stop these files from being listed in .hgstatus, you'll want to add them to the .hgignore file. Now we did discuss how when you create new files in your working directory, and when you remove them from your working directory, you want to tell Mercurial about those new and removed files with the .hgadd command and the .hgremove command. For similar reasons, when you rename a file or remove a file within the working directory, or when you copy a file in the working directory, that is you place in the working directory a copy of some other file that's already included. In these cases, you'll want to tell Mercurial that, hey, these aren't new files, these are actually just copies or renames of existing files in the repo. Doing so helps Mercurial track the revision history of those files more intelligently. For example, if you have some file in the early chain sets of your repository where the file was named foo, but then in later chain sets you've renamed it the bar, you want Mercurial to know that foo in those earlier chain sets are really just earlier versions of the same file named bar in the later chain sets. If Mercurial is told about that relationship, it can do intelligent things like say, identify a common ancestor and emerge even when the file has been renamed since the common ancestor. So, briefly the take away here is when it comes time to rename or copy files within your working directory, you'll want to use the Mercurial commands for doing so, just like when you remove a file with .hgremove. What are called bookmarks in Mercurial are Mercurial's semi-equivalent of what in Git are called refs. A ref is basically just some named pointer to a change set. Quite like a tag, but without the weird business of being stored in the file that's kept in the revision history. And also refs are only used to point to head chain sets and have the special property that when a new revision is made on top of that head, the ref is moved with it to that new change set. So that's the gist of how refs work and bookmarks are basically just Mercurial's equivalent of refs. A hook in a version control system refers to an optional script which is executed when users perform certain actions in the repository. Like for example, you can configure a hook in your repository to execute every time someone makes a commit. And in fact, you can have the hook potentially reject the commit, refuse to let the commit go through if it fails to meet some criteria as determined by the hook. So, for example, you might set up your hook script to first run the unit tests of your code and if the unit tests fail, then the commit is rejected. Basically, it's a strategy to prevent people from committing code with obvious bugs in it. That though is just one common use of hooks there are others that we won't get into. We discussed earlier how binary files don't differ very well. So the problem then becomes in a distributed version control system that if your project has lots of large binary files that go through many versions then the size of this repository which you're cloning out to all your users and cloning to make branches of and so forth is going to be problematically large. A solution to this problem in Mercurial is to use an extension called large files which enables you to mark certain files as binary files which only get stored in some central repository. So if you modify one of these files and then making your chain set, a chain set only has a marker indicating of hey, this is where you go find this file if you actually want it. The file itself doesn't get stored in the repo. So you would typically give this treatment to the large binary files in your project like say if you're working on a game and you have gigabytes or maybe even terabytes of art assets that you need to store somewhere on the central repository but you don't want copied around with every clone of your repository. Lastly, if you ever need to work with a Git repository or a Subversion repository it's possible to do so from Mercurial. There's an extension for interoperating with Git and an extension for interoperating with Subversion. For all the basics interoperating with Git especially is pretty trivial because Git structurally is very very similar. In some cases though you have feature mismatches. You have semantic differences between Mercurial repositories and Git and Subversion repositories especially in the case of Subversion because the structure of Subversion is that of a centralized version control system.