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