belaran@969: belaran@969: belaran@969: belaran@969: belaran@969: A tour of Mercurial: the basics belaran@969: belaran@969: belaran@969: Installing Mercurial on your system belaran@969: belaran@969: Prebuilt binary packages of Mercurial are available for belaran@969: every popular operating system. These make it easy to start belaran@969: using Mercurial on your computer immediately. belaran@969: belaran@969: belaran@969: Windows belaran@969: belaran@969: The best version of Mercurial for Windows is belaran@969: TortoiseHg, which can be found at http://bitbucket.org/tortoisehg/stable/wiki/Home. belaran@969: This package has no external dependencies; it just belaran@969: works. It provides both command line and graphical belaran@969: user interfaces. belaran@969: belaran@969: belaran@969: belaran@969: belaran@969: Mac OS X belaran@969: belaran@969: Lee Cantey publishes an installer of Mercurial belaran@969: for Mac OS X at http://mercurial.berkwood.com. belaran@969: belaran@969: belaran@969: belaran@969: Linux belaran@969: belaran@969: Because each Linux distribution has its own packaging belaran@969: tools, policies, and rate of development, it's difficult to belaran@969: give a comprehensive set of instructions on how to install belaran@969: Mercurial binaries. The version of Mercurial that you will belaran@969: end up with can vary depending on how active the person is who belaran@969: maintains the package for your distribution. belaran@969: belaran@969: To keep things simple, I will focus on installing belaran@969: Mercurial from the command line under the most popular Linux belaran@969: distributions. Most of these distributions provide graphical belaran@969: package managers that will let you install Mercurial with a belaran@969: single click; the package name to look for is belaran@969: mercurial. belaran@969: belaran@969: belaran@969: Ubuntu and Debian: belaran@969: apt-get install mercurial belaran@969: Fedora: belaran@969: yum install mercurial belaran@969: OpenSUSE: belaran@969: zypper install mercurial belaran@969: Gentoo: belaran@969: emerge mercurial belaran@969: belaran@969: belaran@969: belaran@969: belaran@969: Solaris belaran@969: belaran@969: SunFreeWare, at http://www.sunfreeware.com, belaran@969: provides prebuilt packages of Mercurial. belaran@969: belaran@969: belaran@969: belaran@969: belaran@969: belaran@969: belaran@969: Getting started belaran@969: belaran@969: To begin, we'll use the hg belaran@969: version command to find out whether Mercurial is belaran@969: installed properly. The actual version information that it belaran@969: prints isn't so important; we simply care whether the command belaran@969: runs and prints anything at all. belaran@969: belaran@969: &interaction.tour.version; belaran@969: belaran@969: belaran@969: Built-in help belaran@969: belaran@969: Mercurial provides a built-in help system. This is belaran@969: invaluable for those times when you find yourself stuck belaran@969: trying to remember how to run a command. If you are belaran@969: completely stuck, simply run hg belaran@969: help; it will print a brief list of commands, belaran@969: along with a description of what each does. If you ask for belaran@969: help on a specific command (as below), it prints more belaran@969: detailed information. belaran@969: belaran@969: &interaction.tour.help; belaran@969: belaran@969: For a more impressive level of detail (which you won't belaran@969: usually need) run hg help . The option is short for belaran@969: , and tells belaran@969: Mercurial to print more information than it usually belaran@969: would. belaran@969: belaran@969: belaran@969: belaran@969: belaran@969: Working with a repository belaran@969: belaran@969: In Mercurial, everything happens inside a belaran@969: repository. The repository for a project belaran@969: contains all of the files that belong to that belaran@969: project, along with a historical record of the project's belaran@969: files. belaran@969: belaran@969: There's nothing particularly magical about a repository; it belaran@969: is simply a directory tree in your filesystem that Mercurial belaran@969: treats as special. You can rename or delete a repository any belaran@969: time you like, using either the command line or your file belaran@969: browser. belaran@969: belaran@969: belaran@969: Making a local copy of a repository belaran@969: belaran@969: Copying a repository is just a little belaran@969: bit special. While you could use a normal file copying belaran@969: command to make a copy of a repository, it's best to use a belaran@969: built-in command that Mercurial provides. This command is belaran@969: called hg clone, because it belaran@969: makes an identical copy of an existing repository. belaran@969: belaran@969: &interaction.tour.clone; belaran@969: belaran@969: One advantage of using hg belaran@969: clone is that, as we can see above, it lets us clone belaran@969: repositories over the network. Another is that it remembers belaran@969: where we cloned from, which we'll find useful soon when we belaran@969: want to fetch new changes from another repository. belaran@969: belaran@969: If our clone succeeded, we should now have a local belaran@969: directory called hello. belaran@969: This directory will contain some files. belaran@969: belaran@969: &interaction.tour.ls; belaran@969: belaran@969: These files have the same contents and history in our belaran@969: repository as they do in the repository we cloned. belaran@969: belaran@969: Every Mercurial repository is complete, belaran@969: self-contained, and independent. It contains its own private belaran@969: copy of a project's files and history. As we just mentioned, belaran@969: a cloned repository remembers the location of the repository belaran@969: it was cloned from, but Mercurial will not communicate with belaran@969: that repository, or any other, unless you tell it to. belaran@969: belaran@969: What this means for now is that we're free to experiment belaran@969: with our repository, safe in the knowledge that it's a private belaran@969: sandbox that won't affect anyone else. belaran@969: belaran@969: belaran@969: belaran@969: What's in a repository? belaran@969: belaran@969: When we take a more detailed look inside a repository, we belaran@969: can see that it contains a directory named .hg. This is where Mercurial belaran@969: keeps all of its metadata for the repository. belaran@969: belaran@969: &interaction.tour.ls-a; belaran@969: belaran@969: The contents of the .hg directory and its belaran@969: subdirectories are private to Mercurial. Every other file and belaran@969: directory in the repository is yours to do with as you belaran@969: please. belaran@969: belaran@969: To introduce a little terminology, the .hg directory is the belaran@969: real repository, and all of the files and belaran@969: directories that coexist with it are said to live in the belaran@969: working directory. An easy way to belaran@969: remember the distinction is that the belaran@969: repository contains the belaran@969: history of your project, while the belaran@969: working directory contains a belaran@969: snapshot of your project at a particular belaran@969: point in history. belaran@969: belaran@969: belaran@969: belaran@969: belaran@969: A tour through history belaran@969: belaran@969: One of the first things we might want to do with a new, belaran@969: unfamiliar repository is understand its history. The hg log command gives us a view of belaran@969: the history of changes in the repository. belaran@969: belaran@969: &interaction.tour.log; belaran@969: belaran@969: By default, this command prints a brief paragraph of output belaran@969: for each change to the project that was recorded. In Mercurial belaran@969: terminology, we call each of these recorded events a belaran@969: changeset, because it can contain a record belaran@969: of changes to several files. belaran@969: belaran@969: The fields in a record of output from hg log are as follows. belaran@969: belaran@969: belaran@969: changeset: This belaran@969: field has the format of a number, followed by a colon, belaran@969: followed by a hexadecimal (or hex) belaran@969: string. These are identifiers for the belaran@969: changeset. The hex string is a unique identifier: the same belaran@969: hex string will always refer to the same changeset in every belaran@969: copy of this repository. The belaran@969: number is shorter and easier to type than the hex string, belaran@969: but it isn't unique: the same number in two different clones belaran@969: of a repository may identify different changesets. belaran@969: belaran@969: user: The identity of the belaran@969: person who created the changeset. This is a free-form belaran@969: field, but it most often contains a person's name and email belaran@969: address. belaran@969: date: The date and time on belaran@969: which the changeset was created, and the timezone in which belaran@969: it was created. (The date and time are local to that belaran@969: timezone; they display what time and date it was for the belaran@969: person who created the changeset.) belaran@969: summary: The first line of belaran@969: the text message that the creator of the changeset entered belaran@969: to describe the changeset. belaran@969: belaran@969: Some changesets, such as the first in the list above, belaran@969: have a tag field. A tag is another way belaran@969: to identify a changeset, by giving it an easy-to-remember belaran@969: name. (The tag named tip is special: it belaran@969: always refers to the newest change in a repository.) belaran@969: belaran@969: belaran@969: belaran@969: The default output printed by hg log is purely a summary; it is belaran@969: missing a lot of detail. belaran@969: belaran@969: provides belaran@969: a graphical representation of the history of the hello repository, to make it a belaran@969: little easier to see which direction history is belaran@969: flowing in. We'll be returning to this figure belaran@969: several times in this chapter and the chapter that belaran@969: follows. belaran@969: belaran@969:
belaran@969: Graphical history of the <filename belaran@969: class="directory">hello</filename> repository belaran@969: belaran@969: belaran@969: XXX add text belaran@969: belaran@969:
belaran@969: belaran@969: belaran@969: Changesets, revisions, and talking to other belaran@969: people belaran@969: belaran@969: As English is a notoriously sloppy language, and computer belaran@969: science has a hallowed history of terminological confusion belaran@969: (why use one term when four will do?), revision control has a belaran@969: variety of words and phrases that mean the same thing. If you belaran@969: are talking about Mercurial history with other people, you belaran@969: will find that the word changeset is often belaran@969: compressed to change or (when written) belaran@969: cset, and sometimes a changeset is referred to belaran@969: as a revision or a rev. belaran@969: belaran@969: While it doesn't matter what word you belaran@969: use to refer to the concept of a changeset, the belaran@969: identifier that you use to refer to belaran@969: a specific changeset is of belaran@969: great importance. Recall that the changeset belaran@969: field in the output from hg belaran@969: log identifies a changeset using both a number and belaran@969: a hexadecimal string. belaran@969: belaran@969: The revision number is a handy belaran@969: notation that is only valid in that belaran@969: repository. belaran@969: The hexadecimal string is the belaran@969: permanent, unchanging identifier that belaran@969: will always identify that exact changeset in belaran@969: every copy of the belaran@969: repository. belaran@969: belaran@969: This distinction is important. If you send belaran@969: someone an email talking about revision 33, belaran@969: there's a high likelihood that their revision 33 will belaran@969: not be the same as yours. The reason for belaran@969: this is that a revision number depends on the order in which belaran@969: changes arrived in a repository, and there is no guarantee belaran@969: that the same changes will happen in the same order in belaran@969: different repositories. Three changes a,b,c belaran@969: can easily appear in one repository as belaran@969: 0,1,2, while in another as belaran@969: 0,2,1. belaran@969: belaran@969: Mercurial uses revision numbers purely as a convenient belaran@969: shorthand. If you need to discuss a changeset with someone, belaran@969: or make a record of a changeset for some other reason (for belaran@969: example, in a bug report), use the hexadecimal belaran@969: identifier. belaran@969: belaran@969: belaran@969: belaran@969: Viewing specific revisions belaran@969: belaran@969: To narrow the output of hg belaran@969: log down to a single revision, use the (or ) option. You can use belaran@969: either a revision number or a hexadecimal identifier, belaran@969: and you can provide as many revisions as you want. belaran@969: belaran@969: &interaction.tour.log-r; belaran@969: belaran@969: If you want to see the history of several revisions belaran@969: without having to list each one, you can use range belaran@969: notation; this lets you express the idea I belaran@969: want all revisions between abc and belaran@969: def, inclusive. belaran@969: belaran@969: &interaction.tour.log.range; belaran@969: belaran@969: Mercurial also honours the order in which you specify belaran@969: revisions, so hg log -r 2:4 belaran@969: prints 2, 3, and 4. while hg log -r belaran@969: 4:2 prints 4, 3, and 2. belaran@969: belaran@969: belaran@969: belaran@969: More detailed information belaran@969: belaran@969: While the summary information printed by hg log is useful if you already know belaran@969: what you're looking for, you may need to see a complete belaran@969: description of the change, or a list of the files changed, if belaran@969: you're trying to decide whether a changeset is the one you're belaran@969: looking for. The hg log belaran@969: command's (or ) option gives you belaran@969: this extra detail. belaran@969: belaran@969: &interaction.tour.log-v; belaran@969: belaran@969: If you want to see both the description and belaran@969: content of a change, add the (or ) option. This displays belaran@969: the content of a change as a unified diff belaran@969: (if you've never seen a unified diff before, see for an overview). belaran@969: belaran@969: &interaction.tour.log-vp; belaran@969: belaran@969: The option is belaran@969: tremendously useful, so it's well worth remembering. belaran@969: belaran@969: belaran@969:
belaran@969: belaran@969: belaran@969: All about command options belaran@969: belaran@969: Let's take a brief break from exploring Mercurial commands belaran@969: to discuss a pattern in the way that they work; you may find belaran@969: this useful to keep in mind as we continue our tour. belaran@969: belaran@969: Mercurial has a consistent and straightforward approach to belaran@969: dealing with the options that you can pass to commands. It belaran@969: follows the conventions for options that are common to modern belaran@969: Linux and Unix systems. belaran@969: belaran@969: belaran@969: belaran@969: Every option has a long name. For example, as belaran@969: we've already seen, the hg belaran@969: log command accepts a option. belaran@969: belaran@969: belaran@969: Most options have short names, too. Instead belaran@969: of , we can use belaran@969: . (The reason that belaran@969: some options don't have short names is that the options in belaran@969: question are rarely used.) belaran@969: belaran@969: belaran@969: Long options start with two dashes (e.g. belaran@969: ), while short belaran@969: options start with one (e.g. ). belaran@969: belaran@969: belaran@969: Option naming and usage is consistent across belaran@969: commands. For example, every command that lets you specify belaran@969: a changeset ID or revision number accepts both and arguments. belaran@969: belaran@969: belaran@969: If you are using short options, you can save typing by belaran@969: running them together. For example, the command hg log -v -p -r 2 can be written belaran@969: as hg log -vpr2. belaran@969: belaran@969: belaran@969: belaran@969: In the examples throughout this book, I usually belaran@969: use short options instead of long. This simply reflects my own belaran@969: preference, so don't read anything significant into it. belaran@969: belaran@969: Most commands that print output of some kind will print more belaran@969: output when passed a belaran@969: (or ) option, and belaran@969: less when passed (or belaran@969: ). belaran@969: belaran@969: belaran@969: Option naming consistency belaran@969: belaran@969: Almost always, Mercurial commands use consistent option belaran@969: names to refer to the same concepts. For instance, if a belaran@969: command deals with changesets, you'll always identify them belaran@969: with or . This consistent use of belaran@969: option names makes it easier to remember what options a belaran@969: particular command takes. belaran@969: belaran@969: belaran@969: belaran@969: belaran@969: Making and reviewing changes belaran@969: belaran@969: Now that we have a grasp of viewing history in Mercurial, belaran@969: let's take a look at making some changes and examining belaran@969: them. belaran@969: belaran@969: The first thing we'll do is isolate our experiment in a belaran@969: repository of its own. We use the hg belaran@969: clone command, but we don't need to clone a copy of belaran@969: the remote repository. Since we already have a copy of it belaran@969: locally, we can just clone that instead. This is much faster belaran@969: than cloning over the network, and cloning a local repository belaran@969: uses less disk space in most cases, too belaran@969: The saving of space arises when source and destination belaran@969: repositories are on the same filesystem, in which case belaran@969: Mercurial will use hardlinks to do copy-on-write sharing of belaran@969: its internal metadata. If that explanation meant nothing to belaran@969: you, don't worry: everything happens transparently and belaran@969: automatically, and you don't need to understand it. belaran@969: . belaran@969: belaran@969: &interaction.tour.reclone; belaran@969: belaran@969: As an aside, it's often good practice to keep a belaran@969: pristine copy of a remote repository around, belaran@969: which you can then make temporary clones of to create sandboxes belaran@969: for each task you want to work on. This lets you work on belaran@969: multiple tasks in parallel, each isolated from the others until belaran@969: it's complete and you're ready to integrate it back. Because belaran@969: local clones are so cheap, there's almost no overhead to cloning belaran@969: and destroying repositories whenever you want. belaran@969: belaran@969: In our my-hello belaran@969: repository, we have a file hello.c that belaran@969: contains the classic hello, world program. belaran@969: belaran@969: &interaction.tour.cat1; belaran@969: belaran@969: Let's edit this file so that it prints a second line of belaran@969: output. belaran@969: belaran@969: &interaction.tour.cat2; belaran@969: belaran@969: Mercurial's hg status belaran@969: command will tell us what Mercurial knows about the files in the belaran@969: repository. belaran@969: belaran@969: &interaction.tour.status; belaran@969: belaran@969: The hg status command belaran@969: prints no output for some files, but a line starting with belaran@969: M for belaran@969: hello.c. Unless you tell it to, hg status will not print any output belaran@969: for files that have not been modified. belaran@969: belaran@969: The M indicates that belaran@969: Mercurial has noticed that we modified belaran@969: hello.c. We didn't need to belaran@969: inform Mercurial that we were going to belaran@969: modify the file before we started, or that we had modified the belaran@969: file after we were done; it was able to figure this out belaran@969: itself. belaran@969: belaran@969: It's somewhat helpful to know that we've modified belaran@969: hello.c, but we might prefer to know belaran@969: exactly what changes we've made to it. To belaran@969: do this, we use the hg diff belaran@969: command. belaran@969: belaran@969: &interaction.tour.diff; belaran@969: belaran@969: belaran@969: Understanding patches belaran@969: belaran@969: Remember to take a look at if you don't know how to read belaran@969: output above. belaran@969: belaran@969: belaran@969: belaran@969: Recording changes in a new changeset belaran@969: belaran@969: We can modify files, build and test our changes, and use belaran@969: hg status and hg diff to review our changes, until belaran@969: we're satisfied with what we've done and arrive at a natural belaran@969: stopping point where we want to record our work in a new belaran@969: changeset. belaran@969: belaran@969: The hg commit command lets belaran@969: us create a new changeset; we'll usually refer to this as belaran@969: making a commit or belaran@969: committing. belaran@969: belaran@969: belaran@969: Setting up a username belaran@969: belaran@969: When you try to run hg belaran@969: commit for the first time, it is not guaranteed to belaran@969: succeed. Mercurial records your name and address with each belaran@969: change that you commit, so that you and others will later be belaran@969: able to tell who made each change. Mercurial tries to belaran@969: automatically figure out a sensible username to commit the belaran@969: change with. It will attempt each of the following methods, belaran@969: in order: belaran@969: belaran@969: If you specify a option to the hg commit command on the command belaran@969: line, followed by a username, this is always given the belaran@969: highest precedence. belaran@969: If you have set the HGUSER belaran@969: environment variable, this is checked belaran@969: next. belaran@969: If you create a file in your home belaran@969: directory called .hgrc, with a username entry, that will be belaran@969: used next. To see what the contents of this file should belaran@969: look like, refer to belaran@969: below. belaran@969: If you have set the EMAIL belaran@969: environment variable, this will be used belaran@969: next. belaran@969: Mercurial will query your system to find out belaran@969: your local user name and host name, and construct a belaran@969: username from these components. Since this often results belaran@969: in a username that is not very useful, it will print a belaran@969: warning if it has to do belaran@969: this. belaran@969: belaran@969: If all of these mechanisms fail, Mercurial will belaran@969: fail, printing an error message. In this case, it will not belaran@969: let you commit until you set up a belaran@969: username. belaran@969: You should think of the HGUSER environment belaran@969: variable and the belaran@969: option to the hg commit belaran@969: command as ways to override Mercurial's belaran@969: default selection of username. For normal use, the simplest belaran@969: and most robust way to set a username for yourself is by belaran@969: creating a .hgrc file; see belaran@969: below for details. belaran@969: belaran@969: Creating a Mercurial configuration file belaran@969: belaran@969: To set a user name, use your favorite editor belaran@969: to create a file called .hgrc in your home directory. belaran@969: Mercurial will use this file to look up your personalised belaran@969: configuration settings. The initial contents of your belaran@969: .hgrc should look like belaran@969: this. belaran@969: belaran@969: belaran@969: <quote>Home directory</quote> on Windows belaran@969: belaran@969: When we refer to your home directory, on an English belaran@969: language installation of Windows this will usually be a belaran@969: folder named after your user name in belaran@969: C:\Documents and Settings. You can belaran@969: find out the exact name of your home directory by opening belaran@969: a command prompt window and running the following belaran@969: command. belaran@969: belaran@969: C:\> echo %UserProfile% belaran@969: belaran@969: belaran@969: # This is a Mercurial configuration file. belaran@969: [ui] belaran@969: username = Firstname Lastname <email.address@example.net> belaran@969: belaran@969: The [ui] line begins a belaran@969: section of the config file, so you can belaran@969: read the username = ... belaran@969: line as meaning set the value of the belaran@969: username item in the belaran@969: ui section. A section continues belaran@969: until a new section begins, or the end of the file. belaran@969: Mercurial ignores empty lines and treats any text from belaran@969: # to the end of a line as belaran@969: a comment. belaran@969: belaran@969: belaran@969: belaran@969: Choosing a user name belaran@969: belaran@969: You can use any text you like as the value of belaran@969: the username config item, since this belaran@969: information is for reading by other people, but will not be belaran@969: interpreted by Mercurial. The convention that most people belaran@969: follow is to use their name and email address, as in the belaran@969: example above. belaran@969: belaran@969: Mercurial's built-in web server obfuscates belaran@969: email addresses, to make it more difficult for the email belaran@969: harvesting tools that spammers use. This reduces the belaran@969: likelihood that you'll start receiving more junk email if belaran@969: you publish a Mercurial repository on the belaran@969: web. belaran@969: belaran@969: belaran@969: belaran@969: Writing a commit message belaran@969: belaran@969: When we commit a change, Mercurial drops us into belaran@969: a text editor, to enter a message that will describe the belaran@969: modifications we've made in this changeset. This is called belaran@969: the commit message. It will be a record belaran@969: for readers of what we did and why, and it will be printed by belaran@969: hg log after we've finished belaran@969: committing. belaran@969: belaran@969: &interaction.tour.commit; belaran@969: belaran@969: The editor that the hg belaran@969: commit command drops us into will contain an empty belaran@969: line or two, followed by a number of lines starting with belaran@969: HG:. belaran@969: belaran@969: belaran@969: This is where I type my commit comment. belaran@969: belaran@969: HG: Enter commit message. Lines beginning with 'HG:' are removed. belaran@969: HG: -- belaran@969: HG: user: Bryan O'Sullivan <bos@serpentine.com> belaran@969: HG: branch 'default' belaran@969: HG: changed hello.c belaran@969: belaran@969: Mercurial ignores the lines that start with belaran@969: HG:; it uses them only to belaran@969: tell us which files it's recording changes to. Modifying or belaran@969: deleting these lines has no effect. belaran@969: belaran@969: belaran@969: Writing a good commit message belaran@969: belaran@969: Since hg log belaran@969: only prints the first line of a commit message by default, belaran@969: it's best to write a commit message whose first line stands belaran@969: alone. Here's a real example of a commit message that belaran@969: doesn't follow this guideline, and hence belaran@969: has a summary that is not readable. belaran@969: belaran@969: belaran@969: changeset: 73:584af0e231be belaran@969: user: Censored Person <censored.person@example.org> belaran@969: date: Tue Sep 26 21:37:07 2006 -0700 belaran@969: summary: include buildmeister/commondefs. Add exports. belaran@969: belaran@969: As far as the remainder of the contents of the belaran@969: commit message are concerned, there are no hard-and-fast belaran@969: rules. Mercurial itself doesn't interpret or care about the belaran@969: contents of the commit message, though your project may have belaran@969: policies that dictate a certain kind of formatting. belaran@969: My personal preference is for short, but belaran@969: informative, commit messages that tell me something that I belaran@969: can't figure out with a quick glance at the output of hg log --patch. belaran@969: If we run the hg belaran@969: commit command without any arguments, it records belaran@969: all of the changes we've made, as reported by hg status and hg diff. belaran@969: belaran@969: belaran@969: A surprise for Subversion users belaran@969: belaran@969: Like other Mercurial commands, if we don't supply belaran@969: explicit names to commit to the hg belaran@969: commit, it will operate across a repository's belaran@969: entire working directory. Be wary of this if you're coming belaran@969: from the Subversion or CVS world, since you might expect it belaran@969: to operate only on the current directory that you happen to belaran@969: be visiting and its subdirectories. belaran@969: belaran@969: belaran@969: belaran@969: belaran@969: Aborting a commit belaran@969: belaran@969: If you decide that you don't want to commit belaran@969: while in the middle of editing a commit message, simply exit belaran@969: from your editor without saving the file that it's editing. belaran@969: This will cause nothing to happen to either the repository or belaran@969: the working directory. belaran@969: belaran@969: belaran@969: belaran@969: Admiring our new handiwork belaran@969: belaran@969: Once we've finished the commit, we can use the belaran@969: hg tip command to display the belaran@969: changeset we just created. This command produces output that belaran@969: is identical to hg log, but belaran@969: it only displays the newest revision in the repository. belaran@969: belaran@969: &interaction.tour.tip; belaran@969: belaran@969: We refer to the newest revision in the belaran@969: repository as the tip revision, or simply belaran@969: the tip. belaran@969: belaran@969: By the way, the hg tip belaran@969: command accepts many of the same options as hg log, so above indicates be belaran@969: verbose, belaran@969: specifies print a patch. The use of to print patches is another belaran@969: example of the consistent naming we mentioned earlier. belaran@969: belaran@969: belaran@969: belaran@969: belaran@969: Sharing changes belaran@969: belaran@969: We mentioned earlier that repositories in belaran@969: Mercurial are self-contained. This means that the changeset we belaran@969: just created exists only in our my-hello repository. Let's look belaran@969: at a few ways that we can propagate this change into other belaran@969: repositories. belaran@969: belaran@969: belaran@969: Pulling changes from another repository belaran@969: belaran@969: To get started, let's clone our original belaran@969: hello repository, which belaran@969: does not contain the change we just committed. We'll call our belaran@969: temporary repository hello-pull. belaran@969: belaran@969: &interaction.tour.clone-pull; belaran@969: belaran@969: We'll use the hg belaran@969: pull command to bring changes from my-hello into hello-pull. However, blindly belaran@969: pulling unknown changes into a repository is a somewhat scary belaran@969: prospect. Mercurial provides the hg belaran@969: incoming command to tell us what changes the belaran@969: hg pull command belaran@969: would pull into the repository, without belaran@969: actually pulling the changes in. belaran@969: belaran@969: &interaction.tour.incoming; belaran@969: belaran@969: Bringing changes into a repository is a simple belaran@969: matter of running the hg pull belaran@969: command, and optionally telling it which repository to pull from. belaran@969: belaran@969: &interaction.tour.pull; belaran@969: belaran@969: As you can see from the before-and-after output belaran@969: of hg tip, we have belaran@969: successfully pulled changes into our repository. However, belaran@969: Mercurial separates pulling changes in from updating the belaran@969: working directory. There remains one step before we will see belaran@969: the changes that we just pulled appear in the working belaran@969: directory. belaran@969: belaran@969: belaran@969: Pulling specific changes belaran@969: belaran@969: It is possible that due to the delay between belaran@969: running hg incoming and belaran@969: hg pull, you may not see belaran@969: all changesets that will be brought from the other belaran@969: repository. Suppose you're pulling changes from a repository belaran@969: on the network somewhere. While you are looking at the belaran@969: hg incoming output, and belaran@969: before you pull those changes, someone might have committed belaran@969: something in the remote repository. This means that it's belaran@969: possible to pull more changes than you saw when using belaran@969: hg incoming. belaran@969: belaran@969: If you only want to pull precisely the changes that were belaran@969: listed by hg incoming, or belaran@969: you have some other reason to pull a subset of changes, belaran@969: simply identify the change that you want to pull by its belaran@969: changeset ID, e.g. hg pull belaran@969: -r7e95bb. belaran@969: belaran@969: belaran@969: belaran@969: belaran@969: Updating the working directory belaran@969: belaran@969: We have so far glossed over the relationship belaran@969: between a repository and its working directory. The hg pull command that we ran in belaran@969: brought changes into the belaran@969: repository, but if we check, there's no sign of those changes belaran@969: in the working directory. This is because hg pull does not (by default) touch belaran@969: the working directory. Instead, we use the hg update command to do this. belaran@969: belaran@969: &interaction.tour.update; belaran@969: belaran@969: It might seem a bit strange that hg pull doesn't update the working belaran@969: directory automatically. There's actually a good reason for belaran@969: this: you can use hg update belaran@969: to update the working directory to the state it was in at belaran@969: any revision in the history of the belaran@969: repository. If you had the working directory updated to an belaran@969: old revision&emdash;to hunt down the origin of a bug, belaran@969: say&emdash;and ran a hg pull belaran@969: which automatically updated the working directory to a new belaran@969: revision, you might not be terribly happy. belaran@969: belaran@969: Since pull-then-update is such a common sequence belaran@969: of operations, Mercurial lets you combine the two by passing belaran@969: the option to hg pull. belaran@969: belaran@969: If you look back at the output of hg pull in when we ran it without , you can see that it printed belaran@969: a helpful reminder that we'd have to take an explicit step to belaran@969: update the working directory. belaran@969: belaran@969: To find out what revision the working directory belaran@969: is at, use the hg parents belaran@969: command. belaran@969: belaran@969: &interaction.tour.parents; belaran@969: belaran@969: If you look back at , you'll see arrows belaran@969: connecting each changeset. The node that the arrow leads belaran@969: from in each case is a parent, and the belaran@969: node that the arrow leads to is its belaran@969: child. The working directory has a parent in just the same belaran@969: way; this is the changeset that the working directory belaran@969: currently contains. belaran@969: belaran@969: To update the working directory to a particular belaran@969: revision, give a revision number or changeset ID to the belaran@969: hg update command. belaran@969: belaran@969: &interaction.tour.older; belaran@969: belaran@969: If you omit an explicit revision, hg update will update to the tip belaran@969: revision, as shown by the second call to hg update in the example belaran@969: above. belaran@969: belaran@969: belaran@969: belaran@969: Pushing changes to another repository belaran@969: belaran@969: Mercurial lets us push changes to another belaran@969: repository, from the repository we're currently visiting. As belaran@969: with the example of hg pull belaran@969: above, we'll create a temporary repository to push our changes belaran@969: into. belaran@969: belaran@969: &interaction.tour.clone-push; belaran@969: belaran@969: The hg outgoing belaran@969: command tells us what changes would be pushed into another belaran@969: repository. belaran@969: belaran@969: &interaction.tour.outgoing; belaran@969: belaran@969: And the hg push belaran@969: command does the actual push. belaran@969: belaran@969: &interaction.tour.push; belaran@969: belaran@969: As with hg belaran@969: pull, the hg push belaran@969: command does not update the working directory in the belaran@969: repository that it's pushing changes into. Unlike hg pull, hg belaran@969: push does not provide a -u belaran@969: option that updates the other repository's working directory. belaran@969: This asymmetry is deliberate: the repository we're pushing to belaran@969: might be on a remote server and shared between several people. belaran@969: If we were to update its working directory while someone was belaran@969: working in it, their work would be disrupted. belaran@969: belaran@969: What happens if we try to pull or push changes belaran@969: and the receiving repository already has those changes? belaran@969: Nothing too exciting. belaran@969: belaran@969: &interaction.tour.push.nothing; belaran@969: belaran@969: belaran@969: belaran@969: Default locations belaran@969: belaran@969: When we clone a repository, Mercurial records the location belaran@969: of the repository we cloned in the belaran@969: .hg/hgrc file of the new repository. If belaran@969: we don't supply a location to hg pull from belaran@969: or hg push to, those commands will use this belaran@969: location as a default. The hg incoming belaran@969: and hg outgoing commands do so too. belaran@969: belaran@969: If you open a repository's .hg/hgrc belaran@969: file in a text editor, you will see contents like the belaran@969: following. belaran@969: belaran@969: [paths] belaran@969: default = http://www.selenic.com/repo/hg belaran@969: belaran@969: It is possible&emdash;and often useful&emdash;to have the belaran@969: default location for hg push and belaran@969: hg outgoing be different from those for belaran@969: hg pull and hg incoming. belaran@969: We can do this by adding a default-push belaran@969: entry to the [paths] section of the belaran@969: .hg/hgrc file, as follows. belaran@969: belaran@969: [paths] belaran@969: default = http://www.selenic.com/repo/hg belaran@969: default-push = http://hg.example.com/hg belaran@969: belaran@969: belaran@969: belaran@969: Sharing changes over a network belaran@969: belaran@969: The commands we have covered in the previous few belaran@969: sections are not limited to working with local repositories. belaran@969: Each works in exactly the same fashion over a network belaran@969: connection; simply pass in a URL instead of a local belaran@969: path. belaran@969: belaran@969: &interaction.tour.outgoing.net; belaran@969: belaran@969: In this example, we can see what changes we belaran@969: could push to the remote repository, but the repository is belaran@969: understandably not set up to let anonymous users push to belaran@969: it. belaran@969: belaran@969: &interaction.tour.push.net; belaran@969: belaran@969: belaran@969: belaran@969: belaran@969: Starting a new project belaran@969: belaran@969: It is just as easy to begin a new project as to work on one belaran@969: that already exists. The hg init command belaran@969: creates a new, empty Mercurial repository. belaran@969: belaran@969: &interaction.ch01-new.init; belaran@969: belaran@969: This simply creates a repository named belaran@969: myproject in the current directory. belaran@969: belaran@969: &interaction.ch01-new.ls; belaran@969: belaran@969: We can tell that myproject is a belaran@969: Mercurial repository, because it contains a belaran@969: .hg directory. belaran@969: belaran@969: &interaction.ch01-new.ls2; belaran@969: belaran@969: If we want to add some pre-existing files to the repository, belaran@969: we copy them into place, and tell Mercurial to start tracking belaran@969: them using the hg add command. belaran@969: belaran@969: &interaction.ch01-new.add; belaran@969: belaran@969: Once we are satisfied that our project looks right, we belaran@969: commit our changes. belaran@969: belaran@969: &interaction.ch01-new.commit; belaran@969: belaran@969: It takes just a few moments to start using Mercurial on a belaran@969: new project, which is part of its appeal. Revision control is belaran@969: now so easy to work with, we can use it on the smallest of belaran@969: projects that we might not have considered with a more belaran@969: complicated tool. belaran@969: belaran@969:
belaran@969: belaran@969: