hgbook

view en/daily.tex @ 117:6b0f4498569e

Beef up daily routine material. Focus on merge-across-copy.
author Bryan O'Sullivan <bos@serpentine.com>
date Tue Nov 14 15:11:22 2006 -0800 (2006-11-14)
parents 7ac85766db0f
children 1ee53cb37a99
line source
1 \chapter{Mercurial in daily use}
2 \label{chap:daily}
4 \section{Telling Mercurial which files to track}
6 Mercurial does not work with files in your repository unless you tell
7 it to manage them. The \hgcmd{status} command will tell you which
8 files Mercurial doesn't know about; it uses a ``\texttt{?}'' to
9 display such files.
11 To tell Mercurial to track a file, use the \hgcmd{add} command. Once
12 you have added a file, the entry in the output of \hgcmd{status} for
13 that file changes from ``\texttt{?}'' to ``\texttt{A}''.
14 \interaction{daily.files.add}
16 After you run a \hgcmd{commit}, the files that you added before the
17 commit will no longer be listed in the output of \hgcmd{status}. The
18 reason for this is that \hgcmd{status} only tells you about
19 ``interesting'' files---those that you have modified or told Mercurial
20 to do something with---by default. If you have a repository that
21 contains thousands of files, you will rarely want to know about files
22 that Mercurial is tracking, but that have not changed. (You can still
23 get this information; we'll return to this later.)
25 Once you add a file, Mercurial doesn't do anything with it
26 immediately. Instead, it will take a snapshot of the file's state the
27 next time you perform a commit. It will then continue to track the
28 changes you make to the file every time you commit, until you remove
29 the file.
31 \subsection{Explicit versus implicit file naming}
33 A useful behaviour that Mercurial has is that if you pass the name of
34 a directory to a command, every Mercurial command will treat this as
35 ``I want to operate on every file in this directory and its
36 subdirectories''.
37 \interaction{daily.files.add-dir}
38 Notice in this example that Mercurial printed the names of the files
39 it added, whereas it didn't do so when we added the file named
40 \filename{a} in the earlier example.
42 What's going on is that in the former case, we explicitly named the
43 file to add on the command line, so the assumption that Mercurial
44 makes in such cases is that we know what you were doing, and it
45 doesn't print any output.
47 However, when we \emph{imply} the names of files by giving the name of
48 a directory, Mercurial takes the extra step of printing the name of
49 each file that it does something with. This makes it more clear what
50 is happening, and reduces the likelihood of a silent and nasty
51 surprise. This behaviour is common to most Mercurial commands.
53 \subsection{Aside: Mercurial tracks files, not directories}
55 Mercurial does not track directory information. Instead, it tracks
56 the path to a file. Before creating a file, it first creates any
57 missing directory components of the path. After it deletes a file, it
58 then deletes any empty directories that were in the deleted file's
59 path. This sounds like a trivial distinction, but it has one minor
60 practical consequence: it is not possible to represent a completely
61 empty directory in Mercurial.
63 Empty directories are rarely useful, and there are unintrusive
64 workarounds that you can use to achieve an appropriate effect. The
65 developers of Mercurial thus felt that the complexity that would be
66 required to manage empty directories was not worth the limited benefit
67 this feature would bring.
69 If you need an empty directory in your repository, there are a few
70 ways to achieve this. One is to create a directory, then \hgcmd{add} a
71 ``hidden'' file to that directory. On Unix-like systems, any file
72 name that begins with a period (``\texttt{.}'') is treated as hidden
73 by most commands and GUI tools. This approach is illustrated in
74 figure~\ref{ex:daily:hidden}.
76 \begin{figure}[ht]
77 \interaction{daily.files.hidden}
78 \caption{Simulating an empty directory using a hidden file}
79 \label{ex:daily:hidden}
80 \end{figure}
82 Another way to tackle a need for an empty directory is to simply
83 create one in your automated build scripts before they will need it.
85 \section{How to stop tracking a file}
87 Once you decide that a file no longer belongs in your repository, use
88 the \hgcmd{remove} command; this deletes the file, and tells Mercurial
89 to stop tracking it. A removed file is represented in the output of
90 \hgcmd{status} with a ``\texttt{R}''.
91 \interaction{daily.files.remove}
93 \subsection{Missing files}
95 Mercurial considers a file that you have deleted, but not used
96 \hgcmd{remove} to delete, to be \emph{missing}. A missing file is
97 represented with ``\texttt{!}'' in the output of \hgcmd{status}.
98 Mercurial commands will not generally do anything with missing files.
99 \interaction{daily.files.missing}
101 If your repository contains a file that \hgcmd{status} reports as
102 missing, and you want the file to stay gone, you can run
103 \hgcmdargs{remove}{\hgopt{remove}{--after}} at any time later on, to
104 tell Mercurial that you really did mean to remove the file.
105 \interaction{daily.files.remove-after}
107 On the other hand, if you deleted the missing file by accident, use
108 \hgcmdargs{revert}{\emph{filename}} to recover the file. It will
109 reappear, in unmodified form.
110 \interaction{daily.files.recover-missing}
112 \subsection{Aside: why tell Mercurial explicitly to
113 remove a file?}
115 You might wonder why Mercurial requires you to explicitly tell it that
116 you are deleting a file. Early during the development of Mercurial,
117 it let you delete a file however you pleased; Mercurial would notice
118 the absence of the file automatically when you next ran a
119 \hgcmd{commit}, and stop tracking the file. In practice, this made it
120 too easy to accidentally remove a file without noticing.
122 \subsection{Useful shorthand---adding and removing files
123 in one step}
125 Mercurial offers a combination command, \hgcmd{addremove}, that adds
126 untracked files and marks missing files as removed.
127 \interaction{daily.files.addremove}
128 The \hgcmd{commit} command also provides a \hgopt{commit}{-A} option
129 that performs this same add-and-remove, immediately followed by a
130 commit.
131 \interaction{daily.files.commit-addremove}
133 \section{Copying files}
135 Mercurial provides a \hgcmd{copy} command that lets you make a new
136 copy of a file. When you copy a file using this command, Mercurial
137 makes a record of the fact that the new file is a copy of the original
138 file. It treats these copied files specially when you merge your work
139 with someone else's.
141 What happens during a merge is that changes ``follow'' a copy. To
142 best illustrate what this means, let's create an example. We'll start
143 with the usual tiny repository that contains a single file.
144 \interaction{daily.copy.init}
145 We need to do some work in parallel, so that we'll have something to
146 merge. So let's clone our repository.
147 \interaction{daily.copy.clone}
148 Back in our initial repository, let's use the \hgcmd{copy} command to
149 make a copy of the first file we created.
150 \interaction{daily.copy.copy}
152 If we look at the output of the \hgcmd{status} command afterwards, the
153 copied file looks just like a normal added file.
154 \interaction{daily.copy.status}
155 But if we pass the \hgopt{status}{-C} option to \hgcmd{status}, it
156 prints another line of output: this is the file that our newly-added
157 file was copied \emph{from}.
158 \interaction{daily.copy.status-copy}
160 Now, back in the repository we cloned, let's make a change in
161 parallel. We'll add a line of content to the original file that we
162 created.
163 \interaction{daily.copy.other}
164 Now we have a modified \filename{file} in this repository. When we
165 pull the changes from the first repository, and merge the two heads,
166 Mercurial will propagate the changes that we made locally to
167 \filename{file} into its copy, \filename{new-file}.
168 \interaction{daily.copy.merge}
170 \subsection{Why should changes follow copies?}
171 \label{sec:daily:why-copy}
173 This behaviour, of changes to a file propagating out to copies of the
174 file, might seem esoteric, but in most cases it's highly desirable.
176 First of all, remember that this propagation \emph{only} happens when
177 you merge. So if you \hgcmd{copy} a file, and subsequently modify the
178 original file during the normal course of your work, nothing will
179 happen.
181 The second thing to know is that modifications will only propagate
182 across a copy as long as the repository that you're pulling changes
183 from \emph{doesn't know} about the copy.
185 The reason that Mercurial does this is as follows. Let's say I make
186 an important bug fix in a source file, and commit my changes.
187 Meanwhile, you've decided to \hgcmd{copy} the file in your repository,
188 without knowing about the bug or having seen the fix, and you have
189 started hacking on your copy of the file.
191 If you pulled and merged my changes, and Mercurial \emph{didn't}
192 propagate changes across copies, your source file would now contain
193 the bug, and unless you remembered to propagate the bug fix by hand,
194 the bug would \emph{remain} in your copy of the file.
196 By automatically propagating the change that fixed the bug from the
197 original file to the copy, Mercurial prevents this class of problem.
198 To my knowledge, Mercurial is the \emph{only} revision control system
199 that propagates changes across copies like this.
201 Once your change history has a record that the copy and subsequent
202 merge occurred, there's usually no further need to propagate changes
203 from the original file to the copied file, and that's why Mercurial
204 only propagates changes across copies until this point, and no
205 further.
207 \subsection{How to make changes \emph{not} follow a copy}
209 If, for some reason, you decide that this business of automatically
210 propagating changes across copies is not for you, simply use your
211 system's normal file copy command (on Unix-like systems, that's
212 \command{cp}) to make a copy of a file, then \hgcmd{add} the new copy
213 by hand. Before you do so, though, please do reread
214 section~\ref{sec:daily:why-copy}, and make an informed decision that
215 this behaviour is not appropriate to your specific case.
217 \subsection{Behaviour of the \hgcmd{copy} command}
219 The \hgcmd{copy} command acts similarly to the Unix \command{cp}
220 command. The last argument is the \emph{destination}, and all prior
221 arguments are \emph{sources}.
222 If you pass it a single file as the source, and the destination
223 does not exist, it creates a new file with that name.
224 \interaction{daily.copy.simple}
225 If the destination is a directory, Mercurial copies its sources into
226 that directory.
227 \interaction{daily.copy.dir-dest}
228 Copying a directory is recursive, and preserves the directory
229 structure of the source.
230 \interaction{daily.copy.dir-src}
231 If the source and destination are both directories, the source tree is
232 recreated in the destination directory.
233 \interaction{daily.copy.dir-src-dest}
235 \section{Renaming files}
237 To rename a file that is tracked by Mercurial, use the \hgcmd{rename}
238 command. This command behaves similarly to the Unix \command{mv}
239 command (and in fact you can use the alias \hgcmd{mv} if you wish).
240 If the last argument is a directory, \hgcmd{rename} moves all files
241 identified by earlier arguments into that directory. Otherwise, it
242 renames a single file or directory to the name given in the last
243 argument.
245 As with \hgcmd{remove}, you can tell Mercurial about a rename after
246 the fact using the \hgopt{remove}{--after} option.
248 %%% Local Variables:
249 %%% mode: latex
250 %%% TeX-master: "00book"
251 %%% End: