bos@559: bos@559: bos@685: bos@572: bos@559: Mercurial in daily use bos@559: bos@559: bos@559: Telling Mercurial which files to track bos@559: bos@584: Mercurial does not work with files in your repository unless bos@559: you tell it to manage them. The hg bos@559: status command will tell you which files Mercurial bos@559: doesn't know about; it uses a bos@559: ? to display such bos@559: files. bos@559: bos@584: To tell Mercurial to track a file, use the hg add command. Once you have added a bos@559: file, the entry in the output of hg bos@559: status for that file changes from bos@559: ? to bos@567: A. bos@567: bos@567: &interaction.daily.files.add; bos@559: bos@584: After you run a hg commit, bos@559: the files that you added before the commit will no longer be bos@559: listed in the output of hg bos@674: status. The reason for this is that by default, hg status only tells you about bos@674: interesting files&emdash;those that you have (for bos@674: example) modified, removed, or renamed. If you have a repository bos@674: that contains thousands of files, you will rarely want to know bos@674: about files that Mercurial is tracking, but that have not bos@674: changed. (You can still get this information; we'll return to bos@674: this later.) bos@559: bos@584: Once you add a file, Mercurial doesn't do anything with it bos@559: immediately. Instead, it will take a snapshot of the file's bos@559: state the next time you perform a commit. It will then continue bos@559: to track the changes you make to the file every time you commit, bos@559: until you remove the file. bos@559: bos@559: bos@559: Explicit versus implicit file naming bos@559: bos@672: A useful behavior that Mercurial has is that if you pass bos@559: the name of a directory to a command, every Mercurial command bos@559: will treat this as I want to operate on every file in bos@567: this directory and its subdirectories. bos@567: bos@567: &interaction.daily.files.add-dir; bos@567: bos@674: Notice in this example that Mercurial printed bos@674: the names of the files it added, whereas it didn't do so when bos@674: we added the file named myfile.txt in the bos@674: earlier example. bos@559: bos@584: What's going on is that in the former case, we explicitly bos@674: named the file to add on the command line. The assumption bos@674: that Mercurial makes in such cases is that we know what we bos@674: are doing, and it doesn't print any output. bos@559: bos@584: However, when we imply the names of bos@559: files by giving the name of a directory, Mercurial takes the bos@559: extra step of printing the name of each file that it does bos@559: something with. This makes it more clear what is happening, bos@559: and reduces the likelihood of a silent and nasty surprise. bos@672: This behavior is common to most Mercurial commands. bos@674: bos@674: bos@672: bos@672: Mercurial tracks files, not directories bos@559: bos@584: Mercurial does not track directory information. Instead, bos@559: it tracks the path to a file. Before creating a file, it bos@559: first creates any missing directory components of the path. bos@559: After it deletes a file, it then deletes any empty directories bos@559: that were in the deleted file's path. This sounds like a bos@559: trivial distinction, but it has one minor practical bos@559: consequence: it is not possible to represent a completely bos@559: empty directory in Mercurial. bos@559: bos@584: Empty directories are rarely useful, and there are bos@559: unintrusive workarounds that you can use to achieve an bos@559: appropriate effect. The developers of Mercurial thus felt bos@559: that the complexity that would be required to manage empty bos@559: directories was not worth the limited benefit this feature bos@559: would bring. bos@559: bos@584: If you need an empty directory in your repository, there bos@559: are a few ways to achieve this. One is to create a directory, bos@559: then hg add a bos@559: hidden file to that directory. On Unix-like bos@559: systems, any file name that begins with a period bos@559: (.) is treated as hidden by bos@559: most commands and GUI tools. This approach is illustrated bos@559: below. bos@559: bos@567: &interaction.daily.files.hidden; bos@559: bos@584: Another way to tackle a need for an empty directory is to bos@559: simply create one in your automated build scripts before they bos@559: will need it. bos@559: bos@559: bos@674: bos@559: bos@559: How to stop tracking a file bos@559: bos@701: Once you decide that a file no longer belongs in bos@701: your repository, use the hg bos@701: remove command. This deletes the file, and tells bos@701: Mercurial to stop tracking it (which will occur at the next bos@701: commit). A removed file is represented in the output of bos@559: hg status with a bos@567: R. bos@567: bos@567: &interaction.daily.files.remove; bos@559: bos@584: After you hg remove a file, bos@559: Mercurial will no longer track changes to that file, even if you bos@559: recreate a file with the same name in your working directory. bos@559: If you do recreate a file with the same name and want Mercurial bos@559: to track the new file, simply hg bos@559: add it. Mercurial will know that the newly added bos@559: file is not related to the old file of the same name. bos@559: bos@559: bos@559: Removing a file does not affect its history bos@559: bos@584: It is important to understand that removing a file has bos@559: only two effects. bos@559: bos@584: It removes the current version of the file bos@559: from the working directory. bos@559: bos@584: It stops Mercurial from tracking changes to bos@559: the file, from the time of the next commit. bos@559: bos@584: Removing a file does not in any way bos@559: alter the history of the file. bos@559: bos@674: If you update the working directory to a bos@674: changeset that was committed when it was still tracking a file bos@674: that you later removed, the file will reappear in the working bos@674: directory, with the contents it had when you committed that bos@674: changeset. If you then update the working directory to a bos@674: later changeset, in which the file had been removed, Mercurial bos@674: will once again remove the file from the working bos@674: directory. bos@674: bos@674: bos@559: bos@559: Missing files bos@559: bos@584: Mercurial considers a file that you have deleted, but not bos@559: used hg remove to delete, to bos@559: be missing. A missing file is bos@559: represented with ! in the bos@559: output of hg status. bos@559: Mercurial commands will not generally do anything with missing bos@567: files. bos@567: bos@567: &interaction.daily.files.missing; bos@559: bos@584: If your repository contains a file that hg status reports as missing, and bos@559: you want the file to stay gone, you can run hg remove at any bos@559: time later on, to tell Mercurial that you really did mean to bos@567: remove the file. bos@567: bos@567: &interaction.daily.files.remove-after; bos@559: bos@584: On the other hand, if you deleted the missing file by bos@559: accident, give hg revert the bos@559: name of the file to recover. It will reappear, in unmodified bos@559: form. bos@559: bos@674: &interaction.daily.files.recover-missing; bos@674: bos@674: bos@559: bos@559: Aside: why tell Mercurial explicitly to remove a bos@559: file? bos@559: bos@584: You might wonder why Mercurial requires you to explicitly bos@559: tell it that you are deleting a file. Early during the bos@559: development of Mercurial, it let you delete a file however you bos@559: pleased; Mercurial would notice the absence of the file bos@559: automatically when you next ran a hg bos@559: commit, and stop tracking the file. In practice, bos@559: this made it too easy to accidentally remove a file without bos@559: noticing. bos@674: bos@674: bos@559: bos@559: Useful shorthand&emdash;adding and removing files in one bos@559: step bos@559: bos@584: Mercurial offers a combination command, hg addremove, that adds untracked bos@567: files and marks missing files as removed. bos@567: bos@567: &interaction.daily.files.addremove; bos@567: bos@584: The hg commit command bos@567: also provides a bos@567: option that performs this same add-and-remove, immediately bos@567: followed by a commit. bos@567: bos@567: &interaction.daily.files.commit-addremove; bos@559: bos@559: bos@674: bos@701: bos@559: Copying files bos@559: bos@584: Mercurial provides a hg bos@559: copy command that lets you make a new copy of a bos@559: file. When you copy a file using this command, Mercurial makes bos@559: a record of the fact that the new file is a copy of the original bos@559: file. It treats these copied files specially when you merge bos@559: your work with someone else's. bos@559: bos@559: bos@559: The results of copying during a merge bos@559: bos@584: What happens during a merge is that changes bos@559: follow a copy. To best illustrate what this bos@559: means, let's create an example. We'll start with the usual bos@567: tiny repository that contains a single file. bos@567: bos@567: &interaction.daily.copy.init; bos@567: bos@584: We need to do some work in bos@559: parallel, so that we'll have something to merge. So let's bos@567: clone our repository. bos@567: bos@567: &interaction.daily.copy.clone; bos@567: bos@584: Back in our initial repository, let's use the hg copy command to make a copy of bos@567: the first file we created. bos@567: bos@567: &interaction.daily.copy.copy; bos@559: bos@584: If we look at the output of the hg bos@559: status command afterwards, the copied file looks bos@567: just like a normal added file. bos@567: bos@567: &interaction.daily.copy.status; bos@567: bos@584: But if we pass the option to hg status, it prints another line of bos@559: output: this is the file that our newly-added file was copied bos@567: from. bos@567: bos@567: &interaction.daily.copy.status-copy; bos@559: bos@584: Now, back in the repository we cloned, let's make a change bos@559: in parallel. We'll add a line of content to the original file bos@567: that we created. bos@567: bos@567: &interaction.daily.copy.other; bos@567: bos@584: Now we have a modified file in this bos@559: repository. When we pull the changes from the first bos@559: repository, and merge the two heads, Mercurial will propagate bos@559: the changes that we made locally to file bos@567: into its copy, new-file. bos@567: bos@567: &interaction.daily.copy.merge; bos@674: bos@674: bos@559: bos@559: Why should changes follow copies? bos@559: bos@674: This behavior&emdash;of changes to a file bos@674: propagating out to copies of the file&emdash;might seem bos@674: esoteric, but in most cases it's highly desirable. bos@559: bos@584: First of all, remember that this propagation bos@559: only happens when you merge. So if you bos@559: hg copy a file, and bos@559: subsequently modify the original file during the normal course bos@559: of your work, nothing will happen. bos@559: bos@584: The second thing to know is that modifications will only bos@674: propagate across a copy as long as the changeset that you're bos@674: merging changes from hasn't yet seen bos@559: the copy. bos@559: bos@584: The reason that Mercurial does this is as follows. Let's bos@559: say I make an important bug fix in a source file, and commit bos@559: my changes. Meanwhile, you've decided to hg copy the file in your repository, bos@559: without knowing about the bug or having seen the fix, and you bos@559: have started hacking on your copy of the file. bos@559: bos@584: If you pulled and merged my changes, and Mercurial bos@559: didn't propagate changes across copies, bos@674: your new source file would now contain the bug, and unless you bos@674: knew to propagate the bug fix by hand, the bug would bos@559: remain in your copy of the file. bos@559: bos@584: By automatically propagating the change that fixed the bug bos@559: from the original file to the copy, Mercurial prevents this bos@559: class of problem. To my knowledge, Mercurial is the bos@559: only revision control system that bos@559: propagates changes across copies like this. bos@559: bos@584: Once your change history has a record that the copy and bos@559: subsequent merge occurred, there's usually no further need to bos@559: propagate changes from the original file to the copied file, bos@559: and that's why Mercurial only propagates changes across copies bos@674: at the first merge, and not afterwards. bos@674: bos@674: bos@559: bos@559: How to make changes <emphasis>not</emphasis> follow a bos@559: copy bos@559: bos@584: If, for some reason, you decide that this business of bos@559: automatically propagating changes across copies is not for bos@559: you, simply use your system's normal file copy command (on bos@559: Unix-like systems, that's cp) to make a bos@559: copy of a file, then hg add bos@559: the new copy by hand. Before you do so, though, please do bos@592: reread , and make bos@559: an informed bos@672: decision that this behavior is not appropriate to your bos@559: specific case. bos@559: bos@559: bos@559: bos@674: Behavior of the <command role="hg-cmd">hg copy</command> bos@559: command bos@559: bos@584: When you use the hg copy bos@559: command, Mercurial makes a copy of each source file as it bos@559: currently stands in the working directory. This means that if bos@559: you make some modifications to a file, then hg copy it without first having bos@559: committed those changes, the new copy will also contain the bos@559: modifications you have made up until that point. (I find this bos@672: behavior a little counterintuitive, which is why I mention it bos@559: here.) bos@559: bos@674: The hg copy bos@674: command acts similarly to the Unix cp bos@674: command (you can use the hg bos@674: cp alias if you prefer). We must supply two or bos@674: more arguments, of which the last is treated as the bos@674: destination, and all others are bos@674: sources. bos@674: bos@676: If you pass hg copy a bos@674: single file as the source, and the destination does not exist, bos@674: it creates a new file with that name. bos@567: bos@567: &interaction.daily.copy.simple; bos@567: bos@584: If the destination is a directory, Mercurial copies its bos@567: sources into that directory. bos@567: bos@567: &interaction.daily.copy.dir-dest; bos@567: bos@584: Copying a directory is bos@559: recursive, and preserves the directory structure of the bos@567: source. bos@567: bos@567: &interaction.daily.copy.dir-src; bos@567: bos@584: If the source and destination are both directories, the bos@567: source tree is recreated in the destination directory. bos@567: bos@567: &interaction.daily.copy.dir-src-dest; bos@559: bos@674: As with the hg remove bos@559: command, if you copy a file manually and then want Mercurial bos@559: to know that you've copied the file, simply use the option to hg copy. bos@567: bos@567: &interaction.daily.copy.after; bos@559: bos@559: bos@674: bos@559: bos@559: Renaming files bos@559: bos@584: It's rather more common to need to rename a file than to bos@559: make a copy of it. The reason I discussed the hg copy command before talking about bos@559: renaming files is that Mercurial treats a rename in essentially bos@559: the same way as a copy. Therefore, knowing what Mercurial does bos@559: when you copy a file tells you what to expect when you rename a bos@559: file. bos@559: bos@584: When you use the hg rename bos@559: command, Mercurial makes a copy of each source file, then bos@567: deletes it and marks the file as removed. bos@567: bos@567: &interaction.daily.rename.rename; bos@567: bos@584: The hg status command shows bos@567: the newly copied file as added, and the copied-from file as bos@567: removed. bos@567: bos@567: &interaction.daily.rename.status; bos@567: bos@584: As with the results of a hg bos@567: copy, we must use the option to hg status to see that the added file bos@559: is really being tracked by Mercurial as a copy of the original, bos@567: now removed, file. bos@567: bos@567: &interaction.daily.rename.status-copy; bos@559: bos@584: As with hg remove and bos@559: hg copy, you can tell Mercurial bos@559: about a rename after the fact using the option. In most other bos@672: respects, the behavior of the hg bos@559: rename command, and the options it accepts, are bos@559: similar to the hg copy bos@559: command. bos@559: bos@676: If you're familiar with the Unix command line, you'll be bos@674: glad to know that hg rename bos@674: command can be invoked as hg bos@674: mv. bos@674: bos@559: bos@559: Renaming files and merging changes bos@559: bos@584: Since Mercurial's rename is implemented as bos@559: copy-and-remove, the same propagation of changes happens when bos@559: you merge after a rename as after a copy. bos@559: bos@584: If I modify a file, and you rename it to a new name, and bos@559: then we merge our respective changes, my modifications to the bos@559: file under its original name will be propagated into the file bos@559: under its new name. (This is something you might expect to bos@559: simply work, but not all revision control bos@559: systems actually do this.) bos@559: bos@584: Whereas having changes follow a copy is a feature where bos@559: you can perhaps nod and say yes, that might be bos@559: useful, it should be clear that having them follow a bos@559: rename is definitely important. Without this facility, it bos@559: would simply be too easy for changes to become orphaned when bos@559: files are renamed. bos@674: bos@674: bos@559: bos@559: Divergent renames and merging bos@559: bos@584: The case of diverging names occurs when two developers bos@559: start with a file&emdash;let's call it bos@559: foo&emdash;in their respective bos@559: repositories. bos@559: bos@567: &interaction.rename.divergent.clone; bos@567: bos@584: Anne renames the file to bar. bos@567: bos@567: &interaction.rename.divergent.rename.anne; bos@567: bos@584: Meanwhile, Bob renames it to bos@674: quux. (Remember that hg mv is an alias for hg rename.) bos@567: bos@567: &interaction.rename.divergent.rename.bob; bos@559: bos@584: I like to think of this as a conflict because each bos@559: developer has expressed different intentions about what the bos@559: file ought to be named. bos@559: bos@584: What do you think should happen when they merge their bos@672: work? Mercurial's actual behavior is that it always preserves bos@559: both names when it merges changesets that bos@567: contain divergent renames. bos@567: bos@567: &interaction.rename.divergent.merge; bos@559: bos@674: Notice that while Mercurial warns about the divergent bos@674: renames, it leaves it up to you to do something about the bos@559: divergence after the merge. bos@674: bos@674: bos@559: bos@559: Convergent renames and merging bos@559: bos@584: Another kind of rename conflict occurs when two people bos@559: choose to rename different source files bos@559: to the same destination. In this case, bos@559: Mercurial runs its normal merge machinery, and lets you guide bos@559: it to a suitable resolution. bos@674: bos@674: bos@559: bos@559: Other name-related corner cases bos@559: bos@584: Mercurial has a longstanding bug in which it fails to bos@559: handle a merge where one side has a file with a given name, bos@559: while another has a directory with the same name. This is bos@559: documented as issue bos@567: 29. bos@567: bos@567: &interaction.issue29.go; bos@559: bos@559: bos@559: bos@674: bos@559: bos@559: Recovering from mistakes bos@559: bos@584: Mercurial has some useful commands that will help you to bos@559: recover from some common mistakes. bos@559: bos@584: The hg revert command lets bos@559: you undo changes that you have made to your working directory. bos@559: For example, if you hg add a bos@559: file by accident, just run hg bos@559: revert with the name of the file you added, and bos@559: while the file won't be touched in any way, it won't be tracked bos@559: for adding by Mercurial any longer, either. You can also use bos@559: hg revert to get rid of bos@559: erroneous changes to a file. bos@559: bos@701: It is helpful to remember that the hg revert command is useful for bos@701: changes that you have not yet committed. Once you've committed bos@701: a change, if you decide it was a mistake, you can still do bos@701: something about it, though your options may be more bos@701: limited. bos@559: bos@592: For more information about the hg revert command, and details about bos@592: how to deal with changes you have already committed, see . bos@674: bos@674: bos@674: bos@674: Dealing with tricky merges bos@674: bos@676: In a complicated or large project, it's not unusual for a bos@674: merge of two changesets to result in some headaches. Suppose bos@674: there's a big source file that's been extensively edited by each bos@674: side of a merge: this is almost inevitably going to result in bos@674: conflicts, some of which can take a few tries to sort bos@674: out. bos@674: bos@676: Let's develop a simple case of this and see how to deal with bos@674: it. We'll start off with a repository containing one file, and bos@674: clone it twice. bos@674: bos@674: &interaction.ch04-resolve.init; bos@674: bos@676: In one clone, we'll modify the file in one way. bos@674: bos@674: &interaction.ch04-resolve.left; bos@674: bos@676: In another, we'll modify the file differently. bos@674: bos@674: &interaction.ch04-resolve.right; bos@674: bos@676: Next, we'll pull each set of changes into our original bos@674: repo. bos@674: bos@674: &interaction.ch04-resolve.pull; bos@674: bos@676: We expect our repository to now contain two heads. bos@674: bos@674: &interaction.ch04-resolve.heads; bos@674: bos@676: Normally, if we run hg bos@674: merge at this point, it will drop us into a GUI that bos@674: will let us manually resolve the conflicting edits to bos@674: myfile.txt. However, to simplify things bos@674: for presentation here, we'd like the merge to fail immediately bos@674: instead. Here's one way we can do so. bos@674: bos@674: &interaction.ch04-resolve.export; bos@674: bos@676: We've told Mercurial's merge machinery to run the command bos@674: false (which, as we desire, fails bos@674: immediately) if it detects a merge that it can't sort out bos@674: automatically. bos@674: bos@676: If we now fire up hg bos@674: merge, it should grind to a halt and report a bos@674: failure. bos@674: bos@674: &interaction.ch04-resolve.merge; bos@674: bos@676: Even if we don't notice that the merge failed, Mercurial bos@674: will prevent us from accidentally committing the result of a bos@674: failed merge. bos@674: bos@674: &interaction.ch04-resolve.cifail; bos@674: bos@676: When hg commit fails in bos@674: this case, it suggests that we use the unfamiliar hg resolve command. As usual, bos@674: hg help resolve will print a bos@674: helpful synopsis. bos@674: bos@674: bos@674: File resolution states bos@674: bos@676: When a merge occurs, most files will usually remain bos@674: unmodified. For each file where Mercurial has to do bos@674: something, it tracks the state of the file. bos@674: bos@674: bos@674: bos@676: A resolved file has been bos@674: successfully merged, either automatically by Mercurial or bos@674: manually with human intervention. bos@674: bos@674: bos@676: An unresolved file was not merged bos@674: successfully, and needs more attention. bos@674: bos@674: bos@674: bos@676: If Mercurial sees any file in the bos@674: unresolved state after a merge, it considers the merge to have bos@674: failed. Fortunately, we do not need to restart the entire bos@674: merge from scratch. bos@674: bos@676: The or bos@674: option to hg resolve prints out the state of bos@674: each merged file. bos@674: bos@674: &interaction.ch04-resolve.list; bos@674: bos@676: In the output from hg bos@674: resolve, a resolved file is marked with bos@674: R, while an unresolved file is marked with bos@674: U. If any files are listed with bos@674: U, we know that an attempt to commit the bos@674: results of the merge will fail. bos@674: bos@674: bos@674: bos@674: Resolving a file merge bos@674: bos@676: We have several options to move a file from the unresolved bos@674: into the resolved state. By far the most common is to rerun bos@674: hg resolve. If we pass the bos@674: names of individual files or directories, it will retry the bos@674: merges of any unresolved files present in those locations. We bos@674: can also pass the bos@674: or option, which bos@674: will retry the merges of all unresolved bos@674: files. bos@674: bos@676: Mercurial also lets us modify the resolution state of a bos@674: file directly. We can manually mark a file as resolved using bos@674: the option, or bos@674: as unresolved using the option. This allows bos@674: us to clean up a particularly messy merge by hand, and to keep bos@674: track of our progress with each file as we go. bos@674: bos@559: bos@683: bos@683: bos@683: More useful diffs bos@683: bos@684: The default output of the hg bos@683: diff command is backwards compatible with the bos@683: regular diff command, but this has some bos@683: drawbacks. bos@683: bos@684: Consider the case where we use hg bos@683: rename to rename a file. bos@683: bos@683: &interaction.ch04-diff.rename.basic; bos@683: bos@684: The output of hg diff above bos@683: obscures the fact that we simply renamed a file. The hg diff command accepts an option, bos@683: or , to use a newer bos@683: diff format that displays such information in a more readable bos@683: form. bos@683: bos@683: &interaction.ch04-diff.rename.git; bos@683: bos@684: This option also helps with a case that can otherwise be bos@683: confusing: a file that appears to be modified according to bos@683: hg status, but for which bos@683: hg diff prints nothing. This bos@683: situation can arise if we change the file's execute bos@683: permissions. bos@683: bos@683: &interaction.ch04-diff.chmod; bos@683: bos@684: The normal diff command pays no attention bos@683: to file permissions, which is why hg bos@683: diff prints nothing by default. If we supply it bos@683: with the option, it tells us what really bos@683: happened. bos@683: bos@683: &interaction.ch04-diff.chmod.git; bos@683: bos@683: bos@683: bos@683: Which files to manage, and which to avoid bos@683: bos@684: Revision control systems are generally best at managing text bos@683: files that are written by humans, such as source code, where the bos@683: files do not change much from one revision to the next. Some bos@683: centralized revision control systems can also deal tolerably bos@683: well with binary files, such as bitmap images. bos@683: bos@684: For instance, a game development team will typically manage bos@683: both its source code and all of its binary assets (e.g. geometry bos@683: data, textures, map layouts) in a revision control bos@683: system. bos@683: bos@684: Because it is usually impossible to merge two conflicting bos@683: modifications to a binary file, centralized systems often bos@683: provide a file locking mechanism that allow a user to say bos@683: I am the only person who can edit this bos@683: file. bos@683: bos@684: Compared to a centralized system, a distributed revision bos@683: control system changes some of the factors that guide decisions bos@683: over which files to manage and how. bos@683: bos@684: For instance, a distributed revision control system cannot, bos@683: by its nature, offer a file locking facility. There is thus no bos@683: built-in mechanism to prevent two people from making conflicting bos@683: changes to a binary file. If you have a team where several bos@683: people may be editing binary files frequently, it may not be a bos@683: good idea to use Mercurial&emdash;or any other distributed bos@683: revision control system&emdash;to manage those files. bos@683: bos@684: When storing modifications to a file, Mercurial usually bos@683: saves only the differences between the previous and current bos@683: versions of the file. For most text files, this is extremely bos@683: efficient. However, some files (particularly binary files) are bos@683: laid out in such a way that even a small change to a file's bos@683: logical content results in many or most of the bytes inside the bos@683: file changing. For instance, compressed files are particularly bos@683: susceptible to this. If the differences between each successive bos@683: version of a file are always large, Mercurial will not be able bos@683: to store the file's revision history very efficiently. This can bos@683: affect both local storage needs and the amount of time it takes bos@683: to clone a repository. bos@683: bos@684: To get an idea of how this could affect you in practice, bos@683: suppose you want to use Mercurial to manage an OpenOffice bos@683: document. OpenOffice stores documents on disk as compressed zip bos@683: files. Edit even a single letter of your document in OpenOffice, bos@683: and almost every byte in the entire file will change when you bos@683: save it. Now suppose that file is 2MB in size. Because most of bos@683: the file changes every time you save, Mercurial will have to bos@683: store all 2MB of the file every time you commit, even though bos@683: from your perspective, perhaps only a few words are changing bos@683: each time. A single frequently-edited file that is not friendly bos@683: to Mercurial's storage assumptions can easily have an outsized bos@683: effect on the size of the repository. bos@683: bos@684: Even worse, if both you and someone else edit the OpenOffice bos@683: document you're working on, there is no useful way to merge your bos@683: work. In fact, there isn't even a good way to tell what the bos@683: differences are between your respective changes. bos@683: bos@684: There are thus a few clear recommendations about specific bos@683: kinds of files to be very careful with. bos@683: bos@683: bos@683: bos@684: Files that are very large and incompressible, e.g. ISO bos@683: CD-ROM images, will by virtue of sheer size make clones over bos@683: a network very slow. bos@683: bos@683: bos@684: Files that change a lot from one revision to the next bos@683: may be expensive to store if you edit them frequently, and bos@683: conflicts due to concurrent edits may be difficult to bos@683: resolve. bos@683: bos@683: bos@683: bos@683: bos@683: bos@683: Backups and mirroring bos@683: bos@684: Since Mercurial maintains a complete copy of history in each bos@683: clone, everyone who uses Mercurial to collaborate on a project bos@683: can potentially act as a source of backups in the event of a bos@683: catastrophe. If a central repository becomes unavailable, you bos@683: can construct a replacement simply by cloning a copy of the bos@683: repository from one contributor, and pulling any changes they bos@683: may not have seen from others. bos@683: bos@684: It is simple to use Mercurial to perform off-site backups bos@683: and remote mirrors. Set up a periodic job (e.g. via the bos@683: cron command) on a remote server to pull bos@683: changes from your master repositories every hour. This will bos@683: only be tricky in the unlikely case that the number of master bos@683: repositories you maintain changes frequently, in which case bos@683: you'll need to do a little scripting to refresh the list of bos@683: repositories to back up. bos@683: bos@684: If you perform traditional backups of your master bos@683: repositories to tape or disk, and you want to back up a bos@701: repository named myrepo, use hg bos@683: clone -U myrepo myrepo.bak to create a bos@683: clone of myrepo before you start your bos@683: backups. The option doesn't check out a bos@683: working directory after the clone completes, since that would be bos@685: superfluous and make the backup take longer. bos@683: bos@684: If you then back up myrepo.bak instead bos@683: of myrepo, you will be guaranteed to have a bos@683: consistent snapshot of your repository that won't be pushed to bos@683: by an insomniac developer in mid-backup. bos@683: bos@559: bos@559: bos@559: