hgbook

view en/ch05-daily.tex @ 551:f72b7e6cbe90

Snapshot.
author Bryan O'Sullivan <bos@serpentine.com>
date Thu Feb 05 00:01:16 2009 -0800 (2009-02-05)
parents 5cd47f721686
children
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 you 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 After you \hgcmd{remove} a file, Mercurial will no longer track
94 changes to that file, even if you recreate a file with the same name
95 in your working directory. If you do recreate a file with the same
96 name and want Mercurial to track the new file, simply \hgcmd{add} it.
97 Mercurial will know that the newly added file is not related to the
98 old file of the same name.
100 \subsection{Removing a file does not affect its history}
102 It is important to understand that removing a file has only two
103 effects.
104 \begin{itemize}
105 \item It removes the current version of the file from the working
106 directory.
107 \item It stops Mercurial from tracking changes to the file, from the
108 time of the next commit.
109 \end{itemize}
110 Removing a file \emph{does not} in any way alter the \emph{history} of
111 the file.
113 If you update the working directory to a changeset in which a file
114 that you have removed was still tracked, it will reappear in the
115 working directory, with the contents it had when you committed that
116 changeset. If you then update the working directory to a later
117 changeset, in which the file had been removed, Mercurial will once
118 again remove the file from the working directory.
120 \subsection{Missing files}
122 Mercurial considers a file that you have deleted, but not used
123 \hgcmd{remove} to delete, to be \emph{missing}. A missing file is
124 represented with ``\texttt{!}'' in the output of \hgcmd{status}.
125 Mercurial commands will not generally do anything with missing files.
126 \interaction{daily.files.missing}
128 If your repository contains a file that \hgcmd{status} reports as
129 missing, and you want the file to stay gone, you can run
130 \hgcmdargs{remove}{\hgopt{remove}{--after}} at any time later on, to
131 tell Mercurial that you really did mean to remove the file.
132 \interaction{daily.files.remove-after}
134 On the other hand, if you deleted the missing file by accident, use
135 \hgcmdargs{revert}{\emph{filename}} to recover the file. It will
136 reappear, in unmodified form.
137 \interaction{daily.files.recover-missing}
139 \subsection{Aside: why tell Mercurial explicitly to remove a file?}
141 You might wonder why Mercurial requires you to explicitly tell it that
142 you are deleting a file. Early during the development of Mercurial,
143 it let you delete a file however you pleased; Mercurial would notice
144 the absence of the file automatically when you next ran a
145 \hgcmd{commit}, and stop tracking the file. In practice, this made it
146 too easy to accidentally remove a file without noticing.
148 \subsection{Useful shorthand---adding and removing files in one step}
150 Mercurial offers a combination command, \hgcmd{addremove}, that adds
151 untracked files and marks missing files as removed.
152 \interaction{daily.files.addremove}
153 The \hgcmd{commit} command also provides a \hgopt{commit}{-A} option
154 that performs this same add-and-remove, immediately followed by a
155 commit.
156 \interaction{daily.files.commit-addremove}
158 \section{Copying files}
160 Mercurial provides a \hgcmd{copy} command that lets you make a new
161 copy of a file. When you copy a file using this command, Mercurial
162 makes a record of the fact that the new file is a copy of the original
163 file. It treats these copied files specially when you merge your work
164 with someone else's.
166 \subsection{The results of copying during a merge}
168 What happens during a merge is that changes ``follow'' a copy. To
169 best illustrate what this means, let's create an example. We'll start
170 with the usual tiny repository that contains a single file.
171 \interaction{daily.copy.init}
172 We need to do some work in parallel, so that we'll have something to
173 merge. So let's clone our repository.
174 \interaction{daily.copy.clone}
175 Back in our initial repository, let's use the \hgcmd{copy} command to
176 make a copy of the first file we created.
177 \interaction{daily.copy.copy}
179 If we look at the output of the \hgcmd{status} command afterwards, the
180 copied file looks just like a normal added file.
181 \interaction{daily.copy.status}
182 But if we pass the \hgopt{status}{-C} option to \hgcmd{status}, it
183 prints another line of output: this is the file that our newly-added
184 file was copied \emph{from}.
185 \interaction{daily.copy.status-copy}
187 Now, back in the repository we cloned, let's make a change in
188 parallel. We'll add a line of content to the original file that we
189 created.
190 \interaction{daily.copy.other}
191 Now we have a modified \filename{file} in this repository. When we
192 pull the changes from the first repository, and merge the two heads,
193 Mercurial will propagate the changes that we made locally to
194 \filename{file} into its copy, \filename{new-file}.
195 \interaction{daily.copy.merge}
197 \subsection{Why should changes follow copies?}
198 \label{sec:daily:why-copy}
200 This behaviour, of changes to a file propagating out to copies of the
201 file, might seem esoteric, but in most cases it's highly desirable.
203 First of all, remember that this propagation \emph{only} happens when
204 you merge. So if you \hgcmd{copy} a file, and subsequently modify the
205 original file during the normal course of your work, nothing will
206 happen.
208 The second thing to know is that modifications will only propagate
209 across a copy as long as the repository that you're pulling changes
210 from \emph{doesn't know} about the copy.
212 The reason that Mercurial does this is as follows. Let's say I make
213 an important bug fix in a source file, and commit my changes.
214 Meanwhile, you've decided to \hgcmd{copy} the file in your repository,
215 without knowing about the bug or having seen the fix, and you have
216 started hacking on your copy of the file.
218 If you pulled and merged my changes, and Mercurial \emph{didn't}
219 propagate changes across copies, your source file would now contain
220 the bug, and unless you remembered to propagate the bug fix by hand,
221 the bug would \emph{remain} in your copy of the file.
223 By automatically propagating the change that fixed the bug from the
224 original file to the copy, Mercurial prevents this class of problem.
225 To my knowledge, Mercurial is the \emph{only} revision control system
226 that propagates changes across copies like this.
228 Once your change history has a record that the copy and subsequent
229 merge occurred, there's usually no further need to propagate changes
230 from the original file to the copied file, and that's why Mercurial
231 only propagates changes across copies until this point, and no
232 further.
234 \subsection{How to make changes \emph{not} follow a copy}
236 If, for some reason, you decide that this business of automatically
237 propagating changes across copies is not for you, simply use your
238 system's normal file copy command (on Unix-like systems, that's
239 \command{cp}) to make a copy of a file, then \hgcmd{add} the new copy
240 by hand. Before you do so, though, please do reread
241 section~\ref{sec:daily:why-copy}, and make an informed decision that
242 this behaviour is not appropriate to your specific case.
244 \subsection{Behaviour of the \hgcmd{copy} command}
246 When you use the \hgcmd{copy} command, Mercurial makes a copy of each
247 source file as it currently stands in the working directory. This
248 means that if you make some modifications to a file, then \hgcmd{copy}
249 it without first having committed those changes, the new copy will
250 also contain the modifications you have made up until that point. (I
251 find this behaviour a little counterintuitive, which is why I mention
252 it here.)
254 The \hgcmd{copy} command acts similarly to the Unix \command{cp}
255 command (you can use the \hgcmd{cp} alias if you prefer). The last
256 argument is the \emph{destination}, and all prior arguments are
257 \emph{sources}. If you pass it a single file as the source, and the
258 destination does not exist, it creates a new file with that name.
259 \interaction{daily.copy.simple}
260 If the destination is a directory, Mercurial copies its sources into
261 that directory.
262 \interaction{daily.copy.dir-dest}
263 Copying a directory is recursive, and preserves the directory
264 structure of the source.
265 \interaction{daily.copy.dir-src}
266 If the source and destination are both directories, the source tree is
267 recreated in the destination directory.
268 \interaction{daily.copy.dir-src-dest}
270 As with the \hgcmd{rename} command, if you copy a file manually and
271 then want Mercurial to know that you've copied the file, simply use
272 the \hgopt{copy}{--after} option to \hgcmd{copy}.
273 \interaction{daily.copy.after}
275 \section{Renaming files}
277 It's rather more common to need to rename a file than to make a copy
278 of it. The reason I discussed the \hgcmd{copy} command before talking
279 about renaming files is that Mercurial treats a rename in essentially
280 the same way as a copy. Therefore, knowing what Mercurial does when
281 you copy a file tells you what to expect when you rename a file.
283 When you use the \hgcmd{rename} command, Mercurial makes a copy of
284 each source file, then deletes it and marks the file as removed.
285 \interaction{daily.rename.rename}
286 The \hgcmd{status} command shows the newly copied file as added, and
287 the copied-from file as removed.
288 \interaction{daily.rename.status}
289 As with the results of a \hgcmd{copy}, we must use the
290 \hgopt{status}{-C} option to \hgcmd{status} to see that the added file
291 is really being tracked by Mercurial as a copy of the original, now
292 removed, file.
293 \interaction{daily.rename.status-copy}
295 As with \hgcmd{remove} and \hgcmd{copy}, you can tell Mercurial about
296 a rename after the fact using the \hgopt{rename}{--after} option. In
297 most other respects, the behaviour of the \hgcmd{rename} command, and
298 the options it accepts, are similar to the \hgcmd{copy} command.
300 \subsection{Renaming files and merging changes}
302 Since Mercurial's rename is implemented as copy-and-remove, the same
303 propagation of changes happens when you merge after a rename as after
304 a copy.
306 If I modify a file, and you rename it to a new name, and then we merge
307 our respective changes, my modifications to the file under its
308 original name will be propagated into the file under its new name.
309 (This is something you might expect to ``simply work,'' but not all
310 revision control systems actually do this.)
312 Whereas having changes follow a copy is a feature where you can
313 perhaps nod and say ``yes, that might be useful,'' it should be clear
314 that having them follow a rename is definitely important. Without
315 this facility, it would simply be too easy for changes to become
316 orphaned when files are renamed.
318 \subsection{Divergent renames and merging}
320 The case of diverging names occurs when two developers start with a
321 file---let's call it \filename{foo}---in their respective
322 repositories.
324 \interaction{rename.divergent.clone}
325 Anne renames the file to \filename{bar}.
326 \interaction{rename.divergent.rename.anne}
327 Meanwhile, Bob renames it to \filename{quux}.
328 \interaction{rename.divergent.rename.bob}
330 I like to think of this as a conflict because each developer has
331 expressed different intentions about what the file ought to be named.
333 What do you think should happen when they merge their work?
334 Mercurial's actual behaviour is that it always preserves \emph{both}
335 names when it merges changesets that contain divergent renames.
336 \interaction{rename.divergent.merge}
338 Notice that Mercurial does warn about the divergent renames, but it
339 leaves it up to you to do something about the divergence after the merge.
341 \subsection{Convergent renames and merging}
343 Another kind of rename conflict occurs when two people choose to
344 rename different \emph{source} files to the same \emph{destination}.
345 In this case, Mercurial runs its normal merge machinery, and lets you
346 guide it to a suitable resolution.
348 \subsection{Other name-related corner cases}
350 Mercurial has a longstanding bug in which it fails to handle a merge
351 where one side has a file with a given name, while another has a
352 directory with the same name. This is documented as~\bug{29}.
353 \interaction{issue29.go}
355 \section{Recovering from mistakes}
357 Mercurial has some useful commands that will help you to recover from
358 some common mistakes.
360 The \hgcmd{revert} command lets you undo changes that you have made to
361 your working directory. For example, if you \hgcmd{add} a file by
362 accident, just run \hgcmd{revert} with the name of the file you added,
363 and while the file won't be touched in any way, it won't be tracked
364 for adding by Mercurial any longer, either. You can also use
365 \hgcmd{revert} to get rid of erroneous changes to a file.
367 It's useful to remember that the \hgcmd{revert} command is useful for
368 changes that you have not yet committed. Once you've committed a
369 change, if you decide it was a mistake, you can still do something
370 about it, though your options may be more limited.
372 For more information about the \hgcmd{revert} command, and details
373 about how to deal with changes you have already committed, see
374 chapter~\ref{chap:undo}.
376 %%% Local Variables:
377 %%% mode: latex
378 %%% TeX-master: "00book"
379 %%% End: