hgbook

annotate en/daily.tex @ 307:fb5c0d56d7f1

Fix test 'tour'.

Executing 'tour' test now creates some files in /tmp to store the
revision numbers as they are created on the fly and appear in the output
files. When SVG files are to be converted to PNG or EPS files within the
Makefile, a tool 'fixsvg' will be invoked to substitute some placeholder
markup by the real version number which fits to the test output, before
the final conversion takes place.
author Guido Ostkamp <hg@ostkamp.fastmail.fm>
date Wed Aug 20 22:15:35 2008 +0200 (2008-08-20)
parents abebe72451d6
children
rev   line source
bos@42 1 \chapter{Mercurial in daily use}
bos@42 2 \label{chap:daily}
bos@42 3
bos@117 4 \section{Telling Mercurial which files to track}
bos@42 5
bos@42 6 Mercurial does not work with files in your repository unless you tell
bos@42 7 it to manage them. The \hgcmd{status} command will tell you which
bos@42 8 files Mercurial doesn't know about; it uses a ``\texttt{?}'' to
bos@42 9 display such files.
bos@42 10
bos@42 11 To tell Mercurial to track a file, use the \hgcmd{add} command. Once
bos@42 12 you have added a file, the entry in the output of \hgcmd{status} for
bos@42 13 that file changes from ``\texttt{?}'' to ``\texttt{A}''.
bos@117 14 \interaction{daily.files.add}
bos@42 15
bos@42 16 After you run a \hgcmd{commit}, the files that you added before the
bos@42 17 commit will no longer be listed in the output of \hgcmd{status}. The
bos@42 18 reason for this is that \hgcmd{status} only tells you about
bos@117 19 ``interesting'' files---those that you have modified or told Mercurial
bos@117 20 to do something with---by default. If you have a repository that
bos@42 21 contains thousands of files, you will rarely want to know about files
bos@42 22 that Mercurial is tracking, but that have not changed. (You can still
bos@42 23 get this information; we'll return to this later.)
bos@42 24
bos@117 25 Once you add a file, Mercurial doesn't do anything with it
bos@117 26 immediately. Instead, it will take a snapshot of the file's state the
bos@117 27 next time you perform a commit. It will then continue to track the
bos@117 28 changes you make to the file every time you commit, until you remove
bos@117 29 the file.
bos@117 30
bos@117 31 \subsection{Explicit versus implicit file naming}
bos@117 32
bos@117 33 A useful behaviour that Mercurial has is that if you pass the name of
bos@117 34 a directory to a command, every Mercurial command will treat this as
bos@117 35 ``I want to operate on every file in this directory and its
bos@117 36 subdirectories''.
bos@117 37 \interaction{daily.files.add-dir}
bos@117 38 Notice in this example that Mercurial printed the names of the files
bos@117 39 it added, whereas it didn't do so when we added the file named
bos@117 40 \filename{a} in the earlier example.
bos@117 41
bos@117 42 What's going on is that in the former case, we explicitly named the
bos@117 43 file to add on the command line, so the assumption that Mercurial
steve@178 44 makes in such cases is that you know what you were doing, and it
bos@117 45 doesn't print any output.
bos@117 46
bos@117 47 However, when we \emph{imply} the names of files by giving the name of
bos@117 48 a directory, Mercurial takes the extra step of printing the name of
bos@117 49 each file that it does something with. This makes it more clear what
bos@117 50 is happening, and reduces the likelihood of a silent and nasty
bos@117 51 surprise. This behaviour is common to most Mercurial commands.
bos@117 52
bos@117 53 \subsection{Aside: Mercurial tracks files, not directories}
bos@42 54
bos@42 55 Mercurial does not track directory information. Instead, it tracks
bos@117 56 the path to a file. Before creating a file, it first creates any
bos@117 57 missing directory components of the path. After it deletes a file, it
bos@117 58 then deletes any empty directories that were in the deleted file's
bos@117 59 path. This sounds like a trivial distinction, but it has one minor
bos@42 60 practical consequence: it is not possible to represent a completely
bos@42 61 empty directory in Mercurial.
bos@42 62
bos@42 63 Empty directories are rarely useful, and there are unintrusive
bos@42 64 workarounds that you can use to achieve an appropriate effect. The
bos@42 65 developers of Mercurial thus felt that the complexity that would be
bos@42 66 required to manage empty directories was not worth the limited benefit
bos@42 67 this feature would bring.
bos@42 68
bos@42 69 If you need an empty directory in your repository, there are a few
bos@42 70 ways to achieve this. One is to create a directory, then \hgcmd{add} a
bos@42 71 ``hidden'' file to that directory. On Unix-like systems, any file
bos@42 72 name that begins with a period (``\texttt{.}'') is treated as hidden
bos@42 73 by most commands and GUI tools. This approach is illustrated in
bos@43 74 figure~\ref{ex:daily:hidden}.
bos@42 75
bos@42 76 \begin{figure}[ht]
bos@43 77 \interaction{daily.files.hidden}
bos@43 78 \caption{Simulating an empty directory using a hidden file}
bos@43 79 \label{ex:daily:hidden}
bos@42 80 \end{figure}
bos@42 81
bos@42 82 Another way to tackle a need for an empty directory is to simply
bos@42 83 create one in your automated build scripts before they will need it.
bos@42 84
bos@117 85 \section{How to stop tracking a file}
bos@117 86
bos@117 87 Once you decide that a file no longer belongs in your repository, use
bos@42 88 the \hgcmd{remove} command; this deletes the file, and tells Mercurial
bos@43 89 to stop tracking it. A removed file is represented in the output of
bos@43 90 \hgcmd{status} with a ``\texttt{R}''.
bos@117 91 \interaction{daily.files.remove}
bos@117 92
bos@118 93 After you \hgcmd{remove} a file, Mercurial will no longer track
bos@118 94 changes to that file, even if you recreate a file with the same name
bos@118 95 in your working directory. If you do recreate a file with the same
bos@118 96 name and want Mercurial to track the new file, simply \hgcmd{add} it.
bos@118 97 Mercurial will know that the newly added file is not related to the
bos@118 98 old file of the same name.
bos@118 99
bos@118 100 \subsection{Removing a file does not affect its history}
bos@118 101
bos@118 102 It is important to understand that removing a file has only two
bos@118 103 effects.
bos@118 104 \begin{itemize}
bos@118 105 \item It removes the current version of the file from the working
bos@118 106 directory.
bos@118 107 \item It stops Mercurial from tracking changes to the file, from the
bos@118 108 time of the next commit.
bos@118 109 \end{itemize}
bos@118 110 Removing a file \emph{does not} in any way alter the \emph{history} of
bos@118 111 the file.
bos@118 112
bos@118 113 If you update the working directory to a changeset in which a file
bos@118 114 that you have removed was still tracked, it will reappear in the
bos@118 115 working directory, with the contents it had when you committed that
bos@118 116 changeset. If you then update the working directory to a later
bos@118 117 changeset, in which the file had been removed, Mercurial will once
bos@118 118 again remove the file from the working directory.
bos@118 119
bos@117 120 \subsection{Missing files}
bos@42 121
bos@43 122 Mercurial considers a file that you have deleted, but not used
bos@43 123 \hgcmd{remove} to delete, to be \emph{missing}. A missing file is
bos@43 124 represented with ``\texttt{!}'' in the output of \hgcmd{status}.
bos@117 125 Mercurial commands will not generally do anything with missing files.
bos@117 126 \interaction{daily.files.missing}
bos@117 127
bos@117 128 If your repository contains a file that \hgcmd{status} reports as
bos@117 129 missing, and you want the file to stay gone, you can run
bos@117 130 \hgcmdargs{remove}{\hgopt{remove}{--after}} at any time later on, to
bos@117 131 tell Mercurial that you really did mean to remove the file.
bos@117 132 \interaction{daily.files.remove-after}
bos@117 133
bos@117 134 On the other hand, if you deleted the missing file by accident, use
bos@117 135 \hgcmdargs{revert}{\emph{filename}} to recover the file. It will
bos@117 136 reappear, in unmodified form.
bos@117 137 \interaction{daily.files.recover-missing}
bos@117 138
bos@117 139 \subsection{Aside: why tell Mercurial explicitly to
bos@117 140 remove a file?}
bos@117 141
bos@117 142 You might wonder why Mercurial requires you to explicitly tell it that
bos@117 143 you are deleting a file. Early during the development of Mercurial,
bos@117 144 it let you delete a file however you pleased; Mercurial would notice
bos@117 145 the absence of the file automatically when you next ran a
bos@117 146 \hgcmd{commit}, and stop tracking the file. In practice, this made it
bos@117 147 too easy to accidentally remove a file without noticing.
bos@117 148
bos@117 149 \subsection{Useful shorthand---adding and removing files
bos@117 150 in one step}
bos@42 151
bos@43 152 Mercurial offers a combination command, \hgcmd{addremove}, that adds
bos@117 153 untracked files and marks missing files as removed.
bos@117 154 \interaction{daily.files.addremove}
bos@117 155 The \hgcmd{commit} command also provides a \hgopt{commit}{-A} option
bos@117 156 that performs this same add-and-remove, immediately followed by a
bos@117 157 commit.
bos@117 158 \interaction{daily.files.commit-addremove}
bos@117 159
bos@117 160 \section{Copying files}
bos@117 161
bos@117 162 Mercurial provides a \hgcmd{copy} command that lets you make a new
bos@117 163 copy of a file. When you copy a file using this command, Mercurial
bos@117 164 makes a record of the fact that the new file is a copy of the original
bos@117 165 file. It treats these copied files specially when you merge your work
bos@117 166 with someone else's.
bos@117 167
bos@121 168 \subsection{The results of copying during a merge}
bos@121 169
bos@117 170 What happens during a merge is that changes ``follow'' a copy. To
bos@117 171 best illustrate what this means, let's create an example. We'll start
bos@117 172 with the usual tiny repository that contains a single file.
bos@117 173 \interaction{daily.copy.init}
bos@117 174 We need to do some work in parallel, so that we'll have something to
bos@117 175 merge. So let's clone our repository.
bos@117 176 \interaction{daily.copy.clone}
bos@117 177 Back in our initial repository, let's use the \hgcmd{copy} command to
bos@117 178 make a copy of the first file we created.
bos@117 179 \interaction{daily.copy.copy}
bos@117 180
bos@117 181 If we look at the output of the \hgcmd{status} command afterwards, the
bos@117 182 copied file looks just like a normal added file.
bos@117 183 \interaction{daily.copy.status}
bos@117 184 But if we pass the \hgopt{status}{-C} option to \hgcmd{status}, it
bos@117 185 prints another line of output: this is the file that our newly-added
bos@117 186 file was copied \emph{from}.
bos@117 187 \interaction{daily.copy.status-copy}
bos@117 188
bos@117 189 Now, back in the repository we cloned, let's make a change in
bos@117 190 parallel. We'll add a line of content to the original file that we
bos@117 191 created.
bos@117 192 \interaction{daily.copy.other}
bos@117 193 Now we have a modified \filename{file} in this repository. When we
bos@117 194 pull the changes from the first repository, and merge the two heads,
bos@117 195 Mercurial will propagate the changes that we made locally to
bos@117 196 \filename{file} into its copy, \filename{new-file}.
bos@117 197 \interaction{daily.copy.merge}
bos@117 198
bos@117 199 \subsection{Why should changes follow copies?}
bos@117 200 \label{sec:daily:why-copy}
bos@117 201
bos@117 202 This behaviour, of changes to a file propagating out to copies of the
bos@117 203 file, might seem esoteric, but in most cases it's highly desirable.
bos@117 204
bos@117 205 First of all, remember that this propagation \emph{only} happens when
bos@117 206 you merge. So if you \hgcmd{copy} a file, and subsequently modify the
bos@117 207 original file during the normal course of your work, nothing will
bos@117 208 happen.
bos@117 209
bos@117 210 The second thing to know is that modifications will only propagate
bos@117 211 across a copy as long as the repository that you're pulling changes
bos@117 212 from \emph{doesn't know} about the copy.
bos@117 213
bos@117 214 The reason that Mercurial does this is as follows. Let's say I make
bos@117 215 an important bug fix in a source file, and commit my changes.
bos@117 216 Meanwhile, you've decided to \hgcmd{copy} the file in your repository,
bos@117 217 without knowing about the bug or having seen the fix, and you have
bos@117 218 started hacking on your copy of the file.
bos@117 219
bos@117 220 If you pulled and merged my changes, and Mercurial \emph{didn't}
bos@117 221 propagate changes across copies, your source file would now contain
bos@117 222 the bug, and unless you remembered to propagate the bug fix by hand,
bos@117 223 the bug would \emph{remain} in your copy of the file.
bos@117 224
bos@117 225 By automatically propagating the change that fixed the bug from the
bos@117 226 original file to the copy, Mercurial prevents this class of problem.
bos@117 227 To my knowledge, Mercurial is the \emph{only} revision control system
bos@117 228 that propagates changes across copies like this.
bos@117 229
bos@117 230 Once your change history has a record that the copy and subsequent
bos@117 231 merge occurred, there's usually no further need to propagate changes
bos@117 232 from the original file to the copied file, and that's why Mercurial
bos@117 233 only propagates changes across copies until this point, and no
bos@117 234 further.
bos@117 235
bos@117 236 \subsection{How to make changes \emph{not} follow a copy}
bos@117 237
bos@117 238 If, for some reason, you decide that this business of automatically
bos@117 239 propagating changes across copies is not for you, simply use your
bos@117 240 system's normal file copy command (on Unix-like systems, that's
bos@117 241 \command{cp}) to make a copy of a file, then \hgcmd{add} the new copy
bos@117 242 by hand. Before you do so, though, please do reread
bos@117 243 section~\ref{sec:daily:why-copy}, and make an informed decision that
bos@117 244 this behaviour is not appropriate to your specific case.
bos@117 245
bos@117 246 \subsection{Behaviour of the \hgcmd{copy} command}
bos@117 247
bos@118 248 When you use the \hgcmd{copy} command, Mercurial makes a copy of each
bos@118 249 source file as it currently stands in the working directory. This
bos@181 250 means that if you make some modifications to a file, then \hgcmd{copy}
bos@181 251 it without first having committed those changes, the new copy will
bos@181 252 also contain the modifications you have made up until that point. (I
bos@181 253 find this behaviour a little counterintuitive, which is why I mention
bos@181 254 it here.)
bos@118 255
bos@117 256 The \hgcmd{copy} command acts similarly to the Unix \command{cp}
bos@118 257 command (you can use the \hgcmd{cp} alias if you prefer). The last
bos@118 258 argument is the \emph{destination}, and all prior arguments are
bos@118 259 \emph{sources}. If you pass it a single file as the source, and the
bos@118 260 destination does not exist, it creates a new file with that name.
bos@117 261 \interaction{daily.copy.simple}
bos@117 262 If the destination is a directory, Mercurial copies its sources into
bos@117 263 that directory.
bos@117 264 \interaction{daily.copy.dir-dest}
bos@117 265 Copying a directory is recursive, and preserves the directory
bos@117 266 structure of the source.
bos@117 267 \interaction{daily.copy.dir-src}
bos@117 268 If the source and destination are both directories, the source tree is
bos@117 269 recreated in the destination directory.
bos@117 270 \interaction{daily.copy.dir-src-dest}
bos@117 271
bos@118 272 As with the \hgcmd{rename} command, if you copy a file manually and
bos@118 273 then want Mercurial to know that you've copied the file, simply use
bos@236 274 the \hgopt{copy}{--after} option to \hgcmd{copy}.
bos@118 275 \interaction{daily.copy.after}
bos@118 276
bos@117 277 \section{Renaming files}
bos@43 278
bos@118 279 It's rather more common to need to rename a file than to make a copy
bos@118 280 of it. The reason I discussed the \hgcmd{copy} command before talking
bos@118 281 about renaming files is that Mercurial treats a rename in essentially
bos@118 282 the same way as a copy. Therefore, knowing what Mercurial does when
bos@118 283 you copy a file tells you what to expect when you rename a file.
bos@118 284
bos@118 285 When you use the \hgcmd{rename} command, Mercurial makes a copy of
bos@118 286 each source file, then deletes it and marks the file as removed.
bos@118 287 \interaction{daily.rename.rename}
bos@118 288 The \hgcmd{status} command shows the newly copied file as added, and
bos@118 289 the copied-from file as removed.
bos@118 290 \interaction{daily.rename.status}
bos@118 291 As with the results of a \hgcmd{copy}, we must use the
bos@118 292 \hgopt{status}{-C} option to \hgcmd{status} to see that the added file
bos@118 293 is really being tracked by Mercurial as a copy of the original, now
bos@118 294 removed, file.
bos@118 295 \interaction{daily.rename.status-copy}
bos@118 296
bos@118 297 As with \hgcmd{remove} and \hgcmd{copy}, you can tell Mercurial about
bos@118 298 a rename after the fact using the \hgopt{rename}{--after} option. In
bos@118 299 most other respects, the behaviour of the \hgcmd{rename} command, and
bos@118 300 the options it accepts, are similar to the \hgcmd{copy} command.
bos@118 301
bos@118 302 \subsection{Renaming files and merging changes}
bos@118 303
bos@118 304 Since Mercurial's rename is implemented as copy-and-remove, the same
bos@118 305 propagation of changes happens when you merge after a rename as after
bos@118 306 a copy.
bos@118 307
bos@156 308 If I modify a file, and you rename it to a new name, and then we merge
bos@156 309 our respective changes, my modifications to the file under its
bos@156 310 original name will be propagated into the file under its new name.
bos@156 311 (This is something you might expect to ``simply work,'' but not all
bos@156 312 revision control systems actually do this.)
bos@43 313
bos@121 314 Whereas having changes follow a copy is a feature where you can
bos@121 315 perhaps nod and say ``yes, that might be useful,'' it should be clear
bos@121 316 that having them follow a rename is definitely important. Without
bos@121 317 this facility, it would simply be too easy for changes to become
bos@121 318 orphaned when files are renamed.
bos@121 319
bos@156 320 \subsection{Divergent renames and merging}
bos@156 321
bos@156 322 The case of diverging names occurs when two developers start with a
bos@156 323 file---let's call it \filename{foo}---in their respective
bos@156 324 repositories.
bos@156 325
bos@156 326 \interaction{rename.divergent.clone}
bos@156 327 Anne renames the file to \filename{bar}.
bos@156 328 \interaction{rename.divergent.rename.anne}
bos@156 329 Meanwhile, Bob renames it to \filename{quux}.
bos@156 330 \interaction{rename.divergent.rename.bob}
bos@156 331
bos@156 332 I like to think of this as a conflict because each developer has
bos@156 333 expressed different intentions about what the file ought to be named.
bos@156 334
bos@156 335 What do you think should happen when they merge their work?
bos@156 336 Mercurial's actual behaviour is that it always preserves \emph{both}
bos@156 337 names when it merges changesets that contain divergent renames.
bos@156 338 \interaction{rename.divergent.merge}
bos@156 339
bos@273 340 Notice that Mercurial does warn about the divergent renames, but it
bos@273 341 leaves it up to you to do something about the divergence after the merge.
bos@156 342
bos@156 343 \subsection{Convergent renames and merging}
bos@156 344
bos@156 345 Another kind of rename conflict occurs when two people choose to
bos@156 346 rename different \emph{source} files to the same \emph{destination}.
bos@156 347 In this case, Mercurial runs its normal merge machinery, and lets you
bos@156 348 guide it to a suitable resolution.
bos@156 349
bos@156 350 \subsection{Other name-related corner cases}
bos@156 351
bos@156 352 Mercurial has a longstanding bug in which it fails to handle a merge
bos@156 353 where one side has a file with a given name, while another has a
bos@156 354 directory with the same name. This is documented as~\bug{29}.
bos@156 355 \interaction{issue29.go}
bos@121 356
bos@180 357 \section{Recovering from mistakes}
bos@180 358
bos@180 359 Mercurial has some useful commands that will help you to recover from
bos@180 360 some common mistakes.
bos@180 361
bos@180 362 The \hgcmd{revert} command lets you undo changes that you have made to
bos@180 363 your working directory. For example, if you \hgcmd{add} a file by
bos@180 364 accident, just run \hgcmd{revert} with the name of the file you added,
bos@180 365 and while the file won't be touched in any way, it won't be tracked
bos@180 366 for adding by Mercurial any longer, either. You can also use
bos@180 367 \hgcmd{revert} to get rid of erroneous changes to a file.
bos@180 368
bos@180 369 It's useful to remember that the \hgcmd{revert} command is useful for
bos@180 370 changes that you have not yet committed. Once you've committed a
bos@180 371 change, if you decide it was a mistake, you can still do something
bos@180 372 about it, though your options may be more limited.
bos@180 373
bos@180 374 For more information about the \hgcmd{revert} command, and details
bos@180 375 about how to deal with changes you have already committed, see
bos@182 376 chapter~\ref{chap:undo}.
bos@180 377
bos@42 378 %%% Local Variables:
bos@42 379 %%% mode: latex
bos@42 380 %%% TeX-master: "00book"
bos@42 381 %%% End: