Online Book Reader

Home Category

Mercurial_ The Definitive Guide - Bryan O'Sullivan [31]

By Root 1007 0
to the same file.” When Mercurial is about to write to one of a revlog’s files, it checks to see if the number of names pointing at the file is greater than one. If it is, more than one repository is using the file, so Mercurial makes a new copy of the file that is private to this repository.

A few revision control developers have pointed out that this idea of making a complete private copy of a file is not very efficient in its use of storage. While this is true, storage is cheap, and this method gives the highest performance while deferring most book-keeping to the operating system. An alternative scheme would most likely reduce performance and increase the complexity of the software, but speed and simplicity are key to the “feel” of day-to-day use.

Other Contents of the Dirstate

Because Mercurial doesn’t force you to tell it when you’re modifying a file, it uses the dirstate to store some extra information so it can determine efficiently whether you have modified a file. For each file in the working directory, it stores the time that it last modified the file itself, and the size of the file at that time.

When you explicitly hg add, hg remove, hg rename, or hg copy files, Mercurial updates the dirstate so that it knows what to do with those files when you commit.

The dirstate helps Mercurial to efficiently check the status of files in a repository:

When Mercurial checks the state of a file in the working directory, it first checks a file’s modification time against the time in the dirstate that records when Mercurial last wrote the file. If the last modified time is the same as the time when Mercurial wrote the file, the file must not have been modified, so Mercurial does not need to check any further.

If the file’s size has changed, the file must have been modified. If the modification time has changed but the size has not, only then does Mercurial need to actually read the contents of the file to see if it has changed.

Storing the modification time and size dramatically reduces the number of read operations that Mercurial needs to perform when we run commands like hg status. This results in large performance improvements.

Chapter 5. Mercurial in Daily Use

Telling Mercurial Which Files to Track

Mercurial does not work with files in your repository unless you tell it to manage them. The hg status command will tell you which files Mercurial doesn’t know about; it uses a ? to display such files.

To tell Mercurial to track a file, use the hg add command. Once you have added a file, the entry in the output of hg status for that file changes from ? to A.

$ hg init add-example

$ cd add-example

$ echo a > myfile.txt

$ hg status

? myfile.txt

$ hg add myfile.txt

$ hg status

A myfile.txt

$ hg commit -m 'Added one file'

$ hg status

After you run a hg commit, the files that you added before the commit will no longer be listed in the output of hg status. The reason for this is that by default, hg status only tells you about “interesting” files—those that you have (for example) modified, removed, or renamed. If you have a repository that contains thousands of files, you will rarely want to know about files that Mercurial is tracking, but that have not changed. (You can still get this information; we’ll return to this later.)

Once you add a file, Mercurial doesn’t do anything with it immediately. Instead, it will take a snapshot of the file’s state the next time you perform a commit. It will then continue to track the changes you make to the file every time you commit, until you remove the file.

Explicit Versus Implicit File Naming

A useful behavior that Mercurial has is that if you pass the name of a directory to a command, every Mercurial command will treat this as “I want to operate on every file in this directory and its subdirectories.”

$ mkdir b

$ echo b > b/somefile.txt

$ echo c > b/source.cpp

$ mkdir b/d

$ echo d > b/d/test.h

$ hg add b

adding b/d/test.h

adding b/somefile.txt

adding b/source.cpp

$ hg commit -m 'Added all files in subdirectory'

Notice in

Return Main Page Previous Page Next Page

®Online Book Reader