Mercurial > hgbook
comparison po/zh.po @ 726:8271c8891b0e
Add Chinese translation
author | Dongsheng Song <dongsheng.song@gmail.com> |
---|---|
date | Thu, 12 Mar 2009 15:53:01 +0800 |
parents | |
children | ccda4952e5f3 |
comparison
equal
deleted
inserted
replaced
725:83a687a996b2 | 726:8271c8891b0e |
---|---|
1 # | |
2 # Simplified Chinese translation for hgbook | |
3 # This file is distributed under the same license as the hgbook. | |
4 # | |
5 # Authors: | |
6 # Dongsheng Song <dongsheng.song@gmail.com>, 2009 | |
7 # | |
8 # Update to new pot: | |
9 # msgmerge --update zh.po svnbook.pot | |
10 # | |
11 # Check translation: | |
12 # msgfmt --statistics -c -o zh.mo zh.po | |
13 # | |
14 # Please format your translation before commit: | |
15 # msgcat --sort-by-file --width=80 -o zh_new.po zh.po | |
16 # mv -f zh_new.po zh.po | |
17 # | |
18 # Dictionary: | |
19 # blame 追溯 | |
20 # branch 分支 | |
21 # changes 修改 | |
22 # changeset 修改集 | |
23 # checkout 检出 | |
24 # remove 移除(从版本库删除) | |
25 # delete 删除(只从文件系统删除) | |
26 # patchset 补丁集 | |
27 # pushing to 推到 | |
28 # pulling from 拉自 | |
29 # rename 改名 | |
30 # repository 版本库 | |
31 # revert 恢复 | |
32 # revision 版本 | |
33 # tag 标签 | |
34 # tip 顶点 | |
35 # undo 撤销 | |
36 # unversioned 未版本控制 | |
37 # versioned 受版本控制 | |
38 # working copy 工作副本 | |
39 # ... | |
40 # | |
41 msgid "" | |
42 msgstr "" | |
43 "Project-Id-Version: hgbook 1.2\n" | |
44 "POT-Creation-Date: 2009-03-11 10:07+0800\n" | |
45 "PO-Revision-Date: 2009-03-09 23:32+0800\n" | |
46 "Last-Translator: \n" | |
47 "Language-Team: Simplified Chinese <i18n-zh@googlegroups.com >\n" | |
48 "MIME-Version: 1.0\n" | |
49 "Content-Type: text/plain; charset=UTF-8\n" | |
50 "Content-Transfer-Encoding: 8bit\n" | |
51 "X-Poedit-Language: Chinese\n" | |
52 "X-Poedit-Country: CHINA\n" | |
53 "X-Poedit-SourceCharset: utf-8\n" | |
54 | |
55 #. type: Content of: <book><title> | |
56 #: ../en/00book.xml:41 | |
57 msgid "Mercurial: The Definitive Guide" | |
58 msgstr "Mercurial 权威指南" | |
59 | |
60 #. type: Content of: <book><subtitle> | |
61 #: ../en/00book.xml:46 | |
62 msgid "Compiled from $rev_id$" | |
63 msgstr "编译自 $rev_id$" | |
64 | |
65 #. type: Content of: <book><bookinfo><authorgroup><author><firstname> | |
66 #: ../en/00book.xml:50 | |
67 msgid "Bryan" | |
68 msgstr "" | |
69 | |
70 #. type: Content of: <book><bookinfo><authorgroup><author><surname> | |
71 #: ../en/00book.xml:51 | |
72 msgid "O'Sullivan" | |
73 msgstr "" | |
74 | |
75 #. type: Content of: <book><bookinfo> | |
76 #: ../en/00book.xml:55 | |
77 msgid "" | |
78 "<editor> <firstname>Mike</firstname> <surname>Loukides</surname> </editor> " | |
79 "<copyright> <year>2006</year> <year>2007</year> <year>2008</year> <year>2009</" | |
80 "year> <holder>Bryan O'Sullivan</holder> </copyright>" | |
81 msgstr "" | |
82 | |
83 #. type: Content of: <book><appendix><title> | |
84 #: ../en/appA-cmdref.xml:4 | |
85 msgid "Command reference" | |
86 msgstr "命令参考" | |
87 | |
88 #. type: Content of: <book><appendix><para> | |
89 #: ../en/appA-cmdref.xml:6 | |
90 msgid "" | |
91 "\\cmdref{add}{add files at the next commit} \\optref{add}{I}{include} \\optref" | |
92 "{add}{X}{exclude} \\optref{add}{n}{dry-run}" | |
93 msgstr "" | |
94 | |
95 #. type: Content of: <book><appendix><para> | |
96 #: ../en/appA-cmdref.xml:11 | |
97 msgid "\\cmdref{diff}{print changes in history or working directory}" | |
98 msgstr "" | |
99 | |
100 #. type: Content of: <book><appendix><para> | |
101 #: ../en/appA-cmdref.xml:13 | |
102 msgid "" | |
103 "Show differences between revisions for the specified files or directories, " | |
104 "using the unified diff format. For a description of the unified diff format, " | |
105 "see section <xref linkend=\"sec.mq.patch\"/>." | |
106 msgstr "" | |
107 | |
108 #. type: Content of: <book><appendix><para> | |
109 #: ../en/appA-cmdref.xml:17 | |
110 msgid "" | |
111 "By default, this command does not print diffs for files that Mercurial " | |
112 "considers to contain binary data. To control this behaviour, see the <option " | |
113 "role=\"hg-opt-diff\">-a</option> and <option role=\"hg-opt-diff\">--git</" | |
114 "option> options." | |
115 msgstr "" | |
116 | |
117 #. type: Content of: <book><appendix><sect2><title> | |
118 #: ../en/appA-cmdref.xml:22 | |
119 msgid "Options" | |
120 msgstr "选项" | |
121 | |
122 #. type: Content of: <book><appendix><sect2><para> | |
123 #: ../en/appA-cmdref.xml:24 | |
124 msgid "\\loptref{diff}{nodates}" | |
125 msgstr "" | |
126 | |
127 #. type: Content of: <book><appendix><sect2><para> | |
128 #: ../en/appA-cmdref.xml:26 | |
129 msgid "Omit date and time information when printing diff headers." | |
130 msgstr "" | |
131 | |
132 #. type: Content of: <book><appendix><sect2><para> | |
133 #: ../en/appA-cmdref.xml:28 | |
134 msgid "\\optref{diff}{B}{ignore-blank-lines}" | |
135 msgstr "" | |
136 | |
137 #. type: Content of: <book><appendix><sect2><para> | |
138 #: ../en/appA-cmdref.xml:30 | |
139 msgid "" | |
140 "Do not print changes that only insert or delete blank lines. A line that " | |
141 "contains only whitespace is not considered blank." | |
142 msgstr "" | |
143 | |
144 #. type: Content of: <book><appendix><sect2><para> | |
145 #: ../en/appA-cmdref.xml:34 | |
146 msgid "\\optref{diff}{I}{include}" | |
147 msgstr "" | |
148 | |
149 #. type: Content of: <book><appendix><sect2><para> | |
150 #: ../en/appA-cmdref.xml:37 | |
151 msgid "Include files and directories whose names match the given patterns." | |
152 msgstr "" | |
153 | |
154 #. type: Content of: <book><appendix><sect2><para> | |
155 #: ../en/appA-cmdref.xml:40 | |
156 msgid "\\optref{diff}{X}{exclude}" | |
157 msgstr "" | |
158 | |
159 #. type: Content of: <book><appendix><sect2><para> | |
160 #: ../en/appA-cmdref.xml:43 | |
161 msgid "Exclude files and directories whose names match the given patterns." | |
162 msgstr "" | |
163 | |
164 #. type: Content of: <book><appendix><sect2><para> | |
165 #: ../en/appA-cmdref.xml:46 | |
166 msgid "\\optref{diff}{a}{text}" | |
167 msgstr "" | |
168 | |
169 #. type: Content of: <book><appendix><sect2><para> | |
170 #: ../en/appA-cmdref.xml:49 | |
171 msgid "" | |
172 "If this option is not specified, <command role=\"hg-cmd\">hg diff</command> " | |
173 "will refuse to print diffs for files that it detects as binary. Specifying " | |
174 "<option role=\"hg-opt-diff\">-a</option> forces <command role=\"hg-cmd\">hg " | |
175 "diff</command> to treat all files as text, and generate diffs for all of them." | |
176 msgstr "" | |
177 | |
178 #. type: Content of: <book><appendix><sect2><para> | |
179 #: ../en/appA-cmdref.xml:55 | |
180 msgid "" | |
181 "This option is useful for files that are <quote>mostly text</quote> but have " | |
182 "a few embedded NUL characters. If you use it on files that contain a lot of " | |
183 "binary data, its output will be incomprehensible." | |
184 msgstr "" | |
185 | |
186 #. type: Content of: <book><appendix><sect2><para> | |
187 #: ../en/appA-cmdref.xml:60 | |
188 msgid "\\optref{diff}{b}{ignore-space-change}" | |
189 msgstr "" | |
190 | |
191 #. type: Content of: <book><appendix><sect2><para> | |
192 #: ../en/appA-cmdref.xml:63 | |
193 msgid "" | |
194 "Do not print a line if the only change to that line is in the amount of white " | |
195 "space it contains." | |
196 msgstr "" | |
197 | |
198 #. type: Content of: <book><appendix><sect2><para> | |
199 #: ../en/appA-cmdref.xml:67 | |
200 msgid "\\optref{diff}{g}{git}" | |
201 msgstr "" | |
202 | |
203 #. type: Content of: <book><appendix><sect2><para> | |
204 #: ../en/appA-cmdref.xml:70 | |
205 msgid "" | |
206 "Print <command>git</command>-compatible diffs. XXX reference a format " | |
207 "description." | |
208 msgstr "" | |
209 | |
210 #. type: Content of: <book><appendix><sect2><para> | |
211 #: ../en/appA-cmdref.xml:74 | |
212 msgid "\\optref{diff}{p}{show-function}" | |
213 msgstr "" | |
214 | |
215 #. type: Content of: <book><appendix><sect2><para> | |
216 #: ../en/appA-cmdref.xml:77 | |
217 msgid "" | |
218 "Display the name of the enclosing function in a hunk header, using a simple " | |
219 "heuristic. This functionality is enabled by default, so the <option role=" | |
220 "\"hg-opt-diff\">-p</option> option has no effect unless you change the value " | |
221 "of the <envar role=\"rc-item-diff\">showfunc</envar> config item, as in the " | |
222 "following example." | |
223 msgstr "" | |
224 | |
225 #. type: Content of: <book><appendix><sect2><para> | |
226 #: ../en/appA-cmdref.xml:84 | |
227 msgid "\\optref{diff}{r}{rev}" | |
228 msgstr "" | |
229 | |
230 #. type: Content of: <book><appendix><sect2><para> | |
231 #: ../en/appA-cmdref.xml:87 | |
232 msgid "" | |
233 "Specify one or more revisions to compare. The <command role=\"hg-cmd\">hg " | |
234 "diff</command> command accepts up to two <option role=\"hg-opt-diff\">-r</" | |
235 "option> options to specify the revisions to compare." | |
236 msgstr "" | |
237 | |
238 #. type: Content of: <book><appendix><sect2><orderedlist><listitem><para> | |
239 #: ../en/appA-cmdref.xml:93 | |
240 msgid "" | |
241 "Display the differences between the parent revision of the working directory " | |
242 "and the working directory." | |
243 msgstr "" | |
244 | |
245 #. type: Content of: <book><appendix><sect2><orderedlist><listitem><para> | |
246 #: ../en/appA-cmdref.xml:97 | |
247 msgid "" | |
248 "Display the differences between the specified changeset and the working " | |
249 "directory." | |
250 msgstr "" | |
251 | |
252 #. type: Content of: <book><appendix><sect2><orderedlist><listitem><para> | |
253 #: ../en/appA-cmdref.xml:101 | |
254 msgid "Display the differences between the two specified changesets." | |
255 msgstr "" | |
256 | |
257 #. type: Content of: <book><appendix><sect2><para> | |
258 #: ../en/appA-cmdref.xml:105 | |
259 msgid "" | |
260 "You can specify two revisions using either two <option role=\"hg-opt-diff\">-" | |
261 "r</option> options or revision range notation. For example, the two revision " | |
262 "specifications below are equivalent." | |
263 msgstr "" | |
264 | |
265 #. type: Content of: <book><appendix><sect2><para> | |
266 #: ../en/appA-cmdref.xml:112 | |
267 msgid "" | |
268 "When you provide two revisions, Mercurial treats the order of those revisions " | |
269 "as significant. Thus, <command role=\"hg-cmd\">hg diff -r10:20</command> " | |
270 "will produce a diff that will transform files from their contents as of " | |
271 "revision 10 to their contents as of revision 20, while <command role=\"hg-cmd" | |
272 "\">hg diff -r20:10</command> means the opposite: the diff that will transform " | |
273 "files from their revision 20 contents to their revision 10 contents. You " | |
274 "cannot reverse the ordering in this way if you are diffing against the " | |
275 "working directory." | |
276 msgstr "" | |
277 | |
278 #. type: Content of: <book><appendix><sect2><para> | |
279 #: ../en/appA-cmdref.xml:122 | |
280 msgid "\\optref{diff}{w}{ignore-all-space}" | |
281 msgstr "" | |
282 | |
283 #. type: Content of: <book><appendix><sect2><para> | |
284 #: ../en/appA-cmdref.xml:125 | |
285 msgid "\\cmdref{version}{print version and copyright information}" | |
286 msgstr "" | |
287 | |
288 #. type: Content of: <book><appendix><sect2><para> | |
289 #: ../en/appA-cmdref.xml:128 | |
290 msgid "" | |
291 "This command displays the version of Mercurial you are running, and its " | |
292 "copyright license. There are four kinds of version string that you may see." | |
293 msgstr "" | |
294 | |
295 #. type: Content of: <book><appendix><sect2><itemizedlist><listitem><para> | |
296 #: ../en/appA-cmdref.xml:133 | |
297 msgid "" | |
298 "The string <quote><literal>unknown</literal></quote>. This version of " | |
299 "Mercurial was not built in a Mercurial repository, and cannot determine its " | |
300 "own version." | |
301 msgstr "" | |
302 | |
303 #. type: Content of: <book><appendix><sect2><itemizedlist><listitem><para> | |
304 #: ../en/appA-cmdref.xml:138 | |
305 msgid "" | |
306 "A short numeric string, such as <quote><literal>1.1</literal></quote>. This " | |
307 "is a build of a revision of Mercurial that was identified by a specific tag " | |
308 "in the repository where it was built. (This doesn't necessarily mean that " | |
309 "you're running an official release; someone else could have added that tag to " | |
310 "any revision in the repository where they built Mercurial.)" | |
311 msgstr "" | |
312 | |
313 #. type: Content of: <book><appendix><sect2><itemizedlist><listitem><para> | |
314 #: ../en/appA-cmdref.xml:146 | |
315 msgid "" | |
316 "A hexadecimal string, such as <quote><literal>875489e31abe</literal></" | |
317 "quote>. This is a build of the given revision of Mercurial." | |
318 msgstr "" | |
319 | |
320 #. type: Content of: <book><appendix><sect2><itemizedlist><listitem><para> | |
321 #: ../en/appA-cmdref.xml:150 | |
322 msgid "" | |
323 "A hexadecimal string followed by a date, such as <quote><literal>875489e31abe" | |
324 "+20070205</literal></quote>. This is a build of the given revision of " | |
325 "Mercurial, where the build repository contained some local changes that had " | |
326 "not been committed." | |
327 msgstr "" | |
328 | |
329 #. type: Content of: <book><appendix><sect2><title> | |
330 #: ../en/appA-cmdref.xml:159 | |
331 msgid "Tips and tricks" | |
332 msgstr "" | |
333 | |
334 #. type: Content of: <book><appendix><sect2><sect3><title> | |
335 #: ../en/appA-cmdref.xml:162 | |
336 msgid "" | |
337 "Why do the results of <command role=\"hg-cmd\">hg diff</command> and <command " | |
338 "role=\"hg-cmd\">hg status</command> differ?" | |
339 msgstr "" | |
340 "为什么 <command role=\"hg-cmd\">hg diff</command> 与 <command role=\"hg-cmd" | |
341 "\">hg status</command> 的结果不同 ?" | |
342 | |
343 #. type: Content of: <book><appendix><sect2><sect3><para> | |
344 #: ../en/appA-cmdref.xml:164 | |
345 msgid "" | |
346 "When you run the <command role=\"hg-cmd\">hg status</command> command, you'll " | |
347 "see a list of files that Mercurial will record changes for the next time you " | |
348 "perform a commit. If you run the <command role=\"hg-cmd\">hg diff</command> " | |
349 "command, you may notice that it prints diffs for only a <emphasis>subset</" | |
350 "emphasis> of the files that <command role=\"hg-cmd\">hg status</command> " | |
351 "listed. There are two possible reasons for this." | |
352 msgstr "" | |
353 | |
354 #. type: Content of: <book><appendix><sect2><sect3><para> | |
355 #: ../en/appA-cmdref.xml:171 | |
356 msgid "" | |
357 "The first is that <command role=\"hg-cmd\">hg status</command> prints some " | |
358 "kinds of modifications that <command role=\"hg-cmd\">hg diff</command> " | |
359 "doesn't normally display. The <command role=\"hg-cmd\">hg diff</command> " | |
360 "command normally outputs unified diffs, which don't have the ability to " | |
361 "represent some changes that Mercurial can track. Most notably, traditional " | |
362 "diffs can't represent a change in whether or not a file is executable, but " | |
363 "Mercurial records this information." | |
364 msgstr "" | |
365 | |
366 #. type: Content of: <book><appendix><sect2><sect3><para> | |
367 #: ../en/appA-cmdref.xml:179 | |
368 msgid "" | |
369 "If you use the <option role=\"hg-opt-diff\">--git</option> option to <command " | |
370 "role=\"hg-cmd\">hg diff</command>, it will display <command>git</command>-" | |
371 "compatible diffs that <emphasis>can</emphasis> display this extra information." | |
372 msgstr "" | |
373 | |
374 #. type: Content of: <book><appendix><sect2><sect3><para> | |
375 #: ../en/appA-cmdref.xml:184 | |
376 msgid "" | |
377 "The second possible reason that <command role=\"hg-cmd\">hg diff</command> " | |
378 "might be printing diffs for a subset of the files displayed by <command role=" | |
379 "\"hg-cmd\">hg status</command> is that if you invoke it without any " | |
380 "arguments, <command role=\"hg-cmd\">hg diff</command> prints diffs against " | |
381 "the first parent of the working directory. If you have run <command role=" | |
382 "\"hg-cmd\">hg merge</command> to merge two changesets, but you haven't yet " | |
383 "committed the results of the merge, your working directory has two parents " | |
384 "(use <command role=\"hg-cmd\">hg parents</command> to see them). While " | |
385 "<command role=\"hg-cmd\">hg status</command> prints modifications relative to " | |
386 "<emphasis>both</emphasis> parents after an uncommitted merge, <command role=" | |
387 "\"hg-cmd\">hg diff</command> still operates relative only to the first " | |
388 "parent. You can get it to print diffs relative to the second parent by " | |
389 "specifying that parent with the <option role=\"hg-opt-diff\">-r</option> " | |
390 "option. There is no way to print diffs relative to both parents." | |
391 msgstr "" | |
392 | |
393 #. type: Content of: <book><appendix><sect2><sect3><title> | |
394 #: ../en/appA-cmdref.xml:200 | |
395 msgid "Generating safe binary diffs" | |
396 msgstr "生成安全的二进制差异" | |
397 | |
398 #. type: Content of: <book><appendix><sect2><sect3><para> | |
399 #: ../en/appA-cmdref.xml:202 | |
400 msgid "" | |
401 "If you use the <option role=\"hg-opt-diff\">-a</option> option to force " | |
402 "Mercurial to print diffs of files that are either <quote>mostly text</quote> " | |
403 "or contain lots of binary data, those diffs cannot subsequently be applied by " | |
404 "either Mercurial's <command role=\"hg-cmd\">hg import</command> command or " | |
405 "the system's <command>patch</command> command." | |
406 msgstr "" | |
407 | |
408 #. type: Content of: <book><appendix><sect2><sect3><para> | |
409 #: ../en/appA-cmdref.xml:209 | |
410 msgid "" | |
411 "If you want to generate a diff of a binary file that is safe to use as input " | |
412 "for <command role=\"hg-cmd\">hg import</command>, use the <command role=\"hg-" | |
413 "cmd\">hg diff</command>{--git} option when you generate the patch. The " | |
414 "system <command>patch</command> command cannot handle binary patches at all." | |
415 msgstr "" | |
416 | |
417 #. type: Content of: <book><appendix><title> | |
418 #: ../en/appB-mq-ref.xml:5 | |
419 msgid "Mercurial Queues reference" | |
420 msgstr "Mercurial 队列参考" | |
421 | |
422 #. type: Content of: <book><appendix><sect1><title> | |
423 #: ../en/appB-mq-ref.xml:8 | |
424 msgid "MQ command reference" | |
425 msgstr "MQ 命令参考" | |
426 | |
427 #. type: Content of: <book><appendix><sect1><para> | |
428 #: ../en/appB-mq-ref.xml:10 | |
429 msgid "" | |
430 "For an overview of the commands provided by MQ, use the command <command role=" | |
431 "\"hg-cmd\">hg help mq</command>." | |
432 msgstr "" | |
433 | |
434 #. type: Content of: <book><appendix><sect1><sect2><title> | |
435 #: ../en/appB-mq-ref.xml:14 | |
436 msgid "" | |
437 "<command role=\"hg-ext-mq\">qapplied</command>&emdash;print applied patches" | |
438 msgstr "<command role=\"hg-ext-mq\">qapplied</command>&emdash;显示已应用的补丁" | |
439 | |
440 #. type: Content of: <book><appendix><sect1><sect2><para> | |
441 #: ../en/appB-mq-ref.xml:17 | |
442 msgid "" | |
443 "The <command role=\"hg-ext-mq\">qapplied</command> command prints the current " | |
444 "stack of applied patches. Patches are printed in oldest-to-newest order, so " | |
445 "the last patch in the list is the <quote>top</quote> patch." | |
446 msgstr "" | |
447 | |
448 #. type: Content of: <book><appendix><sect1><sect2><title> | |
449 #: ../en/appB-mq-ref.xml:24 | |
450 msgid "" | |
451 "<command role=\"hg-ext-mq\">qcommit</command>&emdash;commit changes in the " | |
452 "queue repository" | |
453 msgstr "<command role=\"hg-ext-mq\">qcommit</command>&emdash;提交队列中的修改" | |
454 | |
455 #. type: Content of: <book><appendix><sect1><sect2><para> | |
456 #: ../en/appB-mq-ref.xml:27 | |
457 msgid "" | |
458 "The <command role=\"hg-ext-mq\">qcommit</command> command commits any " | |
459 "outstanding changes in the <filename role=\"special\" class=\"directory\">.hg/" | |
460 "patches</filename> repository. This command only works if the <filename role=" | |
461 "\"special\" class=\"directory\">.hg/patches</filename> directory is a " | |
462 "repository, i.e. you created the directory using <command role=\"hg-cmd\">hg " | |
463 "qinit <option role=\"hg-ext-mq-cmd-qinit-opt\">-c</option></command> or ran " | |
464 "<command role=\"hg-cmd\">hg init</command> in the directory after running " | |
465 "<command role=\"hg-ext-mq\">qinit</command>." | |
466 msgstr "" | |
467 | |
468 #. type: Content of: <book><appendix><sect1><sect2><para> | |
469 #: ../en/appB-mq-ref.xml:39 | |
470 msgid "" | |
471 "This command is shorthand for <command role=\"hg-cmd\">hg commit --cwd .hg/" | |
472 "patches</command>." | |
473 msgstr "" | |
474 | |
475 #. type: Content of: <book><appendix><sect1><sect2><para> | |
476 #: ../en/appB-mq-ref.xml:42 | |
477 msgid "" | |
478 "\\subsection{<command role=\"hg-ext-mq\">qdelete</command>&emdash;delete a " | |
479 "patch from the <filename role=\"special\">series</filename> file}" | |
480 msgstr "" | |
481 | |
482 #. type: Content of: <book><appendix><sect1><sect2><para> | |
483 #: ../en/appB-mq-ref.xml:47 | |
484 msgid "" | |
485 "The <command role=\"hg-ext-mq\">qdelete</command> command removes the entry " | |
486 "for a patch from the <filename role=\"special\">series</filename> file in the " | |
487 "<filename role=\"special\" class=\"directory\">.hg/patches</filename> " | |
488 "directory. It does not pop the patch if the patch is already applied. By " | |
489 "default, it does not delete the patch file; use the <option role=\"hg-ext-mq-" | |
490 "cmd-qdel-opt\">-f</option> option to do that." | |
491 msgstr "" | |
492 | |
493 #. type: Content of: <book><appendix><sect1><sect2><para> | |
494 #: ../en/appB-mq-ref.xml:56 ../en/appB-mq-ref.xml:98 ../en/appB-mq-ref.xml:156 | |
495 #: ../en/appB-mq-ref.xml:196 ../en/appB-mq-ref.xml:263 | |
496 #: ../en/appB-mq-ref.xml:334 ../en/appB-mq-ref.xml:403 | |
497 #: ../en/appB-mq-ref.xml:496 | |
498 msgid "Options:" | |
499 msgstr "" | |
500 | |
501 #. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para> | |
502 #: ../en/appB-mq-ref.xml:58 | |
503 msgid "" | |
504 "<option role=\"hg-ext-mq-cmd-qdel-opt\">-f</option>: Delete the patch file." | |
505 msgstr "" | |
506 | |
507 #. type: Content of: <book><appendix><sect1><sect2><title> | |
508 #: ../en/appB-mq-ref.xml:65 | |
509 msgid "" | |
510 "<command role=\"hg-ext-mq\">qdiff</command>&emdash;print a diff of the " | |
511 "topmost applied patch" | |
512 msgstr "" | |
513 "<command role=\"hg-ext-mq\">qdiff</command>&emdash;显示最新应用补丁的差异" | |
514 | |
515 #. type: Content of: <book><appendix><sect1><sect2><para> | |
516 #: ../en/appB-mq-ref.xml:68 | |
517 msgid "" | |
518 "The <command role=\"hg-ext-mq\">qdiff</command> command prints a diff of the " | |
519 "topmost applied patch. It is equivalent to <command role=\"hg-cmd\">hg diff -" | |
520 "r-2:-1</command>." | |
521 msgstr "" | |
522 | |
523 #. type: Content of: <book><appendix><sect1><sect2><title> | |
524 #: ../en/appB-mq-ref.xml:74 | |
525 msgid "" | |
526 "<command role=\"hg-ext-mq\">qfold</command>&emdash;merge (<quote>fold</" | |
527 "quote>) several patches into one" | |
528 msgstr "" | |
529 "<command role=\"hg-ext-mq\">qfold</command>&emdash;将多个补丁合并(<quote>折叠" | |
530 "</quote>)成一个" | |
531 | |
532 #. type: Content of: <book><appendix><sect1><sect2><para> | |
533 #: ../en/appB-mq-ref.xml:77 | |
534 msgid "" | |
535 "The <command role=\"hg-ext-mq\">qfold</command> command merges multiple " | |
536 "patches into the topmost applied patch, so that the topmost applied patch " | |
537 "makes the union of all of the changes in the patches in question." | |
538 msgstr "" | |
539 | |
540 #. type: Content of: <book><appendix><sect1><sect2><para> | |
541 #: ../en/appB-mq-ref.xml:82 | |
542 msgid "" | |
543 "The patches to fold must not be applied; <command role=\"hg-ext-mq\">qfold</" | |
544 "command> will exit with an error if any is. The order in which patches are " | |
545 "folded is significant; <command role=\"hg-cmd\">hg qfold a b</command> means " | |
546 "<quote>apply the current topmost patch, followed by <literal>a</literal>, " | |
547 "followed by <literal>b</literal></quote>." | |
548 msgstr "" | |
549 | |
550 #. type: Content of: <book><appendix><sect1><sect2><para> | |
551 #: ../en/appB-mq-ref.xml:90 | |
552 msgid "" | |
553 "The comments from the folded patches are appended to the comments of the " | |
554 "destination patch, with each block of comments separated by three asterisk " | |
555 "(<quote><literal>*</literal></quote>) characters. Use the <option role=\"hg-" | |
556 "ext-mq-cmd-qfold-opt\">-e</option> option to edit the commit message for the " | |
557 "combined patch/changeset after the folding has completed." | |
558 msgstr "" | |
559 | |
560 #. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para> | |
561 #: ../en/appB-mq-ref.xml:100 | |
562 msgid "" | |
563 "<option role=\"hg-ext-mq-cmd-qfold-opt\">-e</option>: Edit the commit message " | |
564 "and patch description for the newly folded patch." | |
565 msgstr "" | |
566 | |
567 #. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para> | |
568 #: ../en/appB-mq-ref.xml:105 | |
569 msgid "" | |
570 "<option role=\"hg-ext-mq-cmd-qfold-opt\">-l</option>: Use the contents of the " | |
571 "given file as the new commit message and patch description for the folded " | |
572 "patch." | |
573 msgstr "" | |
574 | |
575 #. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para> | |
576 #: ../en/appB-mq-ref.xml:110 | |
577 msgid "" | |
578 "<option role=\"hg-ext-mq-cmd-qfold-opt\">-m</option>: Use the given text as " | |
579 "the new commit message and patch description for the folded patch." | |
580 msgstr "" | |
581 | |
582 #. type: Content of: <book><appendix><sect1><sect2><title> | |
583 #: ../en/appB-mq-ref.xml:118 | |
584 msgid "" | |
585 "<command role=\"hg-ext-mq\">qheader</command>&emdash;display the header/" | |
586 "description of a patch" | |
587 msgstr "<command role=\"hg-ext-mq\">qheader</command>&emdash;显示补丁头部描述" | |
588 | |
589 #. type: Content of: <book><appendix><sect1><sect2><para> | |
590 #: ../en/appB-mq-ref.xml:122 | |
591 msgid "" | |
592 "The <command role=\"hg-ext-mq\">qheader</command> command prints the header, " | |
593 "or description, of a patch. By default, it prints the header of the topmost " | |
594 "applied patch. Given an argument, it prints the header of the named patch." | |
595 msgstr "" | |
596 | |
597 #. type: Content of: <book><appendix><sect1><sect2><title> | |
598 #: ../en/appB-mq-ref.xml:129 | |
599 msgid "" | |
600 "<command role=\"hg-ext-mq\">qimport</command>&emdash;import a third-party " | |
601 "patch into the queue" | |
602 msgstr "" | |
603 "<command role=\"hg-ext-mq\">qimport</command>&emdash;将第三方补丁导入队列" | |
604 | |
605 #. type: Content of: <book><appendix><sect1><sect2><para> | |
606 #: ../en/appB-mq-ref.xml:132 | |
607 msgid "" | |
608 "The <command role=\"hg-ext-mq\">qimport</command> command adds an entry for " | |
609 "an external patch to the <filename role=\"special\">series</filename> file, " | |
610 "and copies the patch into the <filename role=\"special\" class=\"directory\">." | |
611 "hg/patches</filename> directory. It adds the entry immediately after the " | |
612 "topmost applied patch, but does not push the patch." | |
613 msgstr "" | |
614 | |
615 #. type: Content of: <book><appendix><sect1><sect2><para> | |
616 #: ../en/appB-mq-ref.xml:140 | |
617 msgid "" | |
618 "If the <filename role=\"special\" class=\"directory\">.hg/patches</filename> " | |
619 "directory is a repository, <command role=\"hg-ext-mq\">qimport</command> " | |
620 "automatically does an <command role=\"hg-cmd\">hg add</command> of the " | |
621 "imported patch." | |
622 msgstr "" | |
623 | |
624 #. type: Content of: <book><appendix><sect1><sect2><title> | |
625 #: ../en/appB-mq-ref.xml:148 | |
626 msgid "" | |
627 "<command role=\"hg-ext-mq\">qinit</command>&emdash;prepare a repository to " | |
628 "work with MQ" | |
629 msgstr "<command role=\"hg-ext-mq\">qinit</command>&emdash;为使用 MQ 配置版本库" | |
630 | |
631 #. type: Content of: <book><appendix><sect1><sect2><para> | |
632 #: ../en/appB-mq-ref.xml:151 | |
633 msgid "" | |
634 "The <command role=\"hg-ext-mq\">qinit</command> command prepares a repository " | |
635 "to work with MQ. It creates a directory called <filename role=\"special\" " | |
636 "class=\"directory\">.hg/patches</filename>." | |
637 msgstr "" | |
638 | |
639 #. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para> | |
640 #: ../en/appB-mq-ref.xml:158 | |
641 msgid "" | |
642 "<option role=\"hg-ext-mq-cmd-qinit-opt\">-c</option>: Create <filename role=" | |
643 "\"special\" class=\"directory\">.hg/patches</filename> as a repository in its " | |
644 "own right. Also creates a <filename role=\"special\">.hgignore</filename> " | |
645 "file that will ignore the <filename role=\"special\">status</filename> file." | |
646 msgstr "" | |
647 | |
648 #. type: Content of: <book><appendix><sect1><sect2><para> | |
649 #: ../en/appB-mq-ref.xml:168 | |
650 msgid "" | |
651 "When the <filename role=\"special\" class=\"directory\">.hg/patches</" | |
652 "filename> directory is a repository, the <command role=\"hg-ext-mq\">qimport</" | |
653 "command> and <command role=\"hg-ext-mq\">qnew</command> commands " | |
654 "automatically <command role=\"hg-cmd\">hg add</command> new patches." | |
655 msgstr "" | |
656 | |
657 #. type: Content of: <book><appendix><sect1><sect2><title> | |
658 #: ../en/appB-mq-ref.xml:177 | |
659 msgid "<command role=\"hg-ext-mq\">qnew</command>&emdash;create a new patch" | |
660 msgstr "<command role=\"hg-ext-mq\">qnew</command>&emdash;创建新补丁" | |
661 | |
662 #. type: Content of: <book><appendix><sect1><sect2><para> | |
663 #: ../en/appB-mq-ref.xml:180 | |
664 msgid "" | |
665 "The <command role=\"hg-ext-mq\">qnew</command> command creates a new patch. " | |
666 "It takes one mandatory argument, the name to use for the patch file. The " | |
667 "newly created patch is created empty by default. It is added to the " | |
668 "<filename role=\"special\">series</filename> file after the current topmost " | |
669 "applied patch, and is immediately pushed on top of that patch." | |
670 msgstr "" | |
671 | |
672 #. type: Content of: <book><appendix><sect1><sect2><para> | |
673 #: ../en/appB-mq-ref.xml:188 | |
674 msgid "" | |
675 "If <command role=\"hg-ext-mq\">qnew</command> finds modified files in the " | |
676 "working directory, it will refuse to create a new patch unless the <option " | |
677 "role=\"hg-ext-mq-cmd-qnew-opt\">-f</option> option is used (see below). This " | |
678 "behaviour allows you to <command role=\"hg-ext-mq\">qrefresh</command> your " | |
679 "topmost applied patch before you apply a new patch on top of it." | |
680 msgstr "" | |
681 | |
682 #. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para> | |
683 #: ../en/appB-mq-ref.xml:198 | |
684 msgid "" | |
685 "<option role=\"hg-ext-mq-cmd-qnew-opt\">-f</option>: Create a new patch if " | |
686 "the contents of the working directory are modified. Any outstanding " | |
687 "modifications are added to the newly created patch, so after this command " | |
688 "completes, the working directory will no longer be modified." | |
689 msgstr "" | |
690 | |
691 #. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para> | |
692 #: ../en/appB-mq-ref.xml:205 | |
693 msgid "" | |
694 "<option role=\"hg-ext-mq-cmd-qnew-opt\">-m</option>: Use the given text as " | |
695 "the commit message. This text will be stored at the beginning of the patch " | |
696 "file, before the patch data." | |
697 msgstr "" | |
698 | |
699 #. type: Content of: <book><appendix><sect1><sect2><title> | |
700 #: ../en/appB-mq-ref.xml:214 | |
701 msgid "" | |
702 "<command role=\"hg-ext-mq\">qnext</command>&emdash;print the name of the next " | |
703 "patch" | |
704 msgstr "<command role=\"hg-ext-mq\">qnext</command>&emdash;显示下个补丁的名称" | |
705 | |
706 #. type: Content of: <book><appendix><sect1><sect2><para> | |
707 #: ../en/appB-mq-ref.xml:217 | |
708 msgid "" | |
709 "The <command role=\"hg-ext-mq\">qnext</command> command prints the name name " | |
710 "of the next patch in the <filename role=\"special\">series</filename> file " | |
711 "after the topmost applied patch. This patch will become the topmost applied " | |
712 "patch if you run <command role=\"hg-ext-mq\">qpush</command>." | |
713 msgstr "" | |
714 | |
715 #. type: Content of: <book><appendix><sect1><sect2><title> | |
716 #: ../en/appB-mq-ref.xml:226 | |
717 msgid "" | |
718 "<command role=\"hg-ext-mq\">qpop</command>&emdash;pop patches off the stack" | |
719 msgstr "<command role=\"hg-ext-mq\">qpop</command>&emdash;删除堆栈顶部的补丁" | |
720 | |
721 #. type: Content of: <book><appendix><sect1><sect2><para> | |
722 #: ../en/appB-mq-ref.xml:229 | |
723 msgid "" | |
724 "The <command role=\"hg-ext-mq\">qpop</command> command removes applied " | |
725 "patches from the top of the stack of applied patches. By default, it removes " | |
726 "only one patch." | |
727 msgstr "" | |
728 | |
729 #. type: Content of: <book><appendix><sect1><sect2><para> | |
730 #: ../en/appB-mq-ref.xml:233 | |
731 msgid "" | |
732 "This command removes the changesets that represent the popped patches from " | |
733 "the repository, and updates the working directory to undo the effects of the " | |
734 "patches." | |
735 msgstr "" | |
736 | |
737 #. type: Content of: <book><appendix><sect1><sect2><para> | |
738 #: ../en/appB-mq-ref.xml:237 | |
739 msgid "" | |
740 "This command takes an optional argument, which it uses as the name or index " | |
741 "of the patch to pop to. If given a name, it will pop patches until the named " | |
742 "patch is the topmost applied patch. If given a number, <command role=\"hg-" | |
743 "ext-mq\">qpop</command> treats the number as an index into the entries in the " | |
744 "series file, counting from zero (empty lines and lines containing only " | |
745 "comments do not count). It pops patches until the patch identified by the " | |
746 "given index is the topmost applied patch." | |
747 msgstr "" | |
748 | |
749 #. type: Content of: <book><appendix><sect1><sect2><para> | |
750 #: ../en/appB-mq-ref.xml:247 | |
751 msgid "" | |
752 "The <command role=\"hg-ext-mq\">qpop</command> command does not read or write " | |
753 "patches or the <filename role=\"special\">series</filename> file. It is thus " | |
754 "safe to <command role=\"hg-ext-mq\">qpop</command> a patch that you have " | |
755 "removed from the <filename role=\"special\">series</filename> file, or a " | |
756 "patch that you have renamed or deleted entirely. In the latter two cases, " | |
757 "use the name of the patch as it was when you applied it." | |
758 msgstr "" | |
759 | |
760 #. type: Content of: <book><appendix><sect1><sect2><para> | |
761 #: ../en/appB-mq-ref.xml:256 | |
762 msgid "" | |
763 "By default, the <command role=\"hg-ext-mq\">qpop</command> command will not " | |
764 "pop any patches if the working directory has been modified. You can override " | |
765 "this behaviour using the <option role=\"hg-ext-mq-cmd-qpop-opt\">-f</option> " | |
766 "option, which reverts all modifications in the working directory." | |
767 msgstr "" | |
768 | |
769 #. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para> | |
770 #: ../en/appB-mq-ref.xml:265 | |
771 msgid "" | |
772 "<option role=\"hg-ext-mq-cmd-qpop-opt\">-a</option>: Pop all applied " | |
773 "patches. This returns the repository to its state before you applied any " | |
774 "patches." | |
775 msgstr "" | |
776 | |
777 #. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para> | |
778 #: ../en/appB-mq-ref.xml:270 | |
779 msgid "" | |
780 "<option role=\"hg-ext-mq-cmd-qpop-opt\">-f</option>: Forcibly revert any " | |
781 "modifications to the working directory when popping." | |
782 msgstr "" | |
783 | |
784 #. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para> | |
785 #: ../en/appB-mq-ref.xml:275 | |
786 msgid "" | |
787 "<option role=\"hg-ext-mq-cmd-qpop-opt\">-n</option>: Pop a patch from the " | |
788 "named queue." | |
789 msgstr "" | |
790 | |
791 #. type: Content of: <book><appendix><sect1><sect2><para> | |
792 #: ../en/appB-mq-ref.xml:280 | |
793 msgid "" | |
794 "The <command role=\"hg-ext-mq\">qpop</command> command removes one line from " | |
795 "the end of the <filename role=\"special\">status</filename> file for each " | |
796 "patch that it pops." | |
797 msgstr "" | |
798 | |
799 #. type: Content of: <book><appendix><sect1><sect2><title> | |
800 #: ../en/appB-mq-ref.xml:287 | |
801 msgid "" | |
802 "<command role=\"hg-ext-mq\">qprev</command>&emdash;print the name of the " | |
803 "previous patch" | |
804 msgstr "<command role=\"hg-ext-mq\">qprev</command>&emdash;显示上个补丁的名称" | |
805 | |
806 #. type: Content of: <book><appendix><sect1><sect2><para> | |
807 #: ../en/appB-mq-ref.xml:290 | |
808 msgid "" | |
809 "The <command role=\"hg-ext-mq\">qprev</command> command prints the name of " | |
810 "the patch in the <filename role=\"special\">series</filename> file that comes " | |
811 "before the topmost applied patch. This will become the topmost applied patch " | |
812 "if you run <command role=\"hg-ext-mq\">qpop</command>." | |
813 msgstr "" | |
814 | |
815 #. type: Content of: <book><appendix><sect1><sect2><title> | |
816 #: ../en/appB-mq-ref.xml:299 | |
817 msgid "" | |
818 "<command role=\"hg-ext-mq\">qpush</command>&emdash;push patches onto the stack" | |
819 msgstr "<command role=\"hg-ext-mq\">qpush</command>&emdash;增加补丁到堆栈" | |
820 | |
821 #. type: Content of: <book><appendix><sect1><sect2><para> | |
822 #: ../en/appB-mq-ref.xml:302 | |
823 msgid "" | |
824 "The <command role=\"hg-ext-mq\">qpush</command> command adds patches onto the " | |
825 "applied stack. By default, it adds only one patch." | |
826 msgstr "" | |
827 | |
828 #. type: Content of: <book><appendix><sect1><sect2><para> | |
829 #: ../en/appB-mq-ref.xml:306 | |
830 msgid "" | |
831 "This command creates a new changeset to represent each applied patch, and " | |
832 "updates the working directory to apply the effects of the patches." | |
833 msgstr "" | |
834 | |
835 #. type: Content of: <book><appendix><sect1><sect2><para> | |
836 #: ../en/appB-mq-ref.xml:310 | |
837 msgid "The default data used when creating a changeset are as follows:" | |
838 msgstr "" | |
839 | |
840 #. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para> | |
841 #: ../en/appB-mq-ref.xml:313 | |
842 msgid "" | |
843 "The commit date and time zone are the current date and time zone. Because " | |
844 "these data are used to compute the identity of a changeset, this means that " | |
845 "if you <command role=\"hg-ext-mq\">qpop</command> a patch and <command role=" | |
846 "\"hg-ext-mq\">qpush</command> it again, the changeset that you push will have " | |
847 "a different identity than the changeset you popped." | |
848 msgstr "" | |
849 | |
850 #. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para> | |
851 #: ../en/appB-mq-ref.xml:321 | |
852 msgid "" | |
853 "The author is the same as the default used by the <command role=\"hg-cmd\">hg " | |
854 "commit</command> command." | |
855 msgstr "" | |
856 | |
857 #. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para> | |
858 #: ../en/appB-mq-ref.xml:325 | |
859 msgid "" | |
860 "The commit message is any text from the patch file that comes before the " | |
861 "first diff header. If there is no such text, a default commit message is " | |
862 "used that identifies the name of the patch." | |
863 msgstr "" | |
864 | |
865 #. type: Content of: <book><appendix><sect1><sect2><para> | |
866 #: ../en/appB-mq-ref.xml:330 | |
867 msgid "" | |
868 "If a patch contains a Mercurial patch header (XXX add link), the information " | |
869 "in the patch header overrides these defaults." | |
870 msgstr "" | |
871 | |
872 #. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para> | |
873 #: ../en/appB-mq-ref.xml:336 | |
874 msgid "" | |
875 "<option role=\"hg-ext-mq-cmd-qpush-opt\">-a</option>: Push all unapplied " | |
876 "patches from the <filename role=\"special\">series</filename> file until " | |
877 "there are none left to push." | |
878 msgstr "" | |
879 | |
880 #. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para> | |
881 #: ../en/appB-mq-ref.xml:342 | |
882 msgid "" | |
883 "<option role=\"hg-ext-mq-cmd-qpush-opt\">-l</option>: Add the name of the " | |
884 "patch to the end of the commit message." | |
885 msgstr "" | |
886 | |
887 #. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para> | |
888 #: ../en/appB-mq-ref.xml:346 | |
889 msgid "" | |
890 "<option role=\"hg-ext-mq-cmd-qpush-opt\">-m</option>: If a patch fails to " | |
891 "apply cleanly, use the entry for the patch in another saved queue to compute " | |
892 "the parameters for a three-way merge, and perform a three-way merge using the " | |
893 "normal Mercurial merge machinery. Use the resolution of the merge as the new " | |
894 "patch content." | |
895 msgstr "" | |
896 | |
897 #. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para> | |
898 #: ../en/appB-mq-ref.xml:354 | |
899 msgid "" | |
900 "<option role=\"hg-ext-mq-cmd-qpush-opt\">-n</option>: Use the named queue if " | |
901 "merging while pushing." | |
902 msgstr "" | |
903 | |
904 #. type: Content of: <book><appendix><sect1><sect2><para> | |
905 #: ../en/appB-mq-ref.xml:359 | |
906 msgid "" | |
907 "The <command role=\"hg-ext-mq\">qpush</command> command reads, but does not " | |
908 "modify, the <filename role=\"special\">series</filename> file. It appends " | |
909 "one line to the <command role=\"hg-cmd\">hg status</command> file for each " | |
910 "patch that it pushes." | |
911 msgstr "" | |
912 | |
913 #. type: Content of: <book><appendix><sect1><sect2><title> | |
914 #: ../en/appB-mq-ref.xml:367 | |
915 msgid "" | |
916 "<command role=\"hg-ext-mq\">qrefresh</command>&emdash;update the topmost " | |
917 "applied patch" | |
918 msgstr "<command role=\"hg-ext-mq\">qrefresh</command>&emdash;更新最新的补丁" | |
919 | |
920 #. type: Content of: <book><appendix><sect1><sect2><para> | |
921 #: ../en/appB-mq-ref.xml:371 | |
922 msgid "" | |
923 "The <command role=\"hg-ext-mq\">qrefresh</command> command updates the " | |
924 "topmost applied patch. It modifies the patch, removes the old changeset that " | |
925 "represented the patch, and creates a new changeset to represent the modified " | |
926 "patch." | |
927 msgstr "" | |
928 | |
929 #. type: Content of: <book><appendix><sect1><sect2><para> | |
930 #: ../en/appB-mq-ref.xml:377 | |
931 msgid "" | |
932 "The <command role=\"hg-ext-mq\">qrefresh</command> command looks for the " | |
933 "following modifications:" | |
934 msgstr "" | |
935 | |
936 #. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para> | |
937 #: ../en/appB-mq-ref.xml:380 | |
938 msgid "" | |
939 "Changes to the commit message, i.e. the text before the first diff header in " | |
940 "the patch file, are reflected in the new changeset that represents the patch." | |
941 msgstr "" | |
942 | |
943 #. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para> | |
944 #: ../en/appB-mq-ref.xml:385 | |
945 msgid "" | |
946 "Modifications to tracked files in the working directory are added to the " | |
947 "patch." | |
948 msgstr "" | |
949 | |
950 #. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para> | |
951 #: ../en/appB-mq-ref.xml:388 | |
952 msgid "" | |
953 "Changes to the files tracked using <command role=\"hg-cmd\">hg add</command>, " | |
954 "<command role=\"hg-cmd\">hg copy</command>, <command role=\"hg-cmd\">hg " | |
955 "remove</command>, or <command role=\"hg-cmd\">hg rename</command>. Added " | |
956 "files and copy and rename destinations are added to the patch, while removed " | |
957 "files and rename sources are removed." | |
958 msgstr "" | |
959 | |
960 #. type: Content of: <book><appendix><sect1><sect2><para> | |
961 #: ../en/appB-mq-ref.xml:397 | |
962 msgid "" | |
963 "Even if <command role=\"hg-ext-mq\">qrefresh</command> detects no changes, it " | |
964 "still recreates the changeset that represents the patch. This causes the " | |
965 "identity of the changeset to differ from the previous changeset that " | |
966 "identified the patch." | |
967 msgstr "" | |
968 | |
969 #. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para> | |
970 #: ../en/appB-mq-ref.xml:405 | |
971 msgid "" | |
972 "<option role=\"hg-ext-mq-cmd-qrefresh-opt\">-e</option>: Modify the commit " | |
973 "and patch description, using the preferred text editor." | |
974 msgstr "" | |
975 | |
976 #. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para> | |
977 #: ../en/appB-mq-ref.xml:410 | |
978 msgid "" | |
979 "<option role=\"hg-ext-mq-cmd-qrefresh-opt\">-m</option>: Modify the commit " | |
980 "message and patch description, using the given text." | |
981 msgstr "" | |
982 | |
983 #. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para> | |
984 #: ../en/appB-mq-ref.xml:415 | |
985 msgid "" | |
986 "<option role=\"hg-ext-mq-cmd-qrefresh-opt\">-l</option>: Modify the commit " | |
987 "message and patch description, using text from the given file." | |
988 msgstr "" | |
989 | |
990 #. type: Content of: <book><appendix><sect1><sect2><title> | |
991 #: ../en/appB-mq-ref.xml:423 | |
992 msgid "<command role=\"hg-ext-mq\">qrename</command>&emdash;rename a patch" | |
993 msgstr "<command role=\"hg-ext-mq\">qrename</command>&emdash;改名补丁" | |
994 | |
995 #. type: Content of: <book><appendix><sect1><sect2><para> | |
996 #: ../en/appB-mq-ref.xml:426 | |
997 msgid "" | |
998 "The <command role=\"hg-ext-mq\">qrename</command> command renames a patch, " | |
999 "and changes the entry for the patch in the <filename role=\"special\">series</" | |
1000 "filename> file." | |
1001 msgstr "" | |
1002 | |
1003 #. type: Content of: <book><appendix><sect1><sect2><para> | |
1004 #: ../en/appB-mq-ref.xml:430 | |
1005 msgid "" | |
1006 "With a single argument, <command role=\"hg-ext-mq\">qrename</command> renames " | |
1007 "the topmost applied patch. With two arguments, it renames its first argument " | |
1008 "to its second." | |
1009 msgstr "" | |
1010 | |
1011 #. type: Content of: <book><appendix><sect1><sect2><title> | |
1012 #: ../en/appB-mq-ref.xml:437 | |
1013 msgid "" | |
1014 "<command role=\"hg-ext-mq\">qrestore</command>&emdash;restore saved queue " | |
1015 "state" | |
1016 msgstr "<command role=\"hg-ext-mq\">qrestore</command>&emdash;恢复保存的队列" | |
1017 | |
1018 #. type: Content of: <book><appendix><sect1><sect2><para> | |
1019 #: ../en/appB-mq-ref.xml:441 | |
1020 msgid "XXX No idea what this does." | |
1021 msgstr "" | |
1022 | |
1023 #. type: Content of: <book><appendix><sect1><sect2><title> | |
1024 #: ../en/appB-mq-ref.xml:445 | |
1025 msgid "" | |
1026 "<command role=\"hg-ext-mq\">qsave</command>&emdash;save current queue state" | |
1027 msgstr "<command role=\"hg-ext-mq\">qsave</command>&emdash;保存当前的队列状态" | |
1028 | |
1029 #. type: Content of: <book><appendix><sect1><sect2><para> | |
1030 #: ../en/appB-mq-ref.xml:448 | |
1031 msgid "XXX Likewise." | |
1032 msgstr "" | |
1033 | |
1034 #. type: Content of: <book><appendix><sect1><sect2><title> | |
1035 #: ../en/appB-mq-ref.xml:452 | |
1036 msgid "" | |
1037 "<command role=\"hg-ext-mq\">qseries</command>&emdash;print the entire patch " | |
1038 "series" | |
1039 msgstr "<command role=\"hg-ext-mq\">qseries</command>&emdash;显示补丁序列" | |
1040 | |
1041 #. type: Content of: <book><appendix><sect1><sect2><para> | |
1042 #: ../en/appB-mq-ref.xml:455 | |
1043 msgid "" | |
1044 "The <command role=\"hg-ext-mq\">qseries</command> command prints the entire " | |
1045 "patch series from the <filename role=\"special\">series</filename> file. It " | |
1046 "prints only patch names, not empty lines or comments. It prints in order " | |
1047 "from first to be applied to last." | |
1048 msgstr "" | |
1049 | |
1050 #. type: Content of: <book><appendix><sect1><sect2><title> | |
1051 #: ../en/appB-mq-ref.xml:463 | |
1052 msgid "" | |
1053 "<command role=\"hg-ext-mq\">qtop</command>&emdash;print the name of the " | |
1054 "current patch" | |
1055 msgstr "<command role=\"hg-ext-mq\">qtop</command>&emdash;显示当前补丁的名称" | |
1056 | |
1057 #. type: Content of: <book><appendix><sect1><sect2><para> | |
1058 #: ../en/appB-mq-ref.xml:466 | |
1059 msgid "" | |
1060 "The <command role=\"hg-ext-mq\">qtop</command> prints the name of the topmost " | |
1061 "currently applied patch." | |
1062 msgstr "" | |
1063 | |
1064 #. type: Content of: <book><appendix><sect1><sect2><title> | |
1065 #: ../en/appB-mq-ref.xml:471 | |
1066 msgid "" | |
1067 "<command role=\"hg-ext-mq\">qunapplied</command>&emdash;print patches not yet " | |
1068 "applied" | |
1069 msgstr "" | |
1070 "<command role=\"hg-ext-mq\">qunapplied</command>&emdash;显示尚未应用的补丁" | |
1071 | |
1072 #. type: Content of: <book><appendix><sect1><sect2><para> | |
1073 #: ../en/appB-mq-ref.xml:475 | |
1074 msgid "" | |
1075 "The <command role=\"hg-ext-mq\">qunapplied</command> command prints the names " | |
1076 "of patches from the <filename role=\"special\">series</filename> file that " | |
1077 "are not yet applied. It prints them in order from the next patch that will " | |
1078 "be pushed to the last." | |
1079 msgstr "" | |
1080 | |
1081 #. type: Content of: <book><appendix><sect1><sect2><title> | |
1082 #: ../en/appB-mq-ref.xml:483 | |
1083 msgid "" | |
1084 "<command role=\"hg-cmd\">hg strip</command>&emdash;remove a revision and " | |
1085 "descendants" | |
1086 msgstr "<command role=\"hg-cmd\">hg strip</command>&emdash;删除一个版本及其后继" | |
1087 | |
1088 #. type: Content of: <book><appendix><sect1><sect2><para> | |
1089 #: ../en/appB-mq-ref.xml:486 | |
1090 msgid "" | |
1091 "The <command role=\"hg-cmd\">hg strip</command> command removes a revision, " | |
1092 "and all of its descendants, from the repository. It undoes the effects of " | |
1093 "the removed revisions from the repository, and updates the working directory " | |
1094 "to the first parent of the removed revision." | |
1095 msgstr "" | |
1096 | |
1097 #. type: Content of: <book><appendix><sect1><sect2><para> | |
1098 #: ../en/appB-mq-ref.xml:492 | |
1099 msgid "" | |
1100 "The <command role=\"hg-cmd\">hg strip</command> command saves a backup of the " | |
1101 "removed changesets in a bundle, so that they can be reapplied if removed in " | |
1102 "error." | |
1103 msgstr "" | |
1104 | |
1105 #. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para> | |
1106 #: ../en/appB-mq-ref.xml:498 | |
1107 msgid "" | |
1108 "<option role=\"hg-opt-strip\">-b</option>: Save unrelated changesets that are " | |
1109 "intermixed with the stripped changesets in the backup bundle." | |
1110 msgstr "" | |
1111 | |
1112 #. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para> | |
1113 #: ../en/appB-mq-ref.xml:502 | |
1114 msgid "" | |
1115 "<option role=\"hg-opt-strip\">-f</option>: If a branch has multiple heads, " | |
1116 "remove all heads. XXX This should be renamed, and use <literal>-f</literal> " | |
1117 "to strip revs when there are pending changes." | |
1118 msgstr "" | |
1119 | |
1120 #. type: Content of: <book><appendix><sect1><sect2><itemizedlist><listitem><para> | |
1121 #: ../en/appB-mq-ref.xml:507 | |
1122 msgid "<option role=\"hg-opt-strip\">-n</option>: Do not save a backup bundle." | |
1123 msgstr "" | |
1124 | |
1125 #. type: Content of: <book><appendix><sect1><title> | |
1126 #: ../en/appB-mq-ref.xml:514 | |
1127 msgid "MQ file reference" | |
1128 msgstr "MQ 文件参考" | |
1129 | |
1130 #. type: Content of: <book><appendix><sect1><sect2><title> | |
1131 #: ../en/appB-mq-ref.xml:517 | |
1132 msgid "The <filename role=\"special\">series</filename> file" | |
1133 msgstr "<filename role=\"special\">序列</filename>文件" | |
1134 | |
1135 #. type: Content of: <book><appendix><sect1><sect2><para> | |
1136 #: ../en/appB-mq-ref.xml:520 | |
1137 msgid "" | |
1138 "The <filename role=\"special\">series</filename> file contains a list of the " | |
1139 "names of all patches that MQ can apply. It is represented as a list of " | |
1140 "names, with one name saved per line. Leading and trailing white space in " | |
1141 "each line are ignored." | |
1142 msgstr "" | |
1143 | |
1144 #. type: Content of: <book><appendix><sect1><sect2><para> | |
1145 #: ../en/appB-mq-ref.xml:526 | |
1146 msgid "" | |
1147 "Lines may contain comments. A comment begins with the <quote><literal>#</" | |
1148 "literal></quote> character, and extends to the end of the line. Empty lines, " | |
1149 "and lines that contain only comments, are ignored." | |
1150 msgstr "" | |
1151 | |
1152 #. type: Content of: <book><appendix><sect1><sect2><para> | |
1153 #: ../en/appB-mq-ref.xml:531 | |
1154 msgid "" | |
1155 "You will often need to edit the <filename role=\"special\">series</filename> " | |
1156 "file by hand, hence the support for comments and empty lines noted above. " | |
1157 "For example, you can comment out a patch temporarily, and <command role=\"hg-" | |
1158 "ext-mq\">qpush</command> will skip over that patch when applying patches. " | |
1159 "You can also change the order in which patches are applied by reordering " | |
1160 "their entries in the <filename role=\"special\">series</filename> file." | |
1161 msgstr "" | |
1162 | |
1163 #. type: Content of: <book><appendix><sect1><sect2><para> | |
1164 #: ../en/appB-mq-ref.xml:540 | |
1165 msgid "" | |
1166 "Placing the <filename role=\"special\">series</filename> file under revision " | |
1167 "control is also supported; it is a good idea to place all of the patches that " | |
1168 "it refers to under revision control, as well. If you create a patch " | |
1169 "directory using the <option role=\"hg-ext-mq-cmd-qinit-opt\">-c</option> " | |
1170 "option to <command role=\"hg-ext-mq\">qinit</command>, this will be done for " | |
1171 "you automatically." | |
1172 msgstr "" | |
1173 | |
1174 #. type: Content of: <book><appendix><sect1><sect2><title> | |
1175 #: ../en/appB-mq-ref.xml:550 | |
1176 msgid "The <filename role=\"special\">status</filename> file" | |
1177 msgstr "<filename role=\"special\">状态</filename>文件" | |
1178 | |
1179 #. type: Content of: <book><appendix><sect1><sect2><para> | |
1180 #: ../en/appB-mq-ref.xml:553 | |
1181 msgid "" | |
1182 "The <filename role=\"special\">status</filename> file contains the names and " | |
1183 "changeset hashes of all patches that MQ currently has applied. Unlike the " | |
1184 "<filename role=\"special\">series</filename> file, this file is not intended " | |
1185 "for editing. You should not place this file under revision control, or " | |
1186 "modify it in any way. It is used by MQ strictly for internal book-keeping." | |
1187 msgstr "" | |
1188 | |
1189 #. type: Content of: <book><appendix><title> | |
1190 #: ../en/appC-srcinstall.xml:5 | |
1191 msgid "Installing Mercurial from source" | |
1192 msgstr "从源代码安装 Mercurial" | |
1193 | |
1194 #. type: Content of: <book><appendix><sect1><title> | |
1195 #: ../en/appC-srcinstall.xml:8 | |
1196 msgid "On a Unix-like system" | |
1197 msgstr "类 Unix 系统" | |
1198 | |
1199 #. type: Content of: <book><appendix><sect1><para> | |
1200 #: ../en/appC-srcinstall.xml:10 | |
1201 msgid "" | |
1202 "If you are using a Unix-like system that has a sufficiently recent version of " | |
1203 "Python (2.3 or newer) available, it is easy to install Mercurial from source." | |
1204 msgstr "" | |
1205 | |
1206 #. type: Content of: <book><appendix><sect1><orderedlist><listitem><para> | |
1207 #: ../en/appC-srcinstall.xml:14 | |
1208 msgid "" | |
1209 "Download a recent source tarball from <ulink url=\"http://www.selenic.com/" | |
1210 "mercurial/download\">http://www.selenic.com/mercurial/download</ulink>." | |
1211 msgstr "" | |
1212 | |
1213 #. type: Content of: <book><appendix><sect1><orderedlist><listitem><para> | |
1214 #: ../en/appC-srcinstall.xml:17 | |
1215 msgid "Unpack the tarball:" | |
1216 msgstr "" | |
1217 | |
1218 #. type: Content of: <book><appendix><sect1><orderedlist><listitem><para> | |
1219 #: ../en/appC-srcinstall.xml:20 | |
1220 msgid "" | |
1221 "Go into the source directory and run the installer script. This will build " | |
1222 "Mercurial and install it in your home directory." | |
1223 msgstr "" | |
1224 | |
1225 #. type: Content of: <book><appendix><sect1><para> | |
1226 #: ../en/appC-srcinstall.xml:27 | |
1227 msgid "" | |
1228 "Once the install finishes, Mercurial will be in the <literal>bin</literal> " | |
1229 "subdirectory of your home directory. Don't forget to make sure that this " | |
1230 "directory is present in your shell's search path." | |
1231 msgstr "" | |
1232 | |
1233 #. type: Content of: <book><appendix><sect1><para> | |
1234 #: ../en/appC-srcinstall.xml:32 | |
1235 msgid "" | |
1236 "You will probably need to set the <envar>PYTHONPATH</envar> environment " | |
1237 "variable so that the Mercurial executable can find the rest of the Mercurial " | |
1238 "packages. For example, on my laptop, I have set it to <literal>/home/bos/lib/" | |
1239 "python</literal>. The exact path that you will need to use depends on how " | |
1240 "Python was built for your system, but should be easy to figure out. If " | |
1241 "you're uncertain, look through the output of the installer script above, and " | |
1242 "see where the contents of the <literal>mercurial</literal> directory were " | |
1243 "installed to." | |
1244 msgstr "" | |
1245 | |
1246 #. type: Content of: <book><appendix><sect1><title> | |
1247 #: ../en/appC-srcinstall.xml:44 | |
1248 msgid "On Windows" | |
1249 msgstr "Windows 系统" | |
1250 | |
1251 #. type: Content of: <book><appendix><sect1><para> | |
1252 #: ../en/appC-srcinstall.xml:46 | |
1253 msgid "" | |
1254 "Building and installing Mercurial on Windows requires a variety of tools, a " | |
1255 "fair amount of technical knowledge, and considerable patience. I very much " | |
1256 "<emphasis>do not recommend</emphasis> this route if you are a <quote>casual " | |
1257 "user</quote>. Unless you intend to hack on Mercurial, I strongly suggest " | |
1258 "that you use a binary package instead." | |
1259 msgstr "" | |
1260 | |
1261 #. type: Content of: <book><appendix><sect1><para> | |
1262 #: ../en/appC-srcinstall.xml:53 | |
1263 msgid "" | |
1264 "If you are intent on building Mercurial from source on Windows, follow the " | |
1265 "<quote>hard way</quote> directions on the Mercurial wiki at <ulink url=" | |
1266 "\"http://www.selenic.com/mercurial/wiki/index.cgi/WindowsInstall\">http://www." | |
1267 "selenic.com/mercurial/wiki/index.cgi/WindowsInstall</ulink>, and expect the " | |
1268 "process to involve a lot of fiddly work." | |
1269 msgstr "" | |
1270 | |
1271 #. type: Content of: <book><appendix><title> | |
1272 #: ../en/appD-license.xml:5 | |
1273 msgid "Open Publication License" | |
1274 msgstr "" | |
1275 | |
1276 #. type: Content of: <book><appendix><para> | |
1277 #: ../en/appD-license.xml:7 | |
1278 msgid "Version 1.0, 8 June 1999" | |
1279 msgstr "" | |
1280 | |
1281 #. type: Content of: <book><appendix><sect1><title> | |
1282 #: ../en/appD-license.xml:10 | |
1283 msgid "Requirements on both unmodified and modified versions" | |
1284 msgstr "" | |
1285 | |
1286 #. type: Content of: <book><appendix><sect1><para> | |
1287 #: ../en/appD-license.xml:13 | |
1288 msgid "" | |
1289 "The Open Publication works may be reproduced and distributed in whole or in " | |
1290 "part, in any medium physical or electronic, provided that the terms of this " | |
1291 "license are adhered to, and that this license or an incorporation of it by " | |
1292 "reference (with any options elected by the author(s) and/or publisher) is " | |
1293 "displayed in the reproduction." | |
1294 msgstr "" | |
1295 | |
1296 #. type: Content of: <book><appendix><sect1><para> | |
1297 #: ../en/appD-license.xml:20 | |
1298 msgid "Proper form for an incorporation by reference is as follows:" | |
1299 msgstr "" | |
1300 | |
1301 #. type: Content of: <book><appendix><sect1><blockquote><para> | |
1302 #: ../en/appD-license.xml:24 | |
1303 msgid "" | |
1304 "Copyright (c) <emphasis>year</emphasis> by <emphasis>author's name or " | |
1305 "designee</emphasis>. This material may be distributed only subject to the " | |
1306 "terms and conditions set forth in the Open Publication License, v<emphasis>x." | |
1307 "y</emphasis> or later (the latest version is presently available at <ulink " | |
1308 "url=\"http://www.opencontent.org/openpub/\">http://www.opencontent.org/" | |
1309 "openpub/</ulink>)." | |
1310 msgstr "" | |
1311 | |
1312 #. type: Content of: <book><appendix><sect1><para> | |
1313 #: ../en/appD-license.xml:33 | |
1314 msgid "" | |
1315 "The reference must be immediately followed with any options elected by the " | |
1316 "author(s) and/or publisher of the document (see section <xref linkend=\"sec." | |
1317 "opl.options\"/>)." | |
1318 msgstr "" | |
1319 | |
1320 #. type: Content of: <book><appendix><sect1><para> | |
1321 #: ../en/appD-license.xml:37 | |
1322 msgid "" | |
1323 "Commercial redistribution of Open Publication-licensed material is permitted." | |
1324 msgstr "" | |
1325 | |
1326 #. type: Content of: <book><appendix><sect1><para> | |
1327 #: ../en/appD-license.xml:40 | |
1328 msgid "" | |
1329 "Any publication in standard (paper) book form shall require the citation of " | |
1330 "the original publisher and author. The publisher and author's names shall " | |
1331 "appear on all outer surfaces of the book. On all outer surfaces of the book " | |
1332 "the original publisher's name shall be as large as the title of the work and " | |
1333 "cited as possessive with respect to the title." | |
1334 msgstr "" | |
1335 | |
1336 #. type: Content of: <book><appendix><sect1><title> | |
1337 #: ../en/appD-license.xml:49 | |
1338 msgid "Copyright" | |
1339 msgstr "" | |
1340 | |
1341 #. type: Content of: <book><appendix><sect1><para> | |
1342 #: ../en/appD-license.xml:51 | |
1343 msgid "" | |
1344 "The copyright to each Open Publication is owned by its author(s) or designee." | |
1345 msgstr "" | |
1346 | |
1347 #. type: Content of: <book><appendix><sect1><title> | |
1348 #: ../en/appD-license.xml:56 | |
1349 msgid "Scope of license" | |
1350 msgstr "" | |
1351 | |
1352 #. type: Content of: <book><appendix><sect1><para> | |
1353 #: ../en/appD-license.xml:58 | |
1354 msgid "" | |
1355 "The following license terms apply to all Open Publication works, unless " | |
1356 "otherwise explicitly stated in the document." | |
1357 msgstr "" | |
1358 | |
1359 #. type: Content of: <book><appendix><sect1><para> | |
1360 #: ../en/appD-license.xml:62 | |
1361 msgid "" | |
1362 "Mere aggregation of Open Publication works or a portion of an Open " | |
1363 "Publication work with other works or programs on the same media shall not " | |
1364 "cause this license to apply to those other works. The aggregate work shall " | |
1365 "contain a notice specifying the inclusion of the Open Publication material " | |
1366 "and appropriate copyright notice." | |
1367 msgstr "" | |
1368 | |
1369 #. type: Content of: <book><appendix><sect1><para> | |
1370 #: ../en/appD-license.xml:69 | |
1371 msgid "" | |
1372 "<emphasis role=\"bold\">Severability</emphasis>. If any part of this license " | |
1373 "is found to be unenforceable in any jurisdiction, the remaining portions of " | |
1374 "the license remain in force." | |
1375 msgstr "" | |
1376 | |
1377 #. type: Content of: <book><appendix><sect1><para> | |
1378 #: ../en/appD-license.xml:74 | |
1379 msgid "" | |
1380 "<emphasis role=\"bold\">No warranty</emphasis>. Open Publication works are " | |
1381 "licensed and provided <quote>as is</quote> without warranty of any kind, " | |
1382 "express or implied, including, but not limited to, the implied warranties of " | |
1383 "merchantability and fitness for a particular purpose or a warranty of non-" | |
1384 "infringement." | |
1385 msgstr "" | |
1386 | |
1387 #. type: Content of: <book><appendix><sect1><title> | |
1388 #: ../en/appD-license.xml:83 | |
1389 msgid "Requirements on modified works" | |
1390 msgstr "" | |
1391 | |
1392 #. type: Content of: <book><appendix><sect1><para> | |
1393 #: ../en/appD-license.xml:85 | |
1394 msgid "" | |
1395 "All modified versions of documents covered by this license, including " | |
1396 "translations, anthologies, compilations and partial documents, must meet the " | |
1397 "following requirements:" | |
1398 msgstr "" | |
1399 | |
1400 #. type: Content of: <book><appendix><sect1><orderedlist><listitem><para> | |
1401 #: ../en/appD-license.xml:90 | |
1402 msgid "The modified version must be labeled as such." | |
1403 msgstr "" | |
1404 | |
1405 #. type: Content of: <book><appendix><sect1><orderedlist><listitem><para> | |
1406 #: ../en/appD-license.xml:93 | |
1407 msgid "" | |
1408 "The person making the modifications must be identified and the modifications " | |
1409 "dated." | |
1410 msgstr "" | |
1411 | |
1412 #. type: Content of: <book><appendix><sect1><orderedlist><listitem><para> | |
1413 #: ../en/appD-license.xml:96 | |
1414 msgid "" | |
1415 "Acknowledgement of the original author and publisher if applicable must be " | |
1416 "retained according to normal academic citation practices." | |
1417 msgstr "" | |
1418 | |
1419 #. type: Content of: <book><appendix><sect1><orderedlist><listitem><para> | |
1420 #: ../en/appD-license.xml:100 | |
1421 msgid "The location of the original unmodified document must be identified." | |
1422 msgstr "" | |
1423 | |
1424 #. type: Content of: <book><appendix><sect1><orderedlist><listitem><para> | |
1425 #: ../en/appD-license.xml:103 | |
1426 msgid "" | |
1427 "The original author's (or authors') name(s) may not be used to assert or " | |
1428 "imply endorsement of the resulting document without the original author's (or " | |
1429 "authors') permission." | |
1430 msgstr "" | |
1431 | |
1432 #. type: Content of: <book><appendix><sect1><title> | |
1433 #: ../en/appD-license.xml:111 | |
1434 msgid "Good-practice recommendations" | |
1435 msgstr "" | |
1436 | |
1437 #. type: Content of: <book><appendix><sect1><para> | |
1438 #: ../en/appD-license.xml:113 | |
1439 msgid "" | |
1440 "In addition to the requirements of this license, it is requested from and " | |
1441 "strongly recommended of redistributors that:" | |
1442 msgstr "" | |
1443 | |
1444 #. type: Content of: <book><appendix><sect1><orderedlist><listitem><para> | |
1445 #: ../en/appD-license.xml:118 | |
1446 msgid "" | |
1447 "If you are distributing Open Publication works on hardcopy or CD-ROM, you " | |
1448 "provide email notification to the authors of your intent to redistribute at " | |
1449 "least thirty days before your manuscript or media freeze, to give the authors " | |
1450 "time to provide updated documents. This notification should describe " | |
1451 "modifications, if any, made to the document." | |
1452 msgstr "" | |
1453 | |
1454 #. type: Content of: <book><appendix><sect1><orderedlist><listitem><para> | |
1455 #: ../en/appD-license.xml:125 | |
1456 msgid "" | |
1457 "All substantive modifications (including deletions) be either clearly marked " | |
1458 "up in the document or else described in an attachment to the document." | |
1459 msgstr "" | |
1460 | |
1461 #. type: Content of: <book><appendix><sect1><orderedlist><listitem><para> | |
1462 #: ../en/appD-license.xml:129 | |
1463 msgid "" | |
1464 "Finally, while it is not mandatory under this license, it is considered good " | |
1465 "form to offer a free copy of any hardcopy and CD-ROM expression of an Open " | |
1466 "Publication-licensed work to its author(s)." | |
1467 msgstr "" | |
1468 | |
1469 #. type: Content of: <book><appendix><sect1><title> | |
1470 #: ../en/appD-license.xml:137 | |
1471 msgid "License options" | |
1472 msgstr "" | |
1473 | |
1474 #. type: Content of: <book><appendix><sect1><para> | |
1475 #: ../en/appD-license.xml:139 | |
1476 msgid "" | |
1477 "The author(s) and/or publisher of an Open Publication-licensed document may " | |
1478 "elect certain options by appending language to the reference to or copy of " | |
1479 "the license. These options are considered part of the license instance and " | |
1480 "must be included with the license (or its incorporation by reference) in " | |
1481 "derived works." | |
1482 msgstr "" | |
1483 | |
1484 #. type: Content of: <book><appendix><sect1><orderedlist><listitem><para> | |
1485 #: ../en/appD-license.xml:147 | |
1486 msgid "" | |
1487 "To prohibit distribution of substantively modified versions without the " | |
1488 "explicit permission of the author(s). <quote>Substantive modification</quote> " | |
1489 "is defined as a change to the semantic content of the document, and excludes " | |
1490 "mere changes in format or typographical corrections." | |
1491 msgstr "" | |
1492 | |
1493 #. type: Content of: <book><appendix><sect1><orderedlist><listitem><para> | |
1494 #: ../en/appD-license.xml:154 | |
1495 msgid "" | |
1496 "To accomplish this, add the phrase <quote>Distribution of substantively " | |
1497 "modified versions of this document is prohibited without the explicit " | |
1498 "permission of the copyright holder.</quote> to the license reference or copy." | |
1499 msgstr "" | |
1500 | |
1501 #. type: Content of: <book><appendix><sect1><orderedlist><listitem><para> | |
1502 #: ../en/appD-license.xml:160 | |
1503 msgid "" | |
1504 "To prohibit any publication of this work or derivative works in whole or in " | |
1505 "part in standard (paper) book form for commercial purposes is prohibited " | |
1506 "unless prior permission is obtained from the copyright holder." | |
1507 msgstr "" | |
1508 | |
1509 #. type: Content of: <book><appendix><sect1><orderedlist><listitem><para> | |
1510 #: ../en/appD-license.xml:165 | |
1511 msgid "" | |
1512 "To accomplish this, add the phrase <quote>Distribution of the work or " | |
1513 "derivative of the work in any standard (paper) book form is prohibited unless " | |
1514 "prior permission is obtained from the copyright holder.</quote> to the " | |
1515 "license reference or copy." | |
1516 msgstr "" | |
1517 | |
1518 #. type: Content of: <book><chapter><title> | |
1519 #: ../en/ch01-intro.xml:5 | |
1520 msgid "Introduction" | |
1521 msgstr "简介" | |
1522 | |
1523 #. type: Content of: <book><chapter><sect1><title> | |
1524 #: ../en/ch01-intro.xml:8 | |
1525 msgid "About revision control" | |
1526 msgstr "关于版本控制" | |
1527 | |
1528 #. type: Content of: <book><chapter><sect1><para> | |
1529 #: ../en/ch01-intro.xml:10 | |
1530 msgid "" | |
1531 "Revision control is the process of managing multiple versions of a piece of " | |
1532 "information. In its simplest form, this is something that many people do by " | |
1533 "hand: every time you modify a file, save it under a new name that contains a " | |
1534 "number, each one higher than the number of the preceding version." | |
1535 msgstr "" | |
1536 | |
1537 #. type: Content of: <book><chapter><sect1><para> | |
1538 #: ../en/ch01-intro.xml:16 | |
1539 msgid "" | |
1540 "Manually managing multiple versions of even a single file is an error-prone " | |
1541 "task, though, so software tools to help automate this process have long been " | |
1542 "available. The earliest automated revision control tools were intended to " | |
1543 "help a single user to manage revisions of a single file. Over the past few " | |
1544 "decades, the scope of revision control tools has expanded greatly; they now " | |
1545 "manage multiple files, and help multiple people to work together. The best " | |
1546 "modern revision control tools have no problem coping with thousands of people " | |
1547 "working together on projects that consist of hundreds of thousands of files." | |
1548 msgstr "" | |
1549 | |
1550 #. type: Content of: <book><chapter><sect1><sect2><title> | |
1551 #: ../en/ch01-intro.xml:28 | |
1552 msgid "Why use revision control?" | |
1553 msgstr "为什么使用版本控制?" | |
1554 | |
1555 #. type: Content of: <book><chapter><sect1><sect2><para> | |
1556 #: ../en/ch01-intro.xml:30 | |
1557 msgid "" | |
1558 "There are a number of reasons why you or your team might want to use an " | |
1559 "automated revision control tool for a project." | |
1560 msgstr "" | |
1561 | |
1562 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
1563 #: ../en/ch01-intro.xml:34 | |
1564 msgid "" | |
1565 "It will track the history and evolution of your project, so you don't have " | |
1566 "to. For every change, you'll have a log of <emphasis>who</emphasis> made it; " | |
1567 "<emphasis>why</emphasis> they made it; <emphasis>when</emphasis> they made " | |
1568 "it; and <emphasis>what</emphasis> the change was." | |
1569 msgstr "" | |
1570 | |
1571 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
1572 #: ../en/ch01-intro.xml:41 | |
1573 msgid "" | |
1574 "When you're working with other people, revision control software makes it " | |
1575 "easier for you to collaborate. For example, when people more or less " | |
1576 "simultaneously make potentially incompatible changes, the software will help " | |
1577 "you to identify and resolve those conflicts." | |
1578 msgstr "" | |
1579 | |
1580 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
1581 #: ../en/ch01-intro.xml:47 | |
1582 msgid "" | |
1583 "It can help you to recover from mistakes. If you make a change that later " | |
1584 "turns out to be in error, you can revert to an earlier version of one or more " | |
1585 "files. In fact, a <emphasis>really</emphasis> good revision control tool " | |
1586 "will even help you to efficiently figure out exactly when a problem was " | |
1587 "introduced (see section <xref linkend=\"sec.undo.bisect\"/> for details)." | |
1588 msgstr "" | |
1589 | |
1590 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
1591 #: ../en/ch01-intro.xml:54 | |
1592 msgid "" | |
1593 "It will help you to work simultaneously on, and manage the drift between, " | |
1594 "multiple versions of your project." | |
1595 msgstr "" | |
1596 | |
1597 #. type: Content of: <book><chapter><sect1><sect2><para> | |
1598 #: ../en/ch01-intro.xml:57 | |
1599 msgid "" | |
1600 "Most of these reasons are equally valid---at least in theory---whether you're " | |
1601 "working on a project by yourself, or with a hundred other people." | |
1602 msgstr "" | |
1603 | |
1604 #. type: Content of: <book><chapter><sect1><sect2><para> | |
1605 #: ../en/ch01-intro.xml:61 | |
1606 msgid "" | |
1607 "A key question about the practicality of revision control at these two " | |
1608 "different scales (<quote>lone hacker</quote> and <quote>huge team</quote>) is " | |
1609 "how its <emphasis>benefits</emphasis> compare to its <emphasis>costs</" | |
1610 "emphasis>. A revision control tool that's difficult to understand or use is " | |
1611 "going to impose a high cost." | |
1612 msgstr "" | |
1613 | |
1614 #. type: Content of: <book><chapter><sect1><sect2><para> | |
1615 #: ../en/ch01-intro.xml:69 | |
1616 msgid "" | |
1617 "A five-hundred-person project is likely to collapse under its own weight " | |
1618 "almost immediately without a revision control tool and process. In this case, " | |
1619 "the cost of using revision control might hardly seem worth considering, since " | |
1620 "<emphasis>without</emphasis> it, failure is almost guaranteed." | |
1621 msgstr "" | |
1622 | |
1623 #. type: Content of: <book><chapter><sect1><sect2><para> | |
1624 #: ../en/ch01-intro.xml:76 | |
1625 msgid "" | |
1626 "On the other hand, a one-person <quote>quick hack</quote> might seem like a " | |
1627 "poor place to use a revision control tool, because surely the cost of using " | |
1628 "one must be close to the overall cost of the project. Right?" | |
1629 msgstr "" | |
1630 | |
1631 #. type: Content of: <book><chapter><sect1><sect2><para> | |
1632 #: ../en/ch01-intro.xml:81 | |
1633 msgid "" | |
1634 "Mercurial uniquely supports <emphasis>both</emphasis> of these scales of " | |
1635 "development. You can learn the basics in just a few minutes, and due to its " | |
1636 "low overhead, you can apply revision control to the smallest of projects with " | |
1637 "ease. Its simplicity means you won't have a lot of abstruse concepts or " | |
1638 "command sequences competing for mental space with whatever you're " | |
1639 "<emphasis>really</emphasis> trying to do. At the same time, Mercurial's high " | |
1640 "performance and peer-to-peer nature let you scale painlessly to handle large " | |
1641 "projects." | |
1642 msgstr "" | |
1643 | |
1644 #. type: Content of: <book><chapter><sect1><sect2><para> | |
1645 #: ../en/ch01-intro.xml:91 | |
1646 msgid "" | |
1647 "No revision control tool can rescue a poorly run project, but a good choice " | |
1648 "of tools can make a huge difference to the fluidity with which you can work " | |
1649 "on a project." | |
1650 msgstr "" | |
1651 | |
1652 #. type: Content of: <book><chapter><sect1><sect2><title> | |
1653 #: ../en/ch01-intro.xml:97 | |
1654 msgid "The many names of revision control" | |
1655 msgstr "版本控制的别名" | |
1656 | |
1657 #. type: Content of: <book><chapter><sect1><sect2><para> | |
1658 #: ../en/ch01-intro.xml:99 | |
1659 msgid "" | |
1660 "Revision control is a diverse field, so much so that it doesn't actually have " | |
1661 "a single name or acronym. Here are a few of the more common names and " | |
1662 "acronyms you'll encounter:" | |
1663 msgstr "" | |
1664 | |
1665 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
1666 #: ../en/ch01-intro.xml:104 | |
1667 msgid "Revision control (RCS)" | |
1668 msgstr "" | |
1669 | |
1670 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
1671 #: ../en/ch01-intro.xml:105 | |
1672 msgid "Software configuration management (SCM), or configuration management" | |
1673 msgstr "" | |
1674 | |
1675 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
1676 #: ../en/ch01-intro.xml:107 | |
1677 msgid "Source code management" | |
1678 msgstr "" | |
1679 | |
1680 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
1681 #: ../en/ch01-intro.xml:108 | |
1682 msgid "Source code control, or source control" | |
1683 msgstr "" | |
1684 | |
1685 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
1686 #: ../en/ch01-intro.xml:110 | |
1687 msgid "Version control (VCS)" | |
1688 msgstr "" | |
1689 | |
1690 #. type: Content of: <book><chapter><sect1><sect2><para> | |
1691 #: ../en/ch01-intro.xml:112 | |
1692 msgid "" | |
1693 "Some people claim that these terms actually have different meanings, but in " | |
1694 "practice they overlap so much that there's no agreed or even useful way to " | |
1695 "tease them apart." | |
1696 msgstr "" | |
1697 | |
1698 #. type: Content of: <book><chapter><sect1><title> | |
1699 #: ../en/ch01-intro.xml:119 | |
1700 msgid "A short history of revision control" | |
1701 msgstr "版本控制简史" | |
1702 | |
1703 #. type: Content of: <book><chapter><sect1><para> | |
1704 #: ../en/ch01-intro.xml:121 | |
1705 msgid "" | |
1706 "The best known of the old-time revision control tools is SCCS (Source Code " | |
1707 "Control System), which Marc Rochkind wrote at Bell Labs, in the early 1970s. " | |
1708 "SCCS operated on individual files, and required every person working on a " | |
1709 "project to have access to a shared workspace on a single system. Only one " | |
1710 "person could modify a file at any time; arbitration for access to files was " | |
1711 "via locks. It was common for people to lock files, and later forget to " | |
1712 "unlock them, preventing anyone else from modifying those files without the " | |
1713 "help of an administrator." | |
1714 msgstr "" | |
1715 | |
1716 #. type: Content of: <book><chapter><sect1><para> | |
1717 #: ../en/ch01-intro.xml:132 | |
1718 msgid "" | |
1719 "Walter Tichy developed a free alternative to SCCS in the early 1980s; he " | |
1720 "called his program RCS (Revision Control System). Like SCCS, RCS required " | |
1721 "developers to work in a single shared workspace, and to lock files to prevent " | |
1722 "multiple people from modifying them simultaneously." | |
1723 msgstr "" | |
1724 | |
1725 #. type: Content of: <book><chapter><sect1><para> | |
1726 #: ../en/ch01-intro.xml:138 | |
1727 msgid "" | |
1728 "Later in the 1980s, Dick Grune used RCS as a building block for a set of " | |
1729 "shell scripts he initially called cmt, but then renamed to CVS (Concurrent " | |
1730 "Versions System). The big innovation of CVS was that it let developers work " | |
1731 "simultaneously and somewhat independently in their own personal workspaces. " | |
1732 "The personal workspaces prevented developers from stepping on each other's " | |
1733 "toes all the time, as was common with SCCS and RCS. Each developer had a copy " | |
1734 "of every project file, and could modify their copies independently. They had " | |
1735 "to merge their edits prior to committing changes to the central repository." | |
1736 msgstr "" | |
1737 | |
1738 #. type: Content of: <book><chapter><sect1><para> | |
1739 #: ../en/ch01-intro.xml:149 | |
1740 msgid "" | |
1741 "Brian Berliner took Grune's original scripts and rewrote them in C, releasing " | |
1742 "in 1989 the code that has since developed into the modern version of CVS. " | |
1743 "CVS subsequently acquired the ability to operate over a network connection, " | |
1744 "giving it a client/server architecture. CVS's architecture is centralised; " | |
1745 "only the server has a copy of the history of the project. Client workspaces " | |
1746 "just contain copies of recent versions of the project's files, and a little " | |
1747 "metadata to tell them where the server is. CVS has been enormously " | |
1748 "successful; it is probably the world's most widely used revision control " | |
1749 "system." | |
1750 msgstr "" | |
1751 | |
1752 #. type: Content of: <book><chapter><sect1><para> | |
1753 #: ../en/ch01-intro.xml:160 | |
1754 msgid "" | |
1755 "In the early 1990s, Sun Microsystems developed an early distributed revision " | |
1756 "control system, called TeamWare. A TeamWare workspace contains a complete " | |
1757 "copy of the project's history. TeamWare has no notion of a central " | |
1758 "repository. (CVS relied upon RCS for its history storage; TeamWare used " | |
1759 "SCCS.)" | |
1760 msgstr "" | |
1761 | |
1762 #. type: Content of: <book><chapter><sect1><para> | |
1763 #: ../en/ch01-intro.xml:167 | |
1764 msgid "" | |
1765 "As the 1990s progressed, awareness grew of a number of problems with CVS. It " | |
1766 "records simultaneous changes to multiple files individually, instead of " | |
1767 "grouping them together as a single logically atomic operation. It does not " | |
1768 "manage its file hierarchy well; it is easy to make a mess of a repository by " | |
1769 "renaming files and directories. Worse, its source code is difficult to read " | |
1770 "and maintain, which made the <quote>pain level</quote> of fixing these " | |
1771 "architectural problems prohibitive." | |
1772 msgstr "" | |
1773 | |
1774 #. type: Content of: <book><chapter><sect1><para> | |
1775 #: ../en/ch01-intro.xml:177 | |
1776 msgid "" | |
1777 "In 2001, Jim Blandy and Karl Fogel, two developers who had worked on CVS, " | |
1778 "started a project to replace it with a tool that would have a better " | |
1779 "architecture and cleaner code. The result, Subversion, does not stray from " | |
1780 "CVS's centralised client/server model, but it adds multi-file atomic commits, " | |
1781 "better namespace management, and a number of other features that make it a " | |
1782 "generally better tool than CVS. Since its initial release, it has rapidly " | |
1783 "grown in popularity." | |
1784 msgstr "" | |
1785 | |
1786 #. type: Content of: <book><chapter><sect1><para> | |
1787 #: ../en/ch01-intro.xml:186 | |
1788 msgid "" | |
1789 "More or less simultaneously, Graydon Hoare began working on an ambitious " | |
1790 "distributed revision control system that he named Monotone. While Monotone " | |
1791 "addresses many of CVS's design flaws and has a peer-to-peer architecture, it " | |
1792 "goes beyond earlier (and subsequent) revision control tools in a number of " | |
1793 "innovative ways. It uses cryptographic hashes as identifiers, and has an " | |
1794 "integral notion of <quote>trust</quote> for code from different sources." | |
1795 msgstr "" | |
1796 | |
1797 #. type: Content of: <book><chapter><sect1><para> | |
1798 #: ../en/ch01-intro.xml:195 | |
1799 msgid "" | |
1800 "Mercurial began life in 2005. While a few aspects of its design are " | |
1801 "influenced by Monotone, Mercurial focuses on ease of use, high performance, " | |
1802 "and scalability to very large projects." | |
1803 msgstr "" | |
1804 | |
1805 #. type: Content of: <book><chapter><sect1><title> | |
1806 #: ../en/ch01-intro.xml:202 | |
1807 msgid "Trends in revision control" | |
1808 msgstr "版本控制的发展趋势" | |
1809 | |
1810 #. type: Content of: <book><chapter><sect1><para> | |
1811 #: ../en/ch01-intro.xml:204 | |
1812 msgid "" | |
1813 "There has been an unmistakable trend in the development and use of revision " | |
1814 "control tools over the past four decades, as people have become familiar with " | |
1815 "the capabilities of their tools and constrained by their limitations." | |
1816 msgstr "" | |
1817 | |
1818 #. type: Content of: <book><chapter><sect1><para> | |
1819 #: ../en/ch01-intro.xml:209 | |
1820 msgid "" | |
1821 "The first generation began by managing single files on individual computers. " | |
1822 "Although these tools represented a huge advance over ad-hoc manual revision " | |
1823 "control, their locking model and reliance on a single computer limited them " | |
1824 "to small, tightly-knit teams." | |
1825 msgstr "" | |
1826 | |
1827 #. type: Content of: <book><chapter><sect1><para> | |
1828 #: ../en/ch01-intro.xml:215 | |
1829 msgid "" | |
1830 "The second generation loosened these constraints by moving to network-" | |
1831 "centered architectures, and managing entire projects at a time. As projects " | |
1832 "grew larger, they ran into new problems. With clients needing to talk to " | |
1833 "servers very frequently, server scaling became an issue for large projects. " | |
1834 "An unreliable network connection could prevent remote users from being able " | |
1835 "to talk to the server at all. As open source projects started making read-" | |
1836 "only access available anonymously to anyone, people without commit privileges " | |
1837 "found that they could not use the tools to interact with a project in a " | |
1838 "natural way, as they could not record their changes." | |
1839 msgstr "" | |
1840 | |
1841 #. type: Content of: <book><chapter><sect1><para> | |
1842 #: ../en/ch01-intro.xml:227 | |
1843 msgid "" | |
1844 "The current generation of revision control tools is peer-to-peer in nature. " | |
1845 "All of these systems have dropped the dependency on a single central server, " | |
1846 "and allow people to distribute their revision control data to where it's " | |
1847 "actually needed. Collaboration over the Internet has moved from constrained " | |
1848 "by technology to a matter of choice and consensus. Modern tools can operate " | |
1849 "offline indefinitely and autonomously, with a network connection only needed " | |
1850 "when syncing changes with another repository." | |
1851 msgstr "" | |
1852 | |
1853 #. type: Content of: <book><chapter><sect1><title> | |
1854 #: ../en/ch01-intro.xml:239 | |
1855 msgid "A few of the advantages of distributed revision control" | |
1856 msgstr "分布版本控制的优点" | |
1857 | |
1858 #. type: Content of: <book><chapter><sect1><para> | |
1859 #: ../en/ch01-intro.xml:242 | |
1860 msgid "" | |
1861 "Even though distributed revision control tools have for several years been as " | |
1862 "robust and usable as their previous-generation counterparts, people using " | |
1863 "older tools have not yet necessarily woken up to their advantages. There are " | |
1864 "a number of ways in which distributed tools shine relative to centralised " | |
1865 "ones." | |
1866 msgstr "" | |
1867 | |
1868 #. type: Content of: <book><chapter><sect1><para> | |
1869 #: ../en/ch01-intro.xml:249 | |
1870 msgid "" | |
1871 "For an individual developer, distributed tools are almost always much faster " | |
1872 "than centralised tools. This is for a simple reason: a centralised tool " | |
1873 "needs to talk over the network for many common operations, because most " | |
1874 "metadata is stored in a single copy on the central server. A distributed " | |
1875 "tool stores all of its metadata locally. All else being equal, talking over " | |
1876 "the network adds overhead to a centralised tool. Don't underestimate the " | |
1877 "value of a snappy, responsive tool: you're going to spend a lot of time " | |
1878 "interacting with your revision control software." | |
1879 msgstr "" | |
1880 | |
1881 #. type: Content of: <book><chapter><sect1><para> | |
1882 #: ../en/ch01-intro.xml:260 | |
1883 msgid "" | |
1884 "Distributed tools are indifferent to the vagaries of your server " | |
1885 "infrastructure, again because they replicate metadata to so many locations. " | |
1886 "If you use a centralised system and your server catches fire, you'd better " | |
1887 "hope that your backup media are reliable, and that your last backup was " | |
1888 "recent and actually worked. With a distributed tool, you have many backups " | |
1889 "available on every contributor's computer." | |
1890 msgstr "" | |
1891 | |
1892 #. type: Content of: <book><chapter><sect1><para> | |
1893 #: ../en/ch01-intro.xml:268 | |
1894 msgid "" | |
1895 "The reliability of your network will affect distributed tools far less than " | |
1896 "it will centralised tools. You can't even use a centralised tool without a " | |
1897 "network connection, except for a few highly constrained commands. With a " | |
1898 "distributed tool, if your network connection goes down while you're working, " | |
1899 "you may not even notice. The only thing you won't be able to do is talk to " | |
1900 "repositories on other computers, something that is relatively rare compared " | |
1901 "with local operations. If you have a far-flung team of collaborators, this " | |
1902 "may be significant." | |
1903 msgstr "" | |
1904 | |
1905 #. type: Content of: <book><chapter><sect1><sect2><title> | |
1906 #: ../en/ch01-intro.xml:279 | |
1907 msgid "Advantages for open source projects" | |
1908 msgstr "开源项目的优点" | |
1909 | |
1910 #. type: Content of: <book><chapter><sect1><sect2><para> | |
1911 #: ../en/ch01-intro.xml:281 | |
1912 msgid "" | |
1913 "If you take a shine to an open source project and decide that you would like " | |
1914 "to start hacking on it, and that project uses a distributed revision control " | |
1915 "tool, you are at once a peer with the people who consider themselves the " | |
1916 "<quote>core</quote> of that project. If they publish their repositories, you " | |
1917 "can immediately copy their project history, start making changes, and record " | |
1918 "your work, using the same tools in the same ways as insiders. By contrast, " | |
1919 "with a centralised tool, you must use the software in a <quote>read only</" | |
1920 "quote> mode unless someone grants you permission to commit changes to their " | |
1921 "central server. Until then, you won't be able to record changes, and your " | |
1922 "local modifications will be at risk of corruption any time you try to update " | |
1923 "your client's view of the repository." | |
1924 msgstr "" | |
1925 | |
1926 #. type: Content of: <book><chapter><sect1><sect2><sect3><title> | |
1927 #: ../en/ch01-intro.xml:297 | |
1928 msgid "The forking non-problem" | |
1929 msgstr "" | |
1930 | |
1931 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
1932 #: ../en/ch01-intro.xml:299 | |
1933 msgid "" | |
1934 "It has been suggested that distributed revision control tools pose some sort " | |
1935 "of risk to open source projects because they make it easy to <quote>fork</" | |
1936 "quote> the development of a project. A fork happens when there are " | |
1937 "differences in opinion or attitude between groups of developers that cause " | |
1938 "them to decide that they can't work together any longer. Each side takes a " | |
1939 "more or less complete copy of the project's source code, and goes off in its " | |
1940 "own direction." | |
1941 msgstr "" | |
1942 | |
1943 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
1944 #: ../en/ch01-intro.xml:309 | |
1945 msgid "" | |
1946 "Sometimes the camps in a fork decide to reconcile their differences. With a " | |
1947 "centralised revision control system, the <emphasis>technical</emphasis> " | |
1948 "process of reconciliation is painful, and has to be performed largely by " | |
1949 "hand. You have to decide whose revision history is going to <quote>win</" | |
1950 "quote>, and graft the other team's changes into the tree somehow. This " | |
1951 "usually loses some or all of one side's revision history." | |
1952 msgstr "" | |
1953 | |
1954 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
1955 #: ../en/ch01-intro.xml:318 | |
1956 msgid "" | |
1957 "What distributed tools do with respect to forking is they make forking the " | |
1958 "<emphasis>only</emphasis> way to develop a project. Every single change that " | |
1959 "you make is potentially a fork point. The great strength of this approach is " | |
1960 "that a distributed revision control tool has to be really good at " | |
1961 "<emphasis>merging</emphasis> forks, because forks are absolutely fundamental: " | |
1962 "they happen all the time." | |
1963 msgstr "" | |
1964 | |
1965 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
1966 #: ../en/ch01-intro.xml:327 | |
1967 msgid "" | |
1968 "If every piece of work that everybody does, all the time, is framed in terms " | |
1969 "of forking and merging, then what the open source world refers to as a " | |
1970 "<quote>fork</quote> becomes <emphasis>purely</emphasis> a social issue. If " | |
1971 "anything, distributed tools <emphasis>lower</emphasis> the likelihood of a " | |
1972 "fork:" | |
1973 msgstr "" | |
1974 | |
1975 #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para> | |
1976 #: ../en/ch01-intro.xml:334 | |
1977 msgid "" | |
1978 "They eliminate the social distinction that centralised tools impose: that " | |
1979 "between insiders (people with commit access) and outsiders (people without)." | |
1980 msgstr "" | |
1981 | |
1982 #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para> | |
1983 #: ../en/ch01-intro.xml:338 | |
1984 msgid "" | |
1985 "They make it easier to reconcile after a social fork, because all that's " | |
1986 "involved from the perspective of the revision control software is just " | |
1987 "another merge." | |
1988 msgstr "" | |
1989 | |
1990 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
1991 #: ../en/ch01-intro.xml:343 | |
1992 msgid "" | |
1993 "Some people resist distributed tools because they want to retain tight " | |
1994 "control over their projects, and they believe that centralised tools give " | |
1995 "them this control. However, if you're of this belief, and you publish your " | |
1996 "CVS or Subversion repositories publicly, there are plenty of tools available " | |
1997 "that can pull out your entire project's history (albeit slowly) and recreate " | |
1998 "it somewhere that you don't control. So while your control in this case is " | |
1999 "illusory, you are forgoing the ability to fluidly collaborate with whatever " | |
2000 "people feel compelled to mirror and fork your history." | |
2001 msgstr "" | |
2002 | |
2003 #. type: Content of: <book><chapter><sect1><sect2><title> | |
2004 #: ../en/ch01-intro.xml:358 | |
2005 msgid "Advantages for commercial projects" | |
2006 msgstr "商业项目的优点" | |
2007 | |
2008 #. type: Content of: <book><chapter><sect1><sect2><para> | |
2009 #: ../en/ch01-intro.xml:360 | |
2010 msgid "" | |
2011 "Many commercial projects are undertaken by teams that are scattered across " | |
2012 "the globe. Contributors who are far from a central server will see slower " | |
2013 "command execution and perhaps less reliability. Commercial revision control " | |
2014 "systems attempt to ameliorate these problems with remote-site replication add-" | |
2015 "ons that are typically expensive to buy and cantankerous to administer. A " | |
2016 "distributed system doesn't suffer from these problems in the first place. " | |
2017 "Better yet, you can easily set up multiple authoritative servers, say one per " | |
2018 "site, so that there's no redundant communication between repositories over " | |
2019 "expensive long-haul network links." | |
2020 msgstr "" | |
2021 | |
2022 #. type: Content of: <book><chapter><sect1><sect2><para> | |
2023 #: ../en/ch01-intro.xml:372 | |
2024 msgid "" | |
2025 "Centralised revision control systems tend to have relatively low " | |
2026 "scalability. It's not unusual for an expensive centralised system to fall " | |
2027 "over under the combined load of just a few dozen concurrent users. Once " | |
2028 "again, the typical response tends to be an expensive and clunky replication " | |
2029 "facility. Since the load on a central server---if you have one at all---is " | |
2030 "many times lower with a distributed tool (because all of the data is " | |
2031 "replicated everywhere), a single cheap server can handle the needs of a much " | |
2032 "larger team, and replication to balance load becomes a simple matter of " | |
2033 "scripting." | |
2034 msgstr "" | |
2035 | |
2036 #. type: Content of: <book><chapter><sect1><sect2><para> | |
2037 #: ../en/ch01-intro.xml:384 | |
2038 msgid "" | |
2039 "If you have an employee in the field, troubleshooting a problem at a " | |
2040 "customer's site, they'll benefit from distributed revision control. The tool " | |
2041 "will let them generate custom builds, try different fixes in isolation from " | |
2042 "each other, and search efficiently through history for the sources of bugs " | |
2043 "and regressions in the customer's environment, all without needing to connect " | |
2044 "to your company's network." | |
2045 msgstr "" | |
2046 | |
2047 #. type: Content of: <book><chapter><sect1><title> | |
2048 #: ../en/ch01-intro.xml:395 | |
2049 msgid "Why choose Mercurial?" | |
2050 msgstr "为什么选择 Mercurial?" | |
2051 | |
2052 #. type: Content of: <book><chapter><sect1><para> | |
2053 #: ../en/ch01-intro.xml:397 | |
2054 msgid "" | |
2055 "Mercurial has a unique set of properties that make it a particularly good " | |
2056 "choice as a revision control system." | |
2057 msgstr "" | |
2058 | |
2059 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
2060 #: ../en/ch01-intro.xml:400 | |
2061 msgid "It is easy to learn and use." | |
2062 msgstr "" | |
2063 | |
2064 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
2065 #: ../en/ch01-intro.xml:401 | |
2066 msgid "It is lightweight." | |
2067 msgstr "" | |
2068 | |
2069 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
2070 #: ../en/ch01-intro.xml:402 | |
2071 msgid "It scales excellently." | |
2072 msgstr "" | |
2073 | |
2074 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
2075 #: ../en/ch01-intro.xml:403 | |
2076 msgid "It is easy to customise." | |
2077 msgstr "" | |
2078 | |
2079 #. type: Content of: <book><chapter><sect1><para> | |
2080 #: ../en/ch01-intro.xml:406 | |
2081 msgid "" | |
2082 "If you are at all familiar with revision control systems, you should be able " | |
2083 "to get up and running with Mercurial in less than five minutes. Even if not, " | |
2084 "it will take no more than a few minutes longer. Mercurial's command and " | |
2085 "feature sets are generally uniform and consistent, so you can keep track of a " | |
2086 "few general rules instead of a host of exceptions." | |
2087 msgstr "" | |
2088 | |
2089 #. type: Content of: <book><chapter><sect1><para> | |
2090 #: ../en/ch01-intro.xml:413 | |
2091 msgid "" | |
2092 "On a small project, you can start working with Mercurial in moments. Creating " | |
2093 "new changes and branches; transferring changes around (whether locally or " | |
2094 "over a network); and history and status operations are all fast. Mercurial " | |
2095 "attempts to stay nimble and largely out of your way by combining low " | |
2096 "cognitive overhead with blazingly fast operations." | |
2097 msgstr "" | |
2098 | |
2099 #. type: Content of: <book><chapter><sect1><para> | |
2100 #: ../en/ch01-intro.xml:420 | |
2101 msgid "" | |
2102 "The usefulness of Mercurial is not limited to small projects: it is used by " | |
2103 "projects with hundreds to thousands of contributors, each containing tens of " | |
2104 "thousands of files and hundreds of megabytes of source code." | |
2105 msgstr "" | |
2106 | |
2107 #. type: Content of: <book><chapter><sect1><para> | |
2108 #: ../en/ch01-intro.xml:425 | |
2109 msgid "" | |
2110 "If the core functionality of Mercurial is not enough for you, it's easy to " | |
2111 "build on. Mercurial is well suited to scripting tasks, and its clean " | |
2112 "internals and implementation in Python make it easy to add features in the " | |
2113 "form of extensions. There are a number of popular and useful extensions " | |
2114 "already available, ranging from helping to identify bugs to improving " | |
2115 "performance." | |
2116 msgstr "" | |
2117 | |
2118 #. type: Content of: <book><chapter><sect1><title> | |
2119 #: ../en/ch01-intro.xml:435 | |
2120 msgid "Mercurial compared with other tools" | |
2121 msgstr "Mercurial 与其它工具的比较" | |
2122 | |
2123 #. type: Content of: <book><chapter><sect1><para> | |
2124 #: ../en/ch01-intro.xml:437 | |
2125 msgid "" | |
2126 "Before you read on, please understand that this section necessarily reflects " | |
2127 "my own experiences, interests, and (dare I say it) biases. I have used every " | |
2128 "one of the revision control tools listed below, in most cases for several " | |
2129 "years at a time." | |
2130 msgstr "" | |
2131 | |
2132 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
2133 #: ../en/ch01-intro.xml:445 ../en/ch01-intro.xml:656 | |
2134 msgid "Subversion" | |
2135 msgstr "" | |
2136 | |
2137 #. type: Content of: <book><chapter><sect1><sect2><para> | |
2138 #: ../en/ch01-intro.xml:447 | |
2139 msgid "" | |
2140 "Subversion is a popular revision control tool, developed to replace CVS. It " | |
2141 "has a centralised client/server architecture." | |
2142 msgstr "" | |
2143 | |
2144 #. type: Content of: <book><chapter><sect1><sect2><para> | |
2145 #: ../en/ch01-intro.xml:451 | |
2146 msgid "" | |
2147 "Subversion and Mercurial have similarly named commands for performing the " | |
2148 "same operations, so if you're familiar with one, it is easy to learn to use " | |
2149 "the other. Both tools are portable to all popular operating systems." | |
2150 msgstr "" | |
2151 | |
2152 #. type: Content of: <book><chapter><sect1><sect2><para> | |
2153 #: ../en/ch01-intro.xml:456 | |
2154 msgid "" | |
2155 "Prior to version 1.5, Subversion had no useful support for merges. At the " | |
2156 "time of writing, its merge tracking capability is new, and known to be <ulink " | |
2157 "url=\"http://svnbook.red-bean.com/nightly/en/svn.branchmerge.advanced." | |
2158 "html#svn.branchmerge.advanced.finalword\">complicated and buggy</ulink>." | |
2159 msgstr "" | |
2160 | |
2161 #. type: Content of: <book><chapter><sect1><sect2><para> | |
2162 #: ../en/ch01-intro.xml:462 | |
2163 msgid "" | |
2164 "Mercurial has a substantial performance advantage over Subversion on every " | |
2165 "revision control operation I have benchmarked. I have measured its advantage " | |
2166 "as ranging from a factor of two to a factor of six when compared with " | |
2167 "Subversion 1.4.3's <emphasis>ra_local</emphasis> file store, which is the " | |
2168 "fastest access method available. In more realistic deployments involving a " | |
2169 "network-based store, Subversion will be at a substantially larger " | |
2170 "disadvantage. Because many Subversion commands must talk to the server and " | |
2171 "Subversion does not have useful replication facilities, server capacity and " | |
2172 "network bandwidth become bottlenecks for modestly large projects." | |
2173 msgstr "" | |
2174 | |
2175 #. type: Content of: <book><chapter><sect1><sect2><para> | |
2176 #: ../en/ch01-intro.xml:475 | |
2177 msgid "" | |
2178 "Additionally, Subversion incurs substantial storage overhead to avoid network " | |
2179 "transactions for a few common operations, such as finding modified files " | |
2180 "(<literal>status</literal>) and displaying modifications against the current " | |
2181 "revision (<literal>diff</literal>). As a result, a Subversion working copy " | |
2182 "is often the same size as, or larger than, a Mercurial repository and working " | |
2183 "directory, even though the Mercurial repository contains a complete history " | |
2184 "of the project." | |
2185 msgstr "" | |
2186 | |
2187 #. type: Content of: <book><chapter><sect1><sect2><para> | |
2188 #: ../en/ch01-intro.xml:485 | |
2189 msgid "" | |
2190 "Subversion is widely supported by third party tools. Mercurial currently " | |
2191 "lags considerably in this area. This gap is closing, however, and indeed " | |
2192 "some of Mercurial's GUI tools now outshine their Subversion equivalents. " | |
2193 "Like Mercurial, Subversion has an excellent user manual." | |
2194 msgstr "" | |
2195 | |
2196 #. type: Content of: <book><chapter><sect1><sect2><para> | |
2197 #: ../en/ch01-intro.xml:491 | |
2198 msgid "" | |
2199 "Because Subversion doesn't store revision history on the client, it is well " | |
2200 "suited to managing projects that deal with lots of large, opaque binary " | |
2201 "files. If you check in fifty revisions to an incompressible 10MB file, " | |
2202 "Subversion's client-side space usage stays constant The space used by any " | |
2203 "distributed SCM will grow rapidly in proportion to the number of revisions, " | |
2204 "because the differences between each revision are large." | |
2205 msgstr "" | |
2206 | |
2207 #. type: Content of: <book><chapter><sect1><sect2><para> | |
2208 #: ../en/ch01-intro.xml:500 | |
2209 msgid "" | |
2210 "In addition, it's often difficult or, more usually, impossible to merge " | |
2211 "different versions of a binary file. Subversion's ability to let a user lock " | |
2212 "a file, so that they temporarily have the exclusive right to commit changes " | |
2213 "to it, can be a significant advantage to a project where binary files are " | |
2214 "widely used." | |
2215 msgstr "" | |
2216 | |
2217 #. type: Content of: <book><chapter><sect1><sect2><para> | |
2218 #: ../en/ch01-intro.xml:507 | |
2219 msgid "" | |
2220 "Mercurial can import revision history from a Subversion repository. It can " | |
2221 "also export revision history to a Subversion repository. This makes it easy " | |
2222 "to <quote>test the waters</quote> and use Mercurial and Subversion in " | |
2223 "parallel before deciding to switch. History conversion is incremental, so " | |
2224 "you can perform an initial conversion, then small additional conversions " | |
2225 "afterwards to bring in new changes." | |
2226 msgstr "" | |
2227 | |
2228 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
2229 #: ../en/ch01-intro.xml:519 ../en/ch01-intro.xml:658 | |
2230 msgid "Git" | |
2231 msgstr "" | |
2232 | |
2233 #. type: Content of: <book><chapter><sect1><sect2><para> | |
2234 #: ../en/ch01-intro.xml:521 | |
2235 msgid "" | |
2236 "Git is a distributed revision control tool that was developed for managing " | |
2237 "the Linux kernel source tree. Like Mercurial, its early design was somewhat " | |
2238 "influenced by Monotone." | |
2239 msgstr "" | |
2240 | |
2241 #. type: Content of: <book><chapter><sect1><sect2><para> | |
2242 #: ../en/ch01-intro.xml:526 | |
2243 msgid "" | |
2244 "Git has a very large command set, with version 1.5.0 providing 139 individual " | |
2245 "commands. It has something of a reputation for being difficult to learn. " | |
2246 "Compared to Git, Mercurial has a strong focus on simplicity." | |
2247 msgstr "" | |
2248 | |
2249 #. type: Content of: <book><chapter><sect1><sect2><para> | |
2250 #: ../en/ch01-intro.xml:531 | |
2251 msgid "" | |
2252 "In terms of performance, Git is extremely fast. In several cases, it is " | |
2253 "faster than Mercurial, at least on Linux, while Mercurial performs better on " | |
2254 "other operations. However, on Windows, the performance and general level of " | |
2255 "support that Git provides is, at the time of writing, far behind that of " | |
2256 "Mercurial." | |
2257 msgstr "" | |
2258 | |
2259 #. type: Content of: <book><chapter><sect1><sect2><para> | |
2260 #: ../en/ch01-intro.xml:538 | |
2261 msgid "" | |
2262 "While a Mercurial repository needs no maintenance, a Git repository requires " | |
2263 "frequent manual <quote>repacks</quote> of its metadata. Without these, " | |
2264 "performance degrades, while space usage grows rapidly. A server that " | |
2265 "contains many Git repositories that are not rigorously and frequently " | |
2266 "repacked will become heavily disk-bound during backups, and there have been " | |
2267 "instances of daily backups taking far longer than 24 hours as a result. A " | |
2268 "freshly packed Git repository is slightly smaller than a Mercurial " | |
2269 "repository, but an unpacked repository is several orders of magnitude larger." | |
2270 msgstr "" | |
2271 | |
2272 #. type: Content of: <book><chapter><sect1><sect2><para> | |
2273 #: ../en/ch01-intro.xml:549 | |
2274 msgid "" | |
2275 "The core of Git is written in C. Many Git commands are implemented as shell " | |
2276 "or Perl scripts, and the quality of these scripts varies widely. I have " | |
2277 "encountered several instances where scripts charged along blindly in the " | |
2278 "presence of errors that should have been fatal." | |
2279 msgstr "" | |
2280 | |
2281 #. type: Content of: <book><chapter><sect1><sect2><para> | |
2282 #: ../en/ch01-intro.xml:555 | |
2283 msgid "Mercurial can import revision history from a Git repository." | |
2284 msgstr "" | |
2285 | |
2286 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
2287 #: ../en/ch01-intro.xml:561 ../en/ch01-intro.xml:657 | |
2288 msgid "CVS" | |
2289 msgstr "" | |
2290 | |
2291 #. type: Content of: <book><chapter><sect1><sect2><para> | |
2292 #: ../en/ch01-intro.xml:563 | |
2293 msgid "" | |
2294 "CVS is probably the most widely used revision control tool in the world. Due " | |
2295 "to its age and internal untidiness, it has been only lightly maintained for " | |
2296 "many years." | |
2297 msgstr "" | |
2298 | |
2299 #. type: Content of: <book><chapter><sect1><sect2><para> | |
2300 #: ../en/ch01-intro.xml:567 | |
2301 msgid "" | |
2302 "It has a centralised client/server architecture. It does not group related " | |
2303 "file changes into atomic commits, making it easy for people to <quote>break " | |
2304 "the build</quote>: one person can successfully commit part of a change and " | |
2305 "then be blocked by the need for a merge, causing other people to see only a " | |
2306 "portion of the work they intended to do. This also affects how you work with " | |
2307 "project history. If you want to see all of the modifications someone made as " | |
2308 "part of a task, you will need to manually inspect the descriptions and " | |
2309 "timestamps of the changes made to each file involved (if you even know what " | |
2310 "those files were)." | |
2311 msgstr "" | |
2312 | |
2313 #. type: Content of: <book><chapter><sect1><sect2><para> | |
2314 #: ../en/ch01-intro.xml:579 | |
2315 msgid "" | |
2316 "CVS has a muddled notion of tags and branches that I will not attempt to even " | |
2317 "describe. It does not support renaming of files or directories well, making " | |
2318 "it easy to corrupt a repository. It has almost no internal consistency " | |
2319 "checking capabilities, so it is usually not even possible to tell whether or " | |
2320 "how a repository is corrupt. I would not recommend CVS for any project, " | |
2321 "existing or new." | |
2322 msgstr "" | |
2323 | |
2324 #. type: Content of: <book><chapter><sect1><sect2><para> | |
2325 #: ../en/ch01-intro.xml:587 | |
2326 msgid "" | |
2327 "Mercurial can import CVS revision history. However, there are a few caveats " | |
2328 "that apply; these are true of every other revision control tool's CVS " | |
2329 "importer, too. Due to CVS's lack of atomic changes and unversioned " | |
2330 "filesystem hierarchy, it is not possible to reconstruct CVS history " | |
2331 "completely accurately; some guesswork is involved, and renames will usually " | |
2332 "not show up. Because a lot of advanced CVS administration has to be done by " | |
2333 "hand and is hence error-prone, it's common for CVS importers to run into " | |
2334 "multiple problems with corrupted repositories (completely bogus revision " | |
2335 "timestamps and files that have remained locked for over a decade are just two " | |
2336 "of the less interesting problems I can recall from personal experience)." | |
2337 msgstr "" | |
2338 | |
2339 #. type: Content of: <book><chapter><sect1><sect2><para> | |
2340 #: ../en/ch01-intro.xml:601 | |
2341 msgid "Mercurial can import revision history from a CVS repository." | |
2342 msgstr "" | |
2343 | |
2344 #. type: Content of: <book><chapter><sect1><sect2><title> | |
2345 #: ../en/ch01-intro.xml:607 | |
2346 msgid "Commercial tools" | |
2347 msgstr "商业工具" | |
2348 | |
2349 #. type: Content of: <book><chapter><sect1><sect2><para> | |
2350 #: ../en/ch01-intro.xml:609 | |
2351 msgid "" | |
2352 "Perforce has a centralised client/server architecture, with no client-side " | |
2353 "caching of any data. Unlike modern revision control tools, Perforce requires " | |
2354 "that a user run a command to inform the server about every file they intend " | |
2355 "to edit." | |
2356 msgstr "" | |
2357 | |
2358 #. type: Content of: <book><chapter><sect1><sect2><para> | |
2359 #: ../en/ch01-intro.xml:615 | |
2360 msgid "" | |
2361 "The performance of Perforce is quite good for small teams, but it falls off " | |
2362 "rapidly as the number of users grows beyond a few dozen. Modestly large " | |
2363 "Perforce installations require the deployment of proxies to cope with the " | |
2364 "load their users generate." | |
2365 msgstr "" | |
2366 | |
2367 #. type: Content of: <book><chapter><sect1><sect2><title> | |
2368 #: ../en/ch01-intro.xml:624 | |
2369 msgid "Choosing a revision control tool" | |
2370 msgstr "选择版本控制工具" | |
2371 | |
2372 #. type: Content of: <book><chapter><sect1><sect2><para> | |
2373 #: ../en/ch01-intro.xml:626 | |
2374 msgid "" | |
2375 "With the exception of CVS, all of the tools listed above have unique " | |
2376 "strengths that suit them to particular styles of work. There is no single " | |
2377 "revision control tool that is best in all situations." | |
2378 msgstr "" | |
2379 | |
2380 #. type: Content of: <book><chapter><sect1><sect2><para> | |
2381 #: ../en/ch01-intro.xml:631 | |
2382 msgid "" | |
2383 "As an example, Subversion is a good choice for working with frequently edited " | |
2384 "binary files, due to its centralised nature and support for file locking." | |
2385 msgstr "" | |
2386 | |
2387 #. type: Content of: <book><chapter><sect1><sect2><para> | |
2388 #: ../en/ch01-intro.xml:635 | |
2389 msgid "" | |
2390 "I personally find Mercurial's properties of simplicity, performance, and good " | |
2391 "merge support to be a compelling combination that has served me well for " | |
2392 "several years." | |
2393 msgstr "" | |
2394 | |
2395 #. type: Content of: <book><chapter><sect1><title> | |
2396 #: ../en/ch01-intro.xml:643 | |
2397 msgid "Switching from another tool to Mercurial" | |
2398 msgstr "从其它工具切换到 Mercurial" | |
2399 | |
2400 #. type: Content of: <book><chapter><sect1><para> | |
2401 #: ../en/ch01-intro.xml:645 | |
2402 msgid "" | |
2403 "Mercurial is bundled with an extension named <literal role=\"hg-ext" | |
2404 "\">convert</literal>, which can incrementally import revision history from " | |
2405 "several other revision control tools. By <quote>incremental</quote>, I mean " | |
2406 "that you can convert all of a project's history to date in one go, then rerun " | |
2407 "the conversion later to obtain new changes that happened after the initial " | |
2408 "conversion." | |
2409 msgstr "" | |
2410 | |
2411 #. type: Content of: <book><chapter><sect1><para> | |
2412 #: ../en/ch01-intro.xml:653 | |
2413 msgid "" | |
2414 "The revision control tools supported by <literal role=\"hg-ext\">convert</" | |
2415 "literal> are as follows:" | |
2416 msgstr "" | |
2417 | |
2418 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
2419 #: ../en/ch01-intro.xml:659 | |
2420 msgid "Darcs" | |
2421 msgstr "" | |
2422 | |
2423 #. type: Content of: <book><chapter><sect1><para> | |
2424 #: ../en/ch01-intro.xml:661 | |
2425 msgid "" | |
2426 "In addition, <literal role=\"hg-ext\">convert</literal> can export changes " | |
2427 "from Mercurial to Subversion. This makes it possible to try Subversion and " | |
2428 "Mercurial in parallel before committing to a switchover, without risking the " | |
2429 "loss of any work." | |
2430 msgstr "" | |
2431 | |
2432 #. type: Content of: <book><chapter><sect1><para> | |
2433 #: ../en/ch01-intro.xml:667 | |
2434 msgid "" | |
2435 "The <command role=\"hg-ext-conver\">convert</command> command is easy to " | |
2436 "use. Simply point it at the path or URL of the source repository, optionally " | |
2437 "give it the name of the destination repository, and it will start working. " | |
2438 "After the initial conversion, just run the same command again to import new " | |
2439 "changes." | |
2440 msgstr "" | |
2441 | |
2442 #. type: Content of: <book><chapter><title> | |
2443 #: ../en/ch02-tour-basic.xml:5 | |
2444 msgid "A tour of Mercurial: the basics" | |
2445 msgstr "Mercurial 教程: 基础知识" | |
2446 | |
2447 #. type: Content of: <book><chapter><sect1><title> | |
2448 #: ../en/ch02-tour-basic.xml:8 | |
2449 msgid "Installing Mercurial on your system" | |
2450 msgstr "安装 Mercurial" | |
2451 | |
2452 #. type: Content of: <book><chapter><sect1><para> | |
2453 #: ../en/ch02-tour-basic.xml:10 | |
2454 msgid "" | |
2455 "Prebuilt binary packages of Mercurial are available for every popular " | |
2456 "operating system. These make it easy to start using Mercurial on your " | |
2457 "computer immediately." | |
2458 msgstr "" | |
2459 | |
2460 #. type: Content of: <book><chapter><sect1><sect2><title> | |
2461 #: ../en/ch02-tour-basic.xml:15 | |
2462 msgid "Linux" | |
2463 msgstr "" | |
2464 | |
2465 #. type: Content of: <book><chapter><sect1><sect2><para> | |
2466 #: ../en/ch02-tour-basic.xml:17 | |
2467 msgid "" | |
2468 "Because each Linux distribution has its own packaging tools, policies, and " | |
2469 "rate of development, it's difficult to give a comprehensive set of " | |
2470 "instructions on how to install Mercurial binaries. The version of Mercurial " | |
2471 "that you will end up with can vary depending on how active the person is who " | |
2472 "maintains the package for your distribution." | |
2473 msgstr "" | |
2474 | |
2475 #. type: Content of: <book><chapter><sect1><sect2><para> | |
2476 #: ../en/ch02-tour-basic.xml:24 | |
2477 msgid "" | |
2478 "To keep things simple, I will focus on installing Mercurial from the command " | |
2479 "line under the most popular Linux distributions. Most of these distributions " | |
2480 "provide graphical package managers that will let you install Mercurial with a " | |
2481 "single click; the package name to look for is <literal>mercurial</literal>." | |
2482 msgstr "" | |
2483 | |
2484 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
2485 #: ../en/ch02-tour-basic.xml:32 | |
2486 msgid "Debian:" | |
2487 msgstr "" | |
2488 | |
2489 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
2490 #: ../en/ch02-tour-basic.xml:35 | |
2491 msgid "Fedora Core:" | |
2492 msgstr "" | |
2493 | |
2494 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
2495 #: ../en/ch02-tour-basic.xml:38 | |
2496 msgid "Gentoo:" | |
2497 msgstr "" | |
2498 | |
2499 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
2500 #: ../en/ch02-tour-basic.xml:40 | |
2501 msgid "OpenSUSE:" | |
2502 msgstr "" | |
2503 | |
2504 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
2505 #: ../en/ch02-tour-basic.xml:43 | |
2506 msgid "" | |
2507 "Ubuntu: Ubuntu's Mercurial package is based on Debian's. To install it, run " | |
2508 "the following command." | |
2509 msgstr "" | |
2510 | |
2511 #. type: Content of: <book><chapter><sect1><sect2><title> | |
2512 #: ../en/ch02-tour-basic.xml:52 | |
2513 msgid "Solaris" | |
2514 msgstr "" | |
2515 | |
2516 #. type: Content of: <book><chapter><sect1><sect2><para> | |
2517 #: ../en/ch02-tour-basic.xml:54 | |
2518 msgid "" | |
2519 "SunFreeWare, at <ulink url=\"http://www.sunfreeware.com\">http://www." | |
2520 "sunfreeware.com</ulink>, is a good source for a large number of pre-built " | |
2521 "Solaris packages for 32 and 64 bit Intel and Sparc architectures, including " | |
2522 "current versions of Mercurial." | |
2523 msgstr "" | |
2524 | |
2525 #. type: Content of: <book><chapter><sect1><sect2><title> | |
2526 #: ../en/ch02-tour-basic.xml:62 | |
2527 msgid "Mac OS X" | |
2528 msgstr "" | |
2529 | |
2530 #. type: Content of: <book><chapter><sect1><sect2><para> | |
2531 #: ../en/ch02-tour-basic.xml:64 | |
2532 msgid "" | |
2533 "Lee Cantey publishes an installer of Mercurial for Mac OS X at <ulink url=" | |
2534 "\"http://mercurial.berkwood.com\">http://mercurial.berkwood.com</ulink>. " | |
2535 "This package works on both Intel- and Power-based Macs. Before you can use " | |
2536 "it, you must install a compatible version of Universal MacPython " | |
2537 "<citation>web:macpython</citation>. This is easy to do; simply follow the " | |
2538 "instructions on Lee's site." | |
2539 msgstr "" | |
2540 | |
2541 #. type: Content of: <book><chapter><sect1><sect2><para> | |
2542 #: ../en/ch02-tour-basic.xml:73 | |
2543 msgid "" | |
2544 "It's also possible to install Mercurial using Fink or MacPorts, two popular " | |
2545 "free package managers for Mac OS X. If you have Fink, use <command>sudo apt-" | |
2546 "get install mercurial-py25</command>. If MacPorts, <command>sudo port " | |
2547 "install mercurial</command>." | |
2548 msgstr "" | |
2549 | |
2550 #. type: Content of: <book><chapter><sect1><sect2><title> | |
2551 #: ../en/ch02-tour-basic.xml:81 | |
2552 msgid "Windows" | |
2553 msgstr "" | |
2554 | |
2555 #. type: Content of: <book><chapter><sect1><sect2><para> | |
2556 #: ../en/ch02-tour-basic.xml:83 | |
2557 msgid "" | |
2558 "Lee Cantey publishes an installer of Mercurial for Windows at <ulink url=" | |
2559 "\"http://mercurial.berkwood.com\">http://mercurial.berkwood.com</ulink>. " | |
2560 "This package has no external dependencies; it <quote>just works</quote>." | |
2561 msgstr "" | |
2562 | |
2563 #. type: Content of: <book><chapter><sect1><sect2><note><para> | |
2564 #: ../en/ch02-tour-basic.xml:90 | |
2565 msgid "" | |
2566 "The Windows version of Mercurial does not automatically convert line endings " | |
2567 "between Windows and Unix styles. If you want to share work with Unix users, " | |
2568 "you must do a little additional configuration work. XXX Flesh this out." | |
2569 msgstr "" | |
2570 | |
2571 #. type: Content of: <book><chapter><sect1><title> | |
2572 #: ../en/ch02-tour-basic.xml:100 | |
2573 msgid "Getting started" | |
2574 msgstr "开始" | |
2575 | |
2576 #. type: Content of: <book><chapter><sect1><para> | |
2577 #: ../en/ch02-tour-basic.xml:102 | |
2578 msgid "" | |
2579 "To begin, we'll use the <command role=\"hg-cmd\">hg version</command> command " | |
2580 "to find out whether Mercurial is actually installed properly. The actual " | |
2581 "version information that it prints isn't so important; it's whether it prints " | |
2582 "anything at all that we care about." | |
2583 msgstr "" | |
2584 | |
2585 #. type: Content of: <book><chapter><sect1><sect2><title> | |
2586 #: ../en/ch02-tour-basic.xml:111 | |
2587 msgid "Built-in help" | |
2588 msgstr "内置帮助" | |
2589 | |
2590 #. type: Content of: <book><chapter><sect1><sect2><para> | |
2591 #: ../en/ch02-tour-basic.xml:113 | |
2592 msgid "" | |
2593 "Mercurial provides a built-in help system. This is invaluable for those " | |
2594 "times when you find yourself stuck trying to remember how to run a command. " | |
2595 "If you are completely stuck, simply run <command role=\"hg-cmd\">hg help</" | |
2596 "command>; it will print a brief list of commands, along with a description of " | |
2597 "what each does. If you ask for help on a specific command (as below), it " | |
2598 "prints more detailed information." | |
2599 msgstr "" | |
2600 | |
2601 #. type: Content of: <book><chapter><sect1><sect2><para> | |
2602 #: ../en/ch02-tour-basic.xml:124 | |
2603 msgid "" | |
2604 "For a more impressive level of detail (which you won't usually need) run " | |
2605 "<command role=\"hg-cmd\">hg help <option role=\"hg-opt-global\">-v</option></" | |
2606 "command>. The <option role=\"hg-opt-global\">-v</option> option is short for " | |
2607 "<option role=\"hg-opt-global\">--verbose</option>, and tells Mercurial to " | |
2608 "print more information than it usually would." | |
2609 msgstr "" | |
2610 | |
2611 #. type: Content of: <book><chapter><sect1><title> | |
2612 #: ../en/ch02-tour-basic.xml:135 | |
2613 msgid "Working with a repository" | |
2614 msgstr "使用版本库" | |
2615 | |
2616 #. type: Content of: <book><chapter><sect1><para> | |
2617 #: ../en/ch02-tour-basic.xml:137 | |
2618 msgid "" | |
2619 "In Mercurial, everything happens inside a <emphasis>repository</emphasis>. " | |
2620 "The repository for a project contains all of the files that <quote>belong to</" | |
2621 "quote> that project, along with a historical record of the project's files." | |
2622 msgstr "" | |
2623 | |
2624 #. type: Content of: <book><chapter><sect1><para> | |
2625 #: ../en/ch02-tour-basic.xml:143 | |
2626 msgid "" | |
2627 "There's nothing particularly magical about a repository; it is simply a " | |
2628 "directory tree in your filesystem that Mercurial treats as special. You can " | |
2629 "rename or delete a repository any time you like, using either the command " | |
2630 "line or your file browser." | |
2631 msgstr "" | |
2632 | |
2633 #. type: Content of: <book><chapter><sect1><sect2><title> | |
2634 #: ../en/ch02-tour-basic.xml:150 | |
2635 msgid "Making a local copy of a repository" | |
2636 msgstr "创建版本库的工作副本" | |
2637 | |
2638 #. type: Content of: <book><chapter><sect1><sect2><para> | |
2639 #: ../en/ch02-tour-basic.xml:152 | |
2640 msgid "" | |
2641 "<emphasis>Copying</emphasis> a repository is just a little bit special. " | |
2642 "While you could use a normal file copying command to make a copy of a " | |
2643 "repository, it's best to use a built-in command that Mercurial provides. " | |
2644 "This command is called <command role=\"hg-cmd\">hg clone</command>, because " | |
2645 "it creates an identical copy of an existing repository." | |
2646 msgstr "" | |
2647 | |
2648 #. type: Content of: <book><chapter><sect1><sect2><para> | |
2649 #: ../en/ch02-tour-basic.xml:161 | |
2650 msgid "" | |
2651 "If our clone succeeded, we should now have a local directory called <filename " | |
2652 "class=\"directory\">hello</filename>. This directory will contain some files." | |
2653 msgstr "" | |
2654 | |
2655 #. type: Content of: <book><chapter><sect1><sect2><para> | |
2656 #: ../en/ch02-tour-basic.xml:167 | |
2657 msgid "" | |
2658 "These files have the same contents and history in our repository as they do " | |
2659 "in the repository we cloned." | |
2660 msgstr "" | |
2661 | |
2662 #. type: Content of: <book><chapter><sect1><sect2><para> | |
2663 #: ../en/ch02-tour-basic.xml:170 | |
2664 msgid "" | |
2665 "Every Mercurial repository is complete, self-contained, and independent. It " | |
2666 "contains its own private copy of a project's files and history. A cloned " | |
2667 "repository remembers the location of the repository it was cloned from, but " | |
2668 "it does not communicate with that repository, or any other, unless you tell " | |
2669 "it to." | |
2670 msgstr "" | |
2671 | |
2672 #. type: Content of: <book><chapter><sect1><sect2><para> | |
2673 #: ../en/ch02-tour-basic.xml:177 | |
2674 msgid "" | |
2675 "What this means for now is that we're free to experiment with our repository, " | |
2676 "safe in the knowledge that it's a private <quote>sandbox</quote> that won't " | |
2677 "affect anyone else." | |
2678 msgstr "" | |
2679 | |
2680 #. type: Content of: <book><chapter><sect1><sect2><title> | |
2681 #: ../en/ch02-tour-basic.xml:183 | |
2682 msgid "What's in a repository?" | |
2683 msgstr "什么是版本库?" | |
2684 | |
2685 #. type: Content of: <book><chapter><sect1><sect2><para> | |
2686 #: ../en/ch02-tour-basic.xml:185 | |
2687 msgid "" | |
2688 "When we take a more detailed look inside a repository, we can see that it " | |
2689 "contains a directory named <filename class=\"directory\">.hg</filename>. " | |
2690 "This is where Mercurial keeps all of its metadata for the repository." | |
2691 msgstr "" | |
2692 | |
2693 #. type: Content of: <book><chapter><sect1><sect2><para> | |
2694 #: ../en/ch02-tour-basic.xml:192 | |
2695 msgid "" | |
2696 "The contents of the <filename class=\"directory\">.hg</filename> directory " | |
2697 "and its subdirectories are private to Mercurial. Every other file and " | |
2698 "directory in the repository is yours to do with as you please." | |
2699 msgstr "" | |
2700 | |
2701 #. type: Content of: <book><chapter><sect1><sect2><para> | |
2702 #: ../en/ch02-tour-basic.xml:198 | |
2703 msgid "" | |
2704 "To introduce a little terminology, the <filename class=\"directory\">.hg</" | |
2705 "filename> directory is the <quote>real</quote> repository, and all of the " | |
2706 "files and directories that coexist with it are said to live in the " | |
2707 "<emphasis>working directory</emphasis>. An easy way to remember the " | |
2708 "distinction is that the <emphasis>repository</emphasis> contains the " | |
2709 "<emphasis>history</emphasis> of your project, while the <emphasis>working " | |
2710 "directory</emphasis> contains a <emphasis>snapshot</emphasis> of your project " | |
2711 "at a particular point in history." | |
2712 msgstr "" | |
2713 | |
2714 #. type: Content of: <book><chapter><sect1><title> | |
2715 #: ../en/ch02-tour-basic.xml:213 | |
2716 msgid "A tour through history" | |
2717 msgstr "回溯历史" | |
2718 | |
2719 #. type: Content of: <book><chapter><sect1><para> | |
2720 #: ../en/ch02-tour-basic.xml:215 | |
2721 msgid "" | |
2722 "One of the first things we might want to do with a new, unfamiliar repository " | |
2723 "is understand its history. The <command role=\"hg-cmd\">hg log</command> " | |
2724 "command gives us a view of history." | |
2725 msgstr "" | |
2726 | |
2727 #. type: Content of: <book><chapter><sect1><para> | |
2728 #: ../en/ch02-tour-basic.xml:222 | |
2729 msgid "" | |
2730 "By default, this command prints a brief paragraph of output for each change " | |
2731 "to the project that was recorded. In Mercurial terminology, we call each of " | |
2732 "these recorded events a <emphasis>changeset</emphasis>, because it can " | |
2733 "contain a record of changes to several files." | |
2734 msgstr "" | |
2735 | |
2736 #. type: Content of: <book><chapter><sect1><para> | |
2737 #: ../en/ch02-tour-basic.xml:228 | |
2738 msgid "" | |
2739 "The fields in a record of output from <command role=\"hg-cmd\">hg log</" | |
2740 "command> are as follows." | |
2741 msgstr "" | |
2742 | |
2743 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
2744 #: ../en/ch02-tour-basic.xml:231 | |
2745 msgid "" | |
2746 "<literal>changeset</literal>: This field has the format of a number, followed " | |
2747 "by a colon, followed by a hexadecimal string. These are " | |
2748 "<emphasis>identifiers</emphasis> for the changeset. There are two " | |
2749 "identifiers because the number is shorter and easier to type than the hex " | |
2750 "string." | |
2751 msgstr "" | |
2752 | |
2753 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
2754 #: ../en/ch02-tour-basic.xml:237 | |
2755 msgid "" | |
2756 "<literal>user</literal>: The identity of the person who created the " | |
2757 "changeset. This is a free-form field, but it most often contains a person's " | |
2758 "name and email address." | |
2759 msgstr "" | |
2760 | |
2761 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
2762 #: ../en/ch02-tour-basic.xml:241 | |
2763 msgid "" | |
2764 "<literal>date</literal>: The date and time on which the changeset was " | |
2765 "created, and the timezone in which it was created. (The date and time are " | |
2766 "local to that timezone; they display what time and date it was for the person " | |
2767 "who created the changeset.)" | |
2768 msgstr "" | |
2769 | |
2770 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
2771 #: ../en/ch02-tour-basic.xml:246 | |
2772 msgid "" | |
2773 "<literal>summary</literal>: The first line of the text message that the " | |
2774 "creator of the changeset entered to describe the changeset." | |
2775 msgstr "" | |
2776 | |
2777 #. type: Content of: <book><chapter><sect1><para> | |
2778 #: ../en/ch02-tour-basic.xml:249 | |
2779 msgid "" | |
2780 "The default output printed by <command role=\"hg-cmd\">hg log</command> is " | |
2781 "purely a summary; it is missing a lot of detail." | |
2782 msgstr "" | |
2783 | |
2784 #. type: Content of: <book><chapter><sect1><para> | |
2785 #: ../en/ch02-tour-basic.xml:253 | |
2786 msgid "" | |
2787 "Figure <xref linkend=\"fig.tour-basic.history\"/> provides a graphical " | |
2788 "representation of the history of the <filename class=\"directory\">hello</" | |
2789 "filename> repository, to make it a little easier to see which direction " | |
2790 "history is <quote>flowing</quote> in. We'll be returning to this figure " | |
2791 "several times in this chapter and the chapter that follows." | |
2792 msgstr "" | |
2793 | |
2794 #. type: Content of: <book><chapter><sect1><informalfigure><mediaobject> | |
2795 #: ../en/ch02-tour-basic.xml:263 | |
2796 msgid "" | |
2797 "<imageobject><imagedata fileref=\"images/tour-history.png\"/></imageobject>" | |
2798 msgstr "" | |
2799 | |
2800 #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject><textobject><phrase> | |
2801 #: ../en/ch02-tour-basic.xml:264 ../en/ch03-tour-merge.xml:48 | |
2802 #: ../en/ch03-tour-merge.xml:76 ../en/ch03-tour-merge.xml:124 | |
2803 #: ../en/ch03-tour-merge.xml:181 ../en/ch03-tour-merge.xml:248 | |
2804 #: ../en/ch04-concepts.xml:54 ../en/ch04-concepts.xml:104 | |
2805 #: ../en/ch04-concepts.xml:189 ../en/ch04-concepts.xml:293 | |
2806 #: ../en/ch04-concepts.xml:342 ../en/ch04-concepts.xml:356 | |
2807 #: ../en/ch04-concepts.xml:396 ../en/ch04-concepts.xml:415 | |
2808 #: ../en/ch04-concepts.xml:456 ../en/ch06-collab.xml:275 | |
2809 #: ../en/ch09-undo.xml:363 ../en/ch09-undo.xml:411 ../en/ch09-undo.xml:476 | |
2810 #: ../en/ch09-undo.xml:516 ../en/ch12-mq.xml:408 | |
2811 msgid "XXX add text" | |
2812 msgstr "" | |
2813 | |
2814 #. type: Content of: <book><chapter><sect1><informalfigure><mediaobject><caption><para> | |
2815 #: ../en/ch02-tour-basic.xml:265 | |
2816 msgid "" | |
2817 "Graphical history of the <filename class=\"directory\">hello</filename> " | |
2818 "repository" | |
2819 msgstr "" | |
2820 | |
2821 #. type: Content of: <book><chapter><sect1><sect2><title> | |
2822 #: ../en/ch02-tour-basic.xml:272 | |
2823 msgid "Changesets, revisions, and talking to other people" | |
2824 msgstr "改变集,版本,与其它用户交互" | |
2825 | |
2826 #. type: Content of: <book><chapter><sect1><sect2><para> | |
2827 #: ../en/ch02-tour-basic.xml:275 | |
2828 msgid "" | |
2829 "As English is a notoriously sloppy language, and computer science has a " | |
2830 "hallowed history of terminological confusion (why use one term when four will " | |
2831 "do?), revision control has a variety of words and phrases that mean the same " | |
2832 "thing. If you are talking about Mercurial history with other people, you " | |
2833 "will find that the word <quote>changeset</quote> is often compressed to " | |
2834 "<quote>change</quote> or (when written) <quote>cset</quote>, and sometimes a " | |
2835 "changeset is referred to as a <quote>revision</quote> or a <quote>rev</quote>." | |
2836 msgstr "" | |
2837 | |
2838 #. type: Content of: <book><chapter><sect1><sect2><para> | |
2839 #: ../en/ch02-tour-basic.xml:285 | |
2840 msgid "" | |
2841 "While it doesn't matter what <emphasis>word</emphasis> you use to refer to " | |
2842 "the concept of <quote>a changeset</quote>, the <emphasis>identifier</" | |
2843 "emphasis> that you use to refer to <quote>a <emphasis>specific</emphasis> " | |
2844 "changeset</quote> is of great importance. Recall that the <literal>changeset</" | |
2845 "literal> field in the output from <command role=\"hg-cmd\">hg log</command> " | |
2846 "identifies a changeset using both a number and a hexadecimal string." | |
2847 msgstr "" | |
2848 | |
2849 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
2850 #: ../en/ch02-tour-basic.xml:294 | |
2851 msgid "" | |
2852 "The revision number is <emphasis>only valid in that repository</emphasis>," | |
2853 msgstr "" | |
2854 | |
2855 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
2856 #: ../en/ch02-tour-basic.xml:296 | |
2857 msgid "" | |
2858 "while the hex string is the <emphasis>permanent, unchanging identifier</" | |
2859 "emphasis> that will always identify that exact changeset in <emphasis>every</" | |
2860 "emphasis> copy of the repository." | |
2861 msgstr "" | |
2862 | |
2863 #. type: Content of: <book><chapter><sect1><sect2><para> | |
2864 #: ../en/ch02-tour-basic.xml:301 | |
2865 msgid "" | |
2866 "This distinction is important. If you send someone an email talking about " | |
2867 "<quote>revision 33</quote>, there's a high likelihood that their revision 33 " | |
2868 "will <emphasis>not be the same</emphasis> as yours. The reason for this is " | |
2869 "that a revision number depends on the order in which changes arrived in a " | |
2870 "repository, and there is no guarantee that the same changes will happen in " | |
2871 "the same order in different repositories. Three changes $a,b,c$ can easily " | |
2872 "appear in one repository as $0,1,2$, while in another as $1,0,2$." | |
2873 msgstr "" | |
2874 | |
2875 #. type: Content of: <book><chapter><sect1><sect2><para> | |
2876 #: ../en/ch02-tour-basic.xml:311 | |
2877 msgid "" | |
2878 "Mercurial uses revision numbers purely as a convenient shorthand. If you " | |
2879 "need to discuss a changeset with someone, or make a record of a changeset for " | |
2880 "some other reason (for example, in a bug report), use the hexadecimal " | |
2881 "identifier." | |
2882 msgstr "" | |
2883 | |
2884 #. type: Content of: <book><chapter><sect1><sect2><title> | |
2885 #: ../en/ch02-tour-basic.xml:319 | |
2886 msgid "Viewing specific revisions" | |
2887 msgstr "察看指定版本" | |
2888 | |
2889 #. type: Content of: <book><chapter><sect1><sect2><para> | |
2890 #: ../en/ch02-tour-basic.xml:321 | |
2891 msgid "" | |
2892 "To narrow the output of <command role=\"hg-cmd\">hg log</command> down to a " | |
2893 "single revision, use the <option role=\"hg-opt-log\">-r</option> (or <option " | |
2894 "role=\"hg-opt-log\">--rev</option>) option. You can use either a revision " | |
2895 "number or a long-form changeset identifier, and you can provide as many " | |
2896 "revisions as you want." | |
2897 msgstr "" | |
2898 | |
2899 #. type: Content of: <book><chapter><sect1><sect2><para> | |
2900 #: ../en/ch02-tour-basic.xml:330 | |
2901 msgid "" | |
2902 "If you want to see the history of several revisions without having to list " | |
2903 "each one, you can use <emphasis>range notation</emphasis>; this lets you " | |
2904 "express the idea <quote>I want all revisions between <literal>abc</literal> " | |
2905 "and <literal>def</literal>, inclusive</quote>." | |
2906 msgstr "" | |
2907 | |
2908 #. type: Content of: <book><chapter><sect1><sect2><para> | |
2909 #: ../en/ch02-tour-basic.xml:338 | |
2910 msgid "" | |
2911 "Mercurial also honours the order in which you specify revisions, so <command " | |
2912 "role=\"hg-cmd\">hg log -r 2:4</command> prints 2, 3, and 4. while <command " | |
2913 "role=\"hg-cmd\">hg log -r 4:2</command> prints 4, 3, and 2." | |
2914 msgstr "" | |
2915 | |
2916 #. type: Content of: <book><chapter><sect1><sect2><title> | |
2917 #: ../en/ch02-tour-basic.xml:345 | |
2918 msgid "More detailed information" | |
2919 msgstr "更详细的信息" | |
2920 | |
2921 #. type: Content of: <book><chapter><sect1><sect2><para> | |
2922 #: ../en/ch02-tour-basic.xml:347 | |
2923 msgid "" | |
2924 "While the summary information printed by <command role=\"hg-cmd\">hg log</" | |
2925 "command> is useful if you already know what you're looking for, you may need " | |
2926 "to see a complete description of the change, or a list of the files changed, " | |
2927 "if you're trying to decide whether a changeset is the one you're looking for. " | |
2928 "The <command role=\"hg-cmd\">hg log</command> command's <option role=\"hg-opt-" | |
2929 "global\">-v</option> (or <option role=\"hg-opt-global\">--verbose</option>) " | |
2930 "option gives you this extra detail." | |
2931 msgstr "" | |
2932 | |
2933 #. type: Content of: <book><chapter><sect1><sect2><para> | |
2934 #: ../en/ch02-tour-basic.xml:359 | |
2935 msgid "" | |
2936 "If you want to see both the description and content of a change, add the " | |
2937 "<option role=\"hg-opt-log\">-p</option> (or <option role=\"hg-opt-log\">--" | |
2938 "patch</option>) option. This displays the content of a change as a " | |
2939 "<emphasis>unified diff</emphasis> (if you've never seen a unified diff " | |
2940 "before, see section <xref linkend=\"sec.mq.patch\"/> for an overview)." | |
2941 msgstr "" | |
2942 | |
2943 #. type: Content of: <book><chapter><sect1><title> | |
2944 #: ../en/ch02-tour-basic.xml:372 | |
2945 msgid "All about command options" | |
2946 msgstr "命令选项" | |
2947 | |
2948 #. type: Content of: <book><chapter><sect1><para> | |
2949 #: ../en/ch02-tour-basic.xml:374 | |
2950 msgid "" | |
2951 "Let's take a brief break from exploring Mercurial commands to discuss a " | |
2952 "pattern in the way that they work; you may find this useful to keep in mind " | |
2953 "as we continue our tour." | |
2954 msgstr "" | |
2955 | |
2956 #. type: Content of: <book><chapter><sect1><para> | |
2957 #: ../en/ch02-tour-basic.xml:378 | |
2958 msgid "" | |
2959 "Mercurial has a consistent and straightforward approach to dealing with the " | |
2960 "options that you can pass to commands. It follows the conventions for " | |
2961 "options that are common to modern Linux and Unix systems." | |
2962 msgstr "" | |
2963 | |
2964 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
2965 #: ../en/ch02-tour-basic.xml:383 | |
2966 msgid "" | |
2967 "Every option has a long name. For example, as we've already seen, the " | |
2968 "<command role=\"hg-cmd\">hg log</command> command accepts a <option role=\"hg-" | |
2969 "opt-log\">--rev</option> option." | |
2970 msgstr "" | |
2971 | |
2972 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
2973 #: ../en/ch02-tour-basic.xml:387 | |
2974 msgid "" | |
2975 "Most options have short names, too. Instead of <option role=\"hg-opt-log\">--" | |
2976 "rev</option>, we can use <option role=\"hg-opt-log\">-r</option>. (The " | |
2977 "reason that some options don't have short names is that the options in " | |
2978 "question are rarely used.)" | |
2979 msgstr "" | |
2980 | |
2981 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
2982 #: ../en/ch02-tour-basic.xml:392 | |
2983 msgid "" | |
2984 "Long options start with two dashes (e.g. <option role=\"hg-opt-log\">--rev</" | |
2985 "option>), while short options start with one (e.g. <option role=\"hg-opt-log" | |
2986 "\">-r</option>)." | |
2987 msgstr "" | |
2988 | |
2989 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
2990 #: ../en/ch02-tour-basic.xml:396 | |
2991 msgid "" | |
2992 "Option naming and usage is consistent across commands. For example, every " | |
2993 "command that lets you specify a changeset ID or revision number accepts both " | |
2994 "<option role=\"hg-opt-log\">-r</option> and <option role=\"hg-opt-log\">--" | |
2995 "rev</option> arguments." | |
2996 msgstr "" | |
2997 | |
2998 #. type: Content of: <book><chapter><sect1><para> | |
2999 #: ../en/ch02-tour-basic.xml:402 | |
3000 msgid "" | |
3001 "In the examples throughout this book, I use short options instead of long. " | |
3002 "This just reflects my own preference, so don't read anything significant into " | |
3003 "it." | |
3004 msgstr "" | |
3005 | |
3006 #. type: Content of: <book><chapter><sect1><para> | |
3007 #: ../en/ch02-tour-basic.xml:406 | |
3008 msgid "" | |
3009 "Most commands that print output of some kind will print more output when " | |
3010 "passed a <option role=\"hg-opt-global\">-v</option> (or <option role=\"hg-opt-" | |
3011 "global\">--verbose</option>) option, and less when passed <option role=\"hg-" | |
3012 "opt-global\">-q</option> (or <option role=\"hg-opt-global\">--quiet</option>)." | |
3013 msgstr "" | |
3014 | |
3015 #. type: Content of: <book><chapter><sect1><title> | |
3016 #: ../en/ch02-tour-basic.xml:414 | |
3017 msgid "Making and reviewing changes" | |
3018 msgstr "创建和复审修改" | |
3019 | |
3020 #. type: Content of: <book><chapter><sect1><para> | |
3021 #: ../en/ch02-tour-basic.xml:416 | |
3022 msgid "" | |
3023 "Now that we have a grasp of viewing history in Mercurial, let's take a look " | |
3024 "at making some changes and examining them." | |
3025 msgstr "" | |
3026 | |
3027 #. type: Content of: <book><chapter><sect1><para> | |
3028 #: ../en/ch02-tour-basic.xml:420 | |
3029 msgid "" | |
3030 "The first thing we'll do is isolate our experiment in a repository of its " | |
3031 "own. We use the <command role=\"hg-cmd\">hg clone</command> command, but we " | |
3032 "don't need to clone a copy of the remote repository. Since we already have a " | |
3033 "copy of it locally, we can just clone that instead. This is much faster than " | |
3034 "cloning over the network, and cloning a local repository uses less disk space " | |
3035 "in most cases, too." | |
3036 msgstr "" | |
3037 | |
3038 #. type: Content of: <book><chapter><sect1><para> | |
3039 #: ../en/ch02-tour-basic.xml:430 | |
3040 msgid "" | |
3041 "As an aside, it's often good practice to keep a <quote>pristine</quote> copy " | |
3042 "of a remote repository around, which you can then make temporary clones of to " | |
3043 "create sandboxes for each task you want to work on. This lets you work on " | |
3044 "multiple tasks in parallel, each isolated from the others until it's complete " | |
3045 "and you're ready to integrate it back. Because local clones are so cheap, " | |
3046 "there's almost no overhead to cloning and destroying repositories whenever " | |
3047 "you want." | |
3048 msgstr "" | |
3049 | |
3050 #. type: Content of: <book><chapter><sect1><para> | |
3051 #: ../en/ch02-tour-basic.xml:439 | |
3052 msgid "" | |
3053 "In our <filename class=\"directory\">my-hello</filename> repository, we have " | |
3054 "a file <filename>hello.c</filename> that contains the classic <quote>hello, " | |
3055 "world</quote> program. Let's use the ancient and venerable <command>sed</" | |
3056 "command> command to edit this file so that it prints a second line of " | |
3057 "output. (I'm only using <command>sed</command> to do this because it's easy " | |
3058 "to write a scripted example this way. Since you're not under the same " | |
3059 "constraint, you probably won't want to use <command>sed</command>; simply use " | |
3060 "your preferred text editor to do the same thing.)" | |
3061 msgstr "" | |
3062 | |
3063 #. type: Content of: <book><chapter><sect1><para> | |
3064 #: ../en/ch02-tour-basic.xml:452 | |
3065 msgid "" | |
3066 "Mercurial's <command role=\"hg-cmd\">hg status</command> command will tell us " | |
3067 "what Mercurial knows about the files in the repository." | |
3068 msgstr "" | |
3069 | |
3070 #. type: Content of: <book><chapter><sect1><para> | |
3071 #: ../en/ch02-tour-basic.xml:458 | |
3072 msgid "" | |
3073 "The <command role=\"hg-cmd\">hg status</command> command prints no output for " | |
3074 "some files, but a line starting with <quote><literal>M</literal></quote> for " | |
3075 "<filename>hello.c</filename>. Unless you tell it to, <command role=\"hg-cmd" | |
3076 "\">hg status</command> will not print any output for files that have not been " | |
3077 "modified." | |
3078 msgstr "" | |
3079 | |
3080 #. type: Content of: <book><chapter><sect1><para> | |
3081 #: ../en/ch02-tour-basic.xml:465 | |
3082 msgid "" | |
3083 "The <quote><literal>M</literal></quote> indicates that Mercurial has noticed " | |
3084 "that we modified <filename>hello.c</filename>. We didn't need to " | |
3085 "<emphasis>inform</emphasis> Mercurial that we were going to modify the file " | |
3086 "before we started, or that we had modified the file after we were done; it " | |
3087 "was able to figure this out itself." | |
3088 msgstr "" | |
3089 | |
3090 #. type: Content of: <book><chapter><sect1><para> | |
3091 #: ../en/ch02-tour-basic.xml:473 | |
3092 msgid "" | |
3093 "It's a little bit helpful to know that we've modified <filename>hello.c</" | |
3094 "filename>, but we might prefer to know exactly <emphasis>what</emphasis> " | |
3095 "changes we've made to it. To do this, we use the <command role=\"hg-cmd\">hg " | |
3096 "diff</command> command." | |
3097 msgstr "" | |
3098 | |
3099 #. type: Content of: <book><chapter><sect1><title> | |
3100 #: ../en/ch02-tour-basic.xml:483 | |
3101 msgid "Recording changes in a new changeset" | |
3102 msgstr "在新修改集中记录修改" | |
3103 | |
3104 #. type: Content of: <book><chapter><sect1><para> | |
3105 #: ../en/ch02-tour-basic.xml:485 | |
3106 msgid "" | |
3107 "We can modify files, build and test our changes, and use <command role=\"hg-" | |
3108 "cmd\">hg status</command> and <command role=\"hg-cmd\">hg diff</command> to " | |
3109 "review our changes, until we're satisfied with what we've done and arrive at " | |
3110 "a natural stopping point where we want to record our work in a new changeset." | |
3111 msgstr "" | |
3112 | |
3113 #. type: Content of: <book><chapter><sect1><para> | |
3114 #: ../en/ch02-tour-basic.xml:492 | |
3115 msgid "" | |
3116 "The <command role=\"hg-cmd\">hg commit</command> command lets us create a new " | |
3117 "changeset; we'll usually refer to this as <quote>making a commit</quote> or " | |
3118 "<quote>committing</quote>." | |
3119 msgstr "" | |
3120 | |
3121 #. type: Content of: <book><chapter><sect1><sect2><title> | |
3122 #: ../en/ch02-tour-basic.xml:498 | |
3123 msgid "Setting up a username" | |
3124 msgstr "配置用户名称" | |
3125 | |
3126 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3127 #: ../en/ch02-tour-basic.xml:500 | |
3128 msgid "" | |
3129 "When you try to run <command role=\"hg-cmd\">hg commit</command> for the " | |
3130 "first time, it is not guaranteed to succeed. Mercurial records your name and " | |
3131 "address with each change that you commit, so that you and others will later " | |
3132 "be able to tell who made each change. Mercurial tries to automatically " | |
3133 "figure out a sensible username to commit the change with. It will attempt " | |
3134 "each of the following methods, in order:" | |
3135 msgstr "" | |
3136 | |
3137 #. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para> | |
3138 #: ../en/ch02-tour-basic.xml:509 | |
3139 msgid "" | |
3140 "If you specify a <option role=\"hg-opt-commit\">-u</option> option to the " | |
3141 "<command role=\"hg-cmd\">hg commit</command> command on the command line, " | |
3142 "followed by a username, this is always given the highest precedence." | |
3143 msgstr "" | |
3144 | |
3145 #. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para> | |
3146 #: ../en/ch02-tour-basic.xml:514 | |
3147 msgid "" | |
3148 "If you have set the <envar>HGUSER</envar> environment variable, this is " | |
3149 "checked next." | |
3150 msgstr "" | |
3151 | |
3152 #. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para> | |
3153 #: ../en/ch02-tour-basic.xml:517 | |
3154 msgid "" | |
3155 "If you create a file in your home directory called <filename role=\"special" | |
3156 "\">.hgrc</filename>, with a <envar role=\"rc-item-ui\">username</envar> " | |
3157 "entry, that will be used next. To see what the contents of this file should " | |
3158 "look like, refer to section <xref linkend=\"sec.tour-basic.username\"/> below." | |
3159 msgstr "" | |
3160 | |
3161 #. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para> | |
3162 #: ../en/ch02-tour-basic.xml:524 | |
3163 msgid "" | |
3164 "If you have set the <envar>EMAIL</envar> environment variable, this will be " | |
3165 "used next." | |
3166 msgstr "" | |
3167 | |
3168 #. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para> | |
3169 #: ../en/ch02-tour-basic.xml:527 | |
3170 msgid "" | |
3171 "Mercurial will query your system to find out your local user name and host " | |
3172 "name, and construct a username from these components. Since this often " | |
3173 "results in a username that is not very useful, it will print a warning if it " | |
3174 "has to do this." | |
3175 msgstr "" | |
3176 | |
3177 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3178 #: ../en/ch02-tour-basic.xml:534 | |
3179 msgid "" | |
3180 "If all of these mechanisms fail, Mercurial will fail, printing an error " | |
3181 "message. In this case, it will not let you commit until you set up a " | |
3182 "username." | |
3183 msgstr "" | |
3184 | |
3185 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3186 #: ../en/ch02-tour-basic.xml:538 | |
3187 msgid "" | |
3188 "You should think of the <envar>HGUSER</envar> environment variable and the " | |
3189 "<option role=\"hg-opt-commit\">-u</option> option to the <command role=\"hg-" | |
3190 "cmd\">hg commit</command> command as ways to <emphasis>override</emphasis> " | |
3191 "Mercurial's default selection of username. For normal use, the simplest and " | |
3192 "most robust way to set a username for yourself is by creating a <filename " | |
3193 "role=\"special\">.hgrc</filename> file; see below for details." | |
3194 msgstr "" | |
3195 | |
3196 #. type: Content of: <book><chapter><sect1><sect2><sect3><title> | |
3197 #: ../en/ch02-tour-basic.xml:547 | |
3198 msgid "Creating a Mercurial configuration file" | |
3199 msgstr "创建 Mercurial 的配置文件" | |
3200 | |
3201 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
3202 #: ../en/ch02-tour-basic.xml:549 | |
3203 msgid "" | |
3204 "To set a user name, use your favourite editor to create a file called " | |
3205 "<filename role=\"special\">.hgrc</filename> in your home directory. " | |
3206 "Mercurial will use this file to look up your personalised configuration " | |
3207 "settings. The initial contents of your <filename role=\"special\">.hgrc</" | |
3208 "filename> should look like this." | |
3209 msgstr "" | |
3210 | |
3211 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
3212 #: ../en/ch02-tour-basic.xml:560 | |
3213 msgid "" | |
3214 "The <quote><literal>[ui]</literal></quote> line begins a <emphasis>section</" | |
3215 "emphasis> of the config file, so you can read the <quote><literal>username " | |
3216 "= ...</literal></quote> line as meaning <quote>set the value of the " | |
3217 "<literal>username</literal> item in the <literal>ui</literal> section</" | |
3218 "quote>. A section continues until a new section begins, or the end of the " | |
3219 "file. Mercurial ignores empty lines and treats any text from " | |
3220 "<quote><literal>#</literal></quote> to the end of a line as a comment." | |
3221 msgstr "" | |
3222 | |
3223 #. type: Content of: <book><chapter><sect1><sect2><sect3><title> | |
3224 #: ../en/ch02-tour-basic.xml:573 | |
3225 msgid "Choosing a user name" | |
3226 msgstr "选择用户名称" | |
3227 | |
3228 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
3229 #: ../en/ch02-tour-basic.xml:575 | |
3230 msgid "" | |
3231 "You can use any text you like as the value of the <literal>username</literal> " | |
3232 "config item, since this information is for reading by other people, but for " | |
3233 "interpreting by Mercurial. The convention that most people follow is to use " | |
3234 "their name and email address, as in the example above." | |
3235 msgstr "" | |
3236 | |
3237 #. type: Content of: <book><chapter><sect1><sect2><sect3><note><para> | |
3238 #: ../en/ch02-tour-basic.xml:582 | |
3239 msgid "" | |
3240 "Mercurial's built-in web server obfuscates email addresses, to make it more " | |
3241 "difficult for the email harvesting tools that spammers use. This reduces the " | |
3242 "likelihood that you'll start receiving more junk email if you publish a " | |
3243 "Mercurial repository on the web." | |
3244 msgstr "" | |
3245 | |
3246 #. type: Content of: <book><chapter><sect1><sect2><title> | |
3247 #: ../en/ch02-tour-basic.xml:592 | |
3248 msgid "Writing a commit message" | |
3249 msgstr "写提交日志" | |
3250 | |
3251 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3252 #: ../en/ch02-tour-basic.xml:594 | |
3253 msgid "" | |
3254 "When we commit a change, Mercurial drops us into a text editor, to enter a " | |
3255 "message that will describe the modifications we've made in this changeset. " | |
3256 "This is called the <emphasis>commit message</emphasis>. It will be a record " | |
3257 "for readers of what we did and why, and it will be printed by <command role=" | |
3258 "\"hg-cmd\">hg log</command> after we've finished committing." | |
3259 msgstr "" | |
3260 | |
3261 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3262 #: ../en/ch02-tour-basic.xml:604 | |
3263 msgid "" | |
3264 "The editor that the <command role=\"hg-cmd\">hg commit</command> command " | |
3265 "drops us into will contain an empty line, followed by a number of lines " | |
3266 "starting with <quote><literal>HG:</literal></quote>." | |
3267 msgstr "" | |
3268 | |
3269 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3270 #: ../en/ch02-tour-basic.xml:611 | |
3271 msgid "" | |
3272 "Mercurial ignores the lines that start with <quote><literal>HG:</literal></" | |
3273 "quote>; it uses them only to tell us which files it's recording changes to. " | |
3274 "Modifying or deleting these lines has no effect." | |
3275 msgstr "" | |
3276 | |
3277 #. type: Content of: <book><chapter><sect1><sect2><title> | |
3278 #: ../en/ch02-tour-basic.xml:617 | |
3279 msgid "Writing a good commit message" | |
3280 msgstr "写好提交日志" | |
3281 | |
3282 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3283 #: ../en/ch02-tour-basic.xml:619 | |
3284 msgid "" | |
3285 "Since <command role=\"hg-cmd\">hg log</command> only prints the first line of " | |
3286 "a commit message by default, it's best to write a commit message whose first " | |
3287 "line stands alone. Here's a real example of a commit message that " | |
3288 "<emphasis>doesn't</emphasis> follow this guideline, and hence has a summary " | |
3289 "that is not readable." | |
3290 msgstr "" | |
3291 | |
3292 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3293 #: ../en/ch02-tour-basic.xml:633 | |
3294 msgid "" | |
3295 "As far as the remainder of the contents of the commit message are concerned, " | |
3296 "there are no hard-and-fast rules. Mercurial itself doesn't interpret or care " | |
3297 "about the contents of the commit message, though your project may have " | |
3298 "policies that dictate a certain kind of formatting." | |
3299 msgstr "" | |
3300 | |
3301 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3302 #: ../en/ch02-tour-basic.xml:639 | |
3303 msgid "" | |
3304 "My personal preference is for short, but informative, commit messages that " | |
3305 "tell me something that I can't figure out with a quick glance at the output " | |
3306 "of <command role=\"hg-cmd\">hg log --patch</command>." | |
3307 msgstr "" | |
3308 | |
3309 #. type: Content of: <book><chapter><sect1><sect2><title> | |
3310 #: ../en/ch02-tour-basic.xml:646 | |
3311 msgid "Aborting a commit" | |
3312 msgstr "终止提交" | |
3313 | |
3314 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3315 #: ../en/ch02-tour-basic.xml:648 | |
3316 msgid "" | |
3317 "If you decide that you don't want to commit while in the middle of editing a " | |
3318 "commit message, simply exit from your editor without saving the file that " | |
3319 "it's editing. This will cause nothing to happen to either the repository or " | |
3320 "the working directory." | |
3321 msgstr "" | |
3322 | |
3323 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3324 #: ../en/ch02-tour-basic.xml:653 | |
3325 msgid "" | |
3326 "If we run the <command role=\"hg-cmd\">hg commit</command> command without " | |
3327 "any arguments, it records all of the changes we've made, as reported by " | |
3328 "<command role=\"hg-cmd\">hg status</command> and <command role=\"hg-cmd\">hg " | |
3329 "diff</command>." | |
3330 msgstr "" | |
3331 | |
3332 #. type: Content of: <book><chapter><sect1><sect2><title> | |
3333 #: ../en/ch02-tour-basic.xml:660 | |
3334 msgid "Admiring our new handiwork" | |
3335 msgstr "欣赏我们的新手艺" | |
3336 | |
3337 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3338 #: ../en/ch02-tour-basic.xml:662 | |
3339 msgid "" | |
3340 "Once we've finished the commit, we can use the <command role=\"hg-cmd\">hg " | |
3341 "tip</command> command to display the changeset we just created. This command " | |
3342 "produces output that is identical to <command role=\"hg-cmd\">hg log</" | |
3343 "command>, but it only displays the newest revision in the repository." | |
3344 msgstr "" | |
3345 | |
3346 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3347 #: ../en/ch02-tour-basic.xml:671 | |
3348 msgid "" | |
3349 "We refer to the newest revision in the repository as the tip revision, or " | |
3350 "simply the tip." | |
3351 msgstr "" | |
3352 | |
3353 #. type: Content of: <book><chapter><sect1><title> | |
3354 #: ../en/ch02-tour-basic.xml:678 | |
3355 msgid "Sharing changes" | |
3356 msgstr "共享修改" | |
3357 | |
3358 #. type: Content of: <book><chapter><sect1><para> | |
3359 #: ../en/ch02-tour-basic.xml:680 | |
3360 msgid "" | |
3361 "We mentioned earlier that repositories in Mercurial are self-contained. This " | |
3362 "means that the changeset we just created exists only in our <filename class=" | |
3363 "\"directory\">my-hello</filename> repository. Let's look at a few ways that " | |
3364 "we can propagate this change into other repositories." | |
3365 msgstr "" | |
3366 | |
3367 #. type: Content of: <book><chapter><sect1><sect2><title> | |
3368 #: ../en/ch02-tour-basic.xml:688 | |
3369 msgid "Pulling changes from another repository" | |
3370 msgstr "从其它版本库取得修改" | |
3371 | |
3372 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3373 #: ../en/ch02-tour-basic.xml:689 | |
3374 msgid "" | |
3375 "To get started, let's clone our original <filename class=\"directory\">hello</" | |
3376 "filename> repository, which does not contain the change we just committed. " | |
3377 "We'll call our temporary repository <filename class=\"directory\">hello-pull</" | |
3378 "filename>." | |
3379 msgstr "" | |
3380 | |
3381 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3382 #: ../en/ch02-tour-basic.xml:697 | |
3383 msgid "" | |
3384 "We'll use the <command role=\"hg-cmd\">hg pull</command> command to bring " | |
3385 "changes from <filename class=\"directory\">my-hello</filename> into <filename " | |
3386 "class=\"directory\">hello-pull</filename>. However, blindly pulling unknown " | |
3387 "changes into a repository is a somewhat scary prospect. Mercurial provides " | |
3388 "the <command role=\"hg-cmd\">hg incoming</command> command to tell us what " | |
3389 "changes the <command role=\"hg-cmd\">hg pull</command> command " | |
3390 "<emphasis>would</emphasis> pull into the repository, without actually pulling " | |
3391 "the changes in." | |
3392 msgstr "" | |
3393 | |
3394 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3395 #: ../en/ch02-tour-basic.xml:710 | |
3396 msgid "" | |
3397 "(Of course, someone could cause more changesets to appear in the repository " | |
3398 "that we ran <command role=\"hg-cmd\">hg incoming</command> in, before we get " | |
3399 "a chance to <command role=\"hg-cmd\">hg pull</command> the changes, so that " | |
3400 "we could end up pulling changes that we didn't expect.)" | |
3401 msgstr "" | |
3402 | |
3403 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3404 #: ../en/ch02-tour-basic.xml:717 | |
3405 msgid "" | |
3406 "Bringing changes into a repository is a simple matter of running the <command " | |
3407 "role=\"hg-cmd\">hg pull</command> command, and telling it which repository to " | |
3408 "pull from." | |
3409 msgstr "" | |
3410 | |
3411 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3412 #: ../en/ch02-tour-basic.xml:724 | |
3413 msgid "" | |
3414 "As you can see from the before-and-after output of <command role=\"hg-cmd" | |
3415 "\">hg tip</command>, we have successfully pulled changes into our " | |
3416 "repository. There remains one step before we can see these changes in the " | |
3417 "working directory." | |
3418 msgstr "" | |
3419 | |
3420 #. type: Content of: <book><chapter><sect1><sect2><title> | |
3421 #: ../en/ch02-tour-basic.xml:732 | |
3422 msgid "Updating the working directory" | |
3423 msgstr "更新工作目录" | |
3424 | |
3425 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3426 #: ../en/ch02-tour-basic.xml:734 | |
3427 msgid "" | |
3428 "We have so far glossed over the relationship between a repository and its " | |
3429 "working directory. The <command role=\"hg-cmd\">hg pull</command> command " | |
3430 "that we ran in section <xref linkend=\"sec.tour.pull\"/> brought changes into " | |
3431 "the repository, but if we check, there's no sign of those changes in the " | |
3432 "working directory. This is because <command role=\"hg-cmd\">hg pull</" | |
3433 "command> does not (by default) touch the working directory. Instead, we use " | |
3434 "the <command role=\"hg-cmd\">hg update</command> command to do this." | |
3435 msgstr "" | |
3436 | |
3437 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3438 #: ../en/ch02-tour-basic.xml:746 | |
3439 msgid "" | |
3440 "It might seem a bit strange that <command role=\"hg-cmd\">hg pull</command> " | |
3441 "doesn't update the working directory automatically. There's actually a good " | |
3442 "reason for this: you can use <command role=\"hg-cmd\">hg update</command> to " | |
3443 "update the working directory to the state it was in at <emphasis>any " | |
3444 "revision</emphasis> in the history of the repository. If you had the working " | |
3445 "directory updated to an old revision---to hunt down the origin of a bug, " | |
3446 "say---and ran a <command role=\"hg-cmd\">hg pull</command> which " | |
3447 "automatically updated the working directory to a new revision, you might not " | |
3448 "be terribly happy." | |
3449 msgstr "" | |
3450 | |
3451 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3452 #: ../en/ch02-tour-basic.xml:757 | |
3453 msgid "" | |
3454 "However, since pull-then-update is such a common thing to do, Mercurial lets " | |
3455 "you combine the two by passing the <option role=\"hg-opt-pull\">-u</option> " | |
3456 "option to <command role=\"hg-cmd\">hg pull</command>." | |
3457 msgstr "" | |
3458 | |
3459 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3460 #: ../en/ch02-tour-basic.xml:762 | |
3461 msgid "" | |
3462 "If you look back at the output of <command role=\"hg-cmd\">hg pull</command> " | |
3463 "in section <xref linkend=\"sec.tour.pull\"/> when we ran it without <option " | |
3464 "role=\"hg-opt-pull\">-u</option>, you can see that it printed a helpful " | |
3465 "reminder that we'd have to take an explicit step to update the working " | |
3466 "directory:" | |
3467 msgstr "" | |
3468 | |
3469 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3470 #: ../en/ch02-tour-basic.xml:771 | |
3471 msgid "" | |
3472 "To find out what revision the working directory is at, use the <command role=" | |
3473 "\"hg-cmd\">hg parents</command> command." | |
3474 msgstr "" | |
3475 | |
3476 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3477 #: ../en/ch02-tour-basic.xml:777 | |
3478 msgid "" | |
3479 "If you look back at figure <xref linkend=\"fig.tour-basic.history\"/>, you'll " | |
3480 "see arrows connecting each changeset. The node that the arrow leads " | |
3481 "<emphasis>from</emphasis> in each case is a parent, and the node that the " | |
3482 "arrow leads <emphasis>to</emphasis> is its child. The working directory has " | |
3483 "a parent in just the same way; this is the changeset that the working " | |
3484 "directory currently contains." | |
3485 msgstr "" | |
3486 | |
3487 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3488 #: ../en/ch02-tour-basic.xml:786 | |
3489 msgid "" | |
3490 "To update the working directory to a particular revision, give a revision " | |
3491 "number or changeset ID to the <command role=\"hg-cmd\">hg update</command> " | |
3492 "command." | |
3493 msgstr "" | |
3494 | |
3495 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3496 #: ../en/ch02-tour-basic.xml:793 | |
3497 msgid "" | |
3498 "If you omit an explicit revision, <command role=\"hg-cmd\">hg update</" | |
3499 "command> will update to the tip revision, as shown by the second call to " | |
3500 "<command role=\"hg-cmd\">hg update</command> in the example above." | |
3501 msgstr "" | |
3502 | |
3503 #. type: Content of: <book><chapter><sect1><sect2><title> | |
3504 #: ../en/ch02-tour-basic.xml:801 | |
3505 msgid "Pushing changes to another repository" | |
3506 msgstr "发布修改到其它版本库" | |
3507 | |
3508 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3509 #: ../en/ch02-tour-basic.xml:803 | |
3510 msgid "" | |
3511 "Mercurial lets us push changes to another repository, from the repository " | |
3512 "we're currently visiting. As with the example of <command role=\"hg-cmd\">hg " | |
3513 "pull</command> above, we'll create a temporary repository to push our changes " | |
3514 "into." | |
3515 msgstr "" | |
3516 | |
3517 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3518 #: ../en/ch02-tour-basic.xml:811 | |
3519 msgid "" | |
3520 "The <command role=\"hg-cmd\">hg outgoing</command> command tells us what " | |
3521 "changes would be pushed into another repository." | |
3522 msgstr "" | |
3523 | |
3524 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3525 #: ../en/ch02-tour-basic.xml:817 | |
3526 msgid "" | |
3527 "And the <command role=\"hg-cmd\">hg push</command> command does the actual " | |
3528 "push." | |
3529 msgstr "" | |
3530 | |
3531 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3532 #: ../en/ch02-tour-basic.xml:823 | |
3533 msgid "" | |
3534 "As with <command role=\"hg-cmd\">hg pull</command>, the <command role=\"hg-cmd" | |
3535 "\">hg push</command> command does not update the working directory in the " | |
3536 "repository that it's pushing changes into. (Unlike <command role=\"hg-cmd" | |
3537 "\">hg pull</command>, <command role=\"hg-cmd\">hg push</command> does not " | |
3538 "provide a <literal>-u</literal> option that updates the other repository's " | |
3539 "working directory.)" | |
3540 msgstr "" | |
3541 | |
3542 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3543 #: ../en/ch02-tour-basic.xml:832 | |
3544 msgid "" | |
3545 "What happens if we try to pull or push changes and the receiving repository " | |
3546 "already has those changes? Nothing too exciting." | |
3547 msgstr "" | |
3548 | |
3549 #. type: Content of: <book><chapter><sect1><sect2><title> | |
3550 #: ../en/ch02-tour-basic.xml:839 | |
3551 msgid "Sharing changes over a network" | |
3552 msgstr "通过网络共享修改" | |
3553 | |
3554 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3555 #: ../en/ch02-tour-basic.xml:841 | |
3556 msgid "" | |
3557 "The commands we have covered in the previous few sections are not limited to " | |
3558 "working with local repositories. Each works in exactly the same fashion over " | |
3559 "a network connection; simply pass in a URL instead of a local path." | |
3560 msgstr "" | |
3561 | |
3562 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3563 #: ../en/ch02-tour-basic.xml:849 | |
3564 msgid "" | |
3565 "In this example, we can see what changes we could push to the remote " | |
3566 "repository, but the repository is understandably not set up to let anonymous " | |
3567 "users push to it." | |
3568 msgstr "" | |
3569 | |
3570 #. type: Content of: <book><chapter><title> | |
3571 #: ../en/ch03-tour-merge.xml:5 | |
3572 msgid "A tour of Mercurial: merging work" | |
3573 msgstr "Mercurial 教程: 合并工作" | |
3574 | |
3575 #. type: Content of: <book><chapter><para> | |
3576 #: ../en/ch03-tour-merge.xml:7 | |
3577 msgid "" | |
3578 "We've now covered cloning a repository, making changes in a repository, and " | |
3579 "pulling or pushing changes from one repository into another. Our next step " | |
3580 "is <emphasis>merging</emphasis> changes from separate repositories." | |
3581 msgstr "" | |
3582 | |
3583 #. type: Content of: <book><chapter><sect1><title> | |
3584 #: ../en/ch03-tour-merge.xml:13 | |
3585 msgid "Merging streams of work" | |
3586 msgstr "合并的流程" | |
3587 | |
3588 #. type: Content of: <book><chapter><sect1><para> | |
3589 #: ../en/ch03-tour-merge.xml:15 | |
3590 msgid "" | |
3591 "Merging is a fundamental part of working with a distributed revision control " | |
3592 "tool." | |
3593 msgstr "" | |
3594 | |
3595 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
3596 #: ../en/ch03-tour-merge.xml:18 | |
3597 msgid "" | |
3598 "Alice and Bob each have a personal copy of a repository for a project they're " | |
3599 "collaborating on. Alice fixes a bug in her repository; Bob adds a new " | |
3600 "feature in his. They want the shared repository to contain both the bug fix " | |
3601 "and the new feature." | |
3602 msgstr "" | |
3603 | |
3604 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
3605 #: ../en/ch03-tour-merge.xml:24 | |
3606 msgid "" | |
3607 "I frequently work on several different tasks for a single project at once, " | |
3608 "each safely isolated in its own repository. Working this way means that I " | |
3609 "often need to merge one piece of my own work with another." | |
3610 msgstr "" | |
3611 | |
3612 #. type: Content of: <book><chapter><sect1><para> | |
3613 #: ../en/ch03-tour-merge.xml:30 | |
3614 msgid "" | |
3615 "Because merging is such a common thing to need to do, Mercurial makes it " | |
3616 "easy. Let's walk through the process. We'll begin by cloning yet another " | |
3617 "repository (see how often they spring up?) and making a change in it." | |
3618 msgstr "" | |
3619 | |
3620 #. type: Content of: <book><chapter><sect1><para> | |
3621 #: ../en/ch03-tour-merge.xml:37 | |
3622 msgid "" | |
3623 "We should now have two copies of <filename>hello.c</filename> with different " | |
3624 "contents. The histories of the two repositories have also diverged, as " | |
3625 "illustrated in figure <xref linkend=\"fig.tour-merge.sep-repos\"/>." | |
3626 msgstr "" | |
3627 | |
3628 #. type: Content of: <book><chapter><sect1><informalfigure><mediaobject> | |
3629 #: ../en/ch03-tour-merge.xml:47 | |
3630 msgid "" | |
3631 "<imageobject><imagedata fileref=\"images/tour-merge-sep-repos.png\"/></" | |
3632 "imageobject>" | |
3633 msgstr "" | |
3634 | |
3635 #. type: Content of: <book><chapter><sect1><informalfigure><mediaobject><caption><para> | |
3636 #: ../en/ch03-tour-merge.xml:49 | |
3637 msgid "" | |
3638 "Divergent recent histories of the <filename class=\"directory\">my-hello</" | |
3639 "filename> and <filename class=\"directory\">my-new-hello</filename> " | |
3640 "repositories" | |
3641 msgstr "" | |
3642 | |
3643 #. type: Content of: <book><chapter><sect1><para> | |
3644 #: ../en/ch03-tour-merge.xml:56 | |
3645 msgid "" | |
3646 "We already know that pulling changes from our <filename class=\"directory" | |
3647 "\">my-hello</filename> repository will have no effect on the working " | |
3648 "directory." | |
3649 msgstr "" | |
3650 | |
3651 #. type: Content of: <book><chapter><sect1><para> | |
3652 #: ../en/ch03-tour-merge.xml:62 | |
3653 msgid "" | |
3654 "However, the <command role=\"hg-cmd\">hg pull</command> command says " | |
3655 "something about <quote>heads</quote>." | |
3656 msgstr "" | |
3657 | |
3658 #. type: Content of: <book><chapter><sect1><sect2><title> | |
3659 #: ../en/ch03-tour-merge.xml:66 | |
3660 msgid "Head changesets" | |
3661 msgstr "顶点改变集" | |
3662 | |
3663 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3664 #: ../en/ch03-tour-merge.xml:68 | |
3665 msgid "" | |
3666 "A head is a change that has no descendants, or children, as they're also " | |
3667 "known. The tip revision is thus a head, because the newest revision in a " | |
3668 "repository doesn't have any children, but a repository can contain more than " | |
3669 "one head." | |
3670 msgstr "" | |
3671 | |
3672 #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject> | |
3673 #: ../en/ch03-tour-merge.xml:75 | |
3674 msgid "" | |
3675 "<imageobject><imagedata fileref=\"images/tour-merge-pull.png\"/></imageobject>" | |
3676 msgstr "" | |
3677 | |
3678 #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject><caption><para> | |
3679 #: ../en/ch03-tour-merge.xml:78 | |
3680 msgid "" | |
3681 "Repository contents after pulling from <filename class=\"directory\">my-" | |
3682 "hello</filename> into <filename class=\"directory\">my-new-hello</filename>" | |
3683 msgstr "" | |
3684 | |
3685 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3686 #: ../en/ch03-tour-merge.xml:85 | |
3687 msgid "" | |
3688 "In figure <xref linkend=\"fig.tour-merge.pull\"/>, you can see the effect of " | |
3689 "the pull from <filename class=\"directory\">my-hello</filename> into " | |
3690 "<filename class=\"directory\">my-new-hello</filename>. The history that was " | |
3691 "already present in <filename class=\"directory\">my-new-hello</filename> is " | |
3692 "untouched, but a new revision has been added. By referring to figure <xref " | |
3693 "linkend=\"fig.tour-merge.sep-repos\"/>, we can see that the " | |
3694 "<emphasis>changeset ID</emphasis> remains the same in the new repository, but " | |
3695 "the <emphasis>revision number</emphasis> has changed. (This, incidentally, " | |
3696 "is a fine example of why it's not safe to use revision numbers when " | |
3697 "discussing changesets.) We can view the heads in a repository using the " | |
3698 "<command role=\"hg-cmd\">hg heads</command> command." | |
3699 msgstr "" | |
3700 | |
3701 #. type: Content of: <book><chapter><sect1><sect2><title> | |
3702 #: ../en/ch03-tour-merge.xml:104 | |
3703 msgid "Performing the merge" | |
3704 msgstr "执行合并" | |
3705 | |
3706 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3707 #: ../en/ch03-tour-merge.xml:106 | |
3708 msgid "" | |
3709 "What happens if we try to use the normal <command role=\"hg-cmd\">hg update</" | |
3710 "command> command to update to the new tip?" | |
3711 msgstr "" | |
3712 | |
3713 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3714 #: ../en/ch03-tour-merge.xml:112 | |
3715 msgid "" | |
3716 "Mercurial is telling us that the <command role=\"hg-cmd\">hg update</command> " | |
3717 "command won't do a merge; it won't update the working directory when it " | |
3718 "thinks we might be wanting to do a merge, unless we force it to do so. " | |
3719 "Instead, we use the <command role=\"hg-cmd\">hg merge</command> command to " | |
3720 "merge the two heads." | |
3721 msgstr "" | |
3722 | |
3723 #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject> | |
3724 #: ../en/ch03-tour-merge.xml:123 | |
3725 msgid "" | |
3726 "<imageobject><imagedata fileref=\"images/tour-merge-merge.png\"/></" | |
3727 "imageobject>" | |
3728 msgstr "" | |
3729 | |
3730 #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject><caption><para> | |
3731 #: ../en/ch03-tour-merge.xml:126 | |
3732 msgid "Working directory and repository during merge, and following commit" | |
3733 msgstr "" | |
3734 | |
3735 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3736 #: ../en/ch03-tour-merge.xml:131 | |
3737 msgid "" | |
3738 "This updates the working directory so that it contains changes from " | |
3739 "<emphasis>both</emphasis> heads, which is reflected in both the output of " | |
3740 "<command role=\"hg-cmd\">hg parents</command> and the contents of " | |
3741 "<filename>hello.c</filename>." | |
3742 msgstr "" | |
3743 | |
3744 #. type: Content of: <book><chapter><sect1><sect2><title> | |
3745 #: ../en/ch03-tour-merge.xml:141 | |
3746 msgid "Committing the results of the merge" | |
3747 msgstr "提交合并结果" | |
3748 | |
3749 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3750 #: ../en/ch03-tour-merge.xml:143 | |
3751 msgid "" | |
3752 "Whenever we've done a merge, <command role=\"hg-cmd\">hg parents</command> " | |
3753 "will display two parents until we <command role=\"hg-cmd\">hg commit</" | |
3754 "command> the results of the merge." | |
3755 msgstr "" | |
3756 | |
3757 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3758 #: ../en/ch03-tour-merge.xml:150 | |
3759 msgid "" | |
3760 "We now have a new tip revision; notice that it has <emphasis>both</emphasis> " | |
3761 "of our former heads as its parents. These are the same revisions that were " | |
3762 "previously displayed by <command role=\"hg-cmd\">hg parents</command>." | |
3763 msgstr "" | |
3764 | |
3765 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3766 #: ../en/ch03-tour-merge.xml:157 | |
3767 msgid "" | |
3768 "In figure <xref linkend=\"fig.tour-merge.merge\"/>, you can see a " | |
3769 "representation of what happens to the working directory during the merge, and " | |
3770 "how this affects the repository when the commit happens. During the merge, " | |
3771 "the working directory has two parent changesets, and these become the parents " | |
3772 "of the new changeset." | |
3773 msgstr "" | |
3774 | |
3775 #. type: Content of: <book><chapter><sect1><title> | |
3776 #: ../en/ch03-tour-merge.xml:168 | |
3777 msgid "Merging conflicting changes" | |
3778 msgstr "合并有冲突的改变" | |
3779 | |
3780 #. type: Content of: <book><chapter><sect1><para> | |
3781 #: ../en/ch03-tour-merge.xml:170 | |
3782 msgid "" | |
3783 "Most merges are simple affairs, but sometimes you'll find yourself merging " | |
3784 "changes where each modifies the same portions of the same files. Unless both " | |
3785 "modifications are identical, this results in a <emphasis>conflict</emphasis>, " | |
3786 "where you have to decide how to reconcile the different changes into " | |
3787 "something coherent." | |
3788 msgstr "" | |
3789 | |
3790 #. type: Content of: <book><chapter><sect1><informalfigure><mediaobject> | |
3791 #: ../en/ch03-tour-merge.xml:180 | |
3792 msgid "" | |
3793 "<imageobject><imagedata fileref=\"images/tour-merge-conflict.png\"/></" | |
3794 "imageobject>" | |
3795 msgstr "" | |
3796 | |
3797 #. type: Content of: <book><chapter><sect1><informalfigure><mediaobject><caption><para> | |
3798 #: ../en/ch03-tour-merge.xml:182 | |
3799 msgid "Conflicting changes to a document" | |
3800 msgstr "" | |
3801 | |
3802 #. type: Content of: <book><chapter><sect1><para> | |
3803 #: ../en/ch03-tour-merge.xml:186 | |
3804 msgid "" | |
3805 "Figure <xref linkend=\"fig.tour-merge.conflict\"/> illustrates an instance of " | |
3806 "two conflicting changes to a document. We started with a single version of " | |
3807 "the file; then we made some changes; while someone else made different " | |
3808 "changes to the same text. Our task in resolving the conflicting changes is " | |
3809 "to decide what the file should look like." | |
3810 msgstr "" | |
3811 | |
3812 #. type: Content of: <book><chapter><sect1><para> | |
3813 #: ../en/ch03-tour-merge.xml:193 | |
3814 msgid "" | |
3815 "Mercurial doesn't have a built-in facility for handling conflicts. Instead, " | |
3816 "it runs an external program called <command>hgmerge</command>. This is a " | |
3817 "shell script that is bundled with Mercurial; you can change it to behave " | |
3818 "however you please. What it does by default is try to find one of several " | |
3819 "different merging tools that are likely to be installed on your system. It " | |
3820 "first tries a few fully automatic merging tools; if these don't succeed " | |
3821 "(because the resolution process requires human guidance) or aren't present, " | |
3822 "the script tries a few different graphical merging tools." | |
3823 msgstr "" | |
3824 | |
3825 #. type: Content of: <book><chapter><sect1><para> | |
3826 #: ../en/ch03-tour-merge.xml:204 | |
3827 msgid "" | |
3828 "It's also possible to get Mercurial to run another program or script instead " | |
3829 "of <command>hgmerge</command>, by setting the <envar>HGMERGE</envar> " | |
3830 "environment variable to the name of your preferred program." | |
3831 msgstr "" | |
3832 | |
3833 #. type: Content of: <book><chapter><sect1><sect2><title> | |
3834 #: ../en/ch03-tour-merge.xml:210 | |
3835 msgid "Using a graphical merge tool" | |
3836 msgstr "使用图形合并工具" | |
3837 | |
3838 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3839 #: ../en/ch03-tour-merge.xml:212 | |
3840 msgid "" | |
3841 "My preferred graphical merge tool is <command>kdiff3</command>, which I'll " | |
3842 "use to describe the features that are common to graphical file merging " | |
3843 "tools. You can see a screenshot of <command>kdiff3</command> in action in " | |
3844 "figure <xref linkend=\"fig.tour-merge.kdiff3\"/>. The kind of merge it is " | |
3845 "performing is called a <emphasis>three-way merge</emphasis>, because there " | |
3846 "are three different versions of the file of interest to us. The tool thus " | |
3847 "splits the upper portion of the window into three panes:" | |
3848 msgstr "" | |
3849 | |
3850 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
3851 #: ../en/ch03-tour-merge.xml:222 | |
3852 msgid "" | |
3853 "At the left is the <emphasis>base</emphasis> version of the file, i.e. the " | |
3854 "most recent version from which the two versions we're trying to merge are " | |
3855 "descended." | |
3856 msgstr "" | |
3857 | |
3858 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
3859 #: ../en/ch03-tour-merge.xml:227 | |
3860 msgid "" | |
3861 "In the middle is <quote>our</quote> version of the file, with the contents " | |
3862 "that we modified." | |
3863 msgstr "" | |
3864 | |
3865 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
3866 #: ../en/ch03-tour-merge.xml:230 | |
3867 msgid "" | |
3868 "On the right is <quote>their</quote> version of the file, the one that from " | |
3869 "the changeset that we're trying to merge with." | |
3870 msgstr "" | |
3871 | |
3872 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3873 #: ../en/ch03-tour-merge.xml:234 | |
3874 msgid "" | |
3875 "In the pane below these is the current <emphasis>result</emphasis> of the " | |
3876 "merge. Our task is to replace all of the red text, which indicates unresolved " | |
3877 "conflicts, with some sensible merger of the <quote>ours</quote> and " | |
3878 "<quote>theirs</quote> versions of the file." | |
3879 msgstr "" | |
3880 | |
3881 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3882 #: ../en/ch03-tour-merge.xml:241 | |
3883 msgid "" | |
3884 "All four of these panes are <emphasis>locked together</emphasis>; if we " | |
3885 "scroll vertically or horizontally in any of them, the others are updated to " | |
3886 "display the corresponding sections of their respective files." | |
3887 msgstr "" | |
3888 | |
3889 #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject> | |
3890 #: ../en/ch03-tour-merge.xml:247 | |
3891 msgid "<imageobject><imagedata fileref=\"images/kdiff3.png\"/></imageobject>" | |
3892 msgstr "" | |
3893 | |
3894 #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject><caption><para> | |
3895 #: ../en/ch03-tour-merge.xml:250 | |
3896 msgid "Using <command>kdiff3</command> to merge versions of a file" | |
3897 msgstr "" | |
3898 | |
3899 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3900 #: ../en/ch03-tour-merge.xml:255 | |
3901 msgid "" | |
3902 "For each conflicting portion of the file, we can choose to resolve the " | |
3903 "conflict using some combination of text from the base version, ours, or " | |
3904 "theirs. We can also manually edit the merged file at any time, in case we " | |
3905 "need to make further modifications." | |
3906 msgstr "" | |
3907 | |
3908 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3909 #: ../en/ch03-tour-merge.xml:261 | |
3910 msgid "" | |
3911 "There are <emphasis>many</emphasis> file merging tools available, too many to " | |
3912 "cover here. They vary in which platforms they are available for, and in " | |
3913 "their particular strengths and weaknesses. Most are tuned for merging files " | |
3914 "containing plain text, while a few are aimed at specialised file formats " | |
3915 "(generally XML)." | |
3916 msgstr "" | |
3917 | |
3918 #. type: Content of: <book><chapter><sect1><sect2><title> | |
3919 #: ../en/ch03-tour-merge.xml:270 | |
3920 msgid "A worked example" | |
3921 msgstr "合并实例" | |
3922 | |
3923 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3924 #: ../en/ch03-tour-merge.xml:272 | |
3925 msgid "" | |
3926 "In this example, we will reproduce the file modification history of figure " | |
3927 "<xref linkend=\"fig.tour-merge.conflict\"/> above. Let's begin by creating a " | |
3928 "repository with a base version of our document." | |
3929 msgstr "" | |
3930 | |
3931 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3932 #: ../en/ch03-tour-merge.xml:279 | |
3933 msgid "We'll clone the repository and make a change to the file." | |
3934 msgstr "" | |
3935 | |
3936 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3937 #: ../en/ch03-tour-merge.xml:284 | |
3938 msgid "" | |
3939 "And another clone, to simulate someone else making a change to the file. " | |
3940 "(This hints at the idea that it's not all that unusual to merge with yourself " | |
3941 "when you isolate tasks in separate repositories, and indeed to find and " | |
3942 "resolve conflicts while doing so.)" | |
3943 msgstr "" | |
3944 | |
3945 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3946 #: ../en/ch03-tour-merge.xml:292 | |
3947 msgid "" | |
3948 "Having created two different versions of the file, we'll set up an " | |
3949 "environment suitable for running our merge." | |
3950 msgstr "" | |
3951 | |
3952 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3953 #: ../en/ch03-tour-merge.xml:298 | |
3954 msgid "" | |
3955 "In this example, I won't use Mercurial's normal <command>hgmerge</command> " | |
3956 "program to do the merge, because it would drop my nice automated example-" | |
3957 "running tool into a graphical user interface. Instead, I'll set " | |
3958 "<envar>HGMERGE</envar> to tell Mercurial to use the non-interactive " | |
3959 "<command>merge</command> command. This is bundled with many Unix-like " | |
3960 "systems. If you're following this example on your computer, don't bother " | |
3961 "setting <envar>HGMERGE</envar>." | |
3962 msgstr "" | |
3963 | |
3964 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3965 #: ../en/ch03-tour-merge.xml:308 | |
3966 msgid "<emphasis role=\"bold\">XXX FIX THIS EXAMPLE.</emphasis>" | |
3967 msgstr "" | |
3968 | |
3969 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3970 #: ../en/ch03-tour-merge.xml:313 | |
3971 msgid "" | |
3972 "Because <command>merge</command> can't resolve the conflicting changes, it " | |
3973 "leaves <emphasis>merge markers</emphasis> inside the file that has conflicts, " | |
3974 "indicating which lines have conflicts, and whether they came from our version " | |
3975 "of the file or theirs." | |
3976 msgstr "" | |
3977 | |
3978 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3979 #: ../en/ch03-tour-merge.xml:319 | |
3980 msgid "" | |
3981 "Mercurial can tell from the way <command>merge</command> exits that it wasn't " | |
3982 "able to merge successfully, so it tells us what commands we'll need to run if " | |
3983 "we want to redo the merging operation. This could be useful if, for example, " | |
3984 "we were running a graphical merge tool and quit because we were confused or " | |
3985 "realised we had made a mistake." | |
3986 msgstr "" | |
3987 | |
3988 #. type: Content of: <book><chapter><sect1><sect2><para> | |
3989 #: ../en/ch03-tour-merge.xml:326 | |
3990 msgid "" | |
3991 "If automatic or manual merges fail, there's nothing to prevent us from " | |
3992 "<quote>fixing up</quote> the affected files ourselves, and committing the " | |
3993 "results of our merge:" | |
3994 msgstr "" | |
3995 | |
3996 #. type: Content of: <book><chapter><sect1><title> | |
3997 #: ../en/ch03-tour-merge.xml:335 | |
3998 msgid "Simplifying the pull-merge-commit sequence" | |
3999 msgstr "简化拉-合并-提交程序" | |
4000 | |
4001 #. type: Content of: <book><chapter><sect1><para> | |
4002 #: ../en/ch03-tour-merge.xml:337 | |
4003 msgid "" | |
4004 "The process of merging changes as outlined above is straightforward, but " | |
4005 "requires running three commands in sequence." | |
4006 msgstr "" | |
4007 | |
4008 #. type: Content of: <book><chapter><sect1><para> | |
4009 #: ../en/ch03-tour-merge.xml:343 | |
4010 msgid "" | |
4011 "In the case of the final commit, you also need to enter a commit message, " | |
4012 "which is almost always going to be a piece of uninteresting " | |
4013 "<quote>boilerplate</quote> text." | |
4014 msgstr "" | |
4015 | |
4016 #. type: Content of: <book><chapter><sect1><para> | |
4017 #: ../en/ch03-tour-merge.xml:347 | |
4018 msgid "" | |
4019 "It would be nice to reduce the number of steps needed, if this were " | |
4020 "possible. Indeed, Mercurial is distributed with an extension called <literal " | |
4021 "role=\"hg-ext\">fetch</literal> that does just this." | |
4022 msgstr "" | |
4023 | |
4024 #. type: Content of: <book><chapter><sect1><para> | |
4025 #: ../en/ch03-tour-merge.xml:352 | |
4026 msgid "" | |
4027 "Mercurial provides a flexible extension mechanism that lets people extend its " | |
4028 "functionality, while keeping the core of Mercurial small and easy to deal " | |
4029 "with. Some extensions add new commands that you can use from the command " | |
4030 "line, while others work <quote>behind the scenes,</quote> for example adding " | |
4031 "capabilities to the server." | |
4032 msgstr "" | |
4033 | |
4034 #. type: Content of: <book><chapter><sect1><para> | |
4035 #: ../en/ch03-tour-merge.xml:359 | |
4036 msgid "" | |
4037 "The <literal role=\"hg-ext\">fetch</literal> extension adds a new command " | |
4038 "called, not surprisingly, <command role=\"hg-cmd\">hg fetch</command>. This " | |
4039 "extension acts as a combination of <command role=\"hg-cmd\">hg pull</" | |
4040 "command>, <command role=\"hg-cmd\">hg update</command> and <command role=\"hg-" | |
4041 "cmd\">hg merge</command>. It begins by pulling changes from another " | |
4042 "repository into the current repository. If it finds that the changes added a " | |
4043 "new head to the repository, it begins a merge, then commits the result of the " | |
4044 "merge with an automatically-generated commit message. If no new heads were " | |
4045 "added, it updates the working directory to the new tip changeset." | |
4046 msgstr "" | |
4047 | |
4048 #. type: Content of: <book><chapter><sect1><para> | |
4049 #: ../en/ch03-tour-merge.xml:372 | |
4050 msgid "" | |
4051 "Enabling the <literal role=\"hg-ext\">fetch</literal> extension is easy. " | |
4052 "Edit your <filename role=\"special\">.hgrc</filename>, and either go to the " | |
4053 "<literal role=\"rc-extensions\">extensions</literal> section or create an " | |
4054 "<literal role=\"rc-extensions\">extensions</literal> section. Then add a line " | |
4055 "that simply reads <quote><literal>fetch </literal></quote>." | |
4056 msgstr "" | |
4057 | |
4058 #. type: Content of: <book><chapter><sect1><para> | |
4059 #: ../en/ch03-tour-merge.xml:382 | |
4060 msgid "" | |
4061 "(Normally, on the right-hand side of the <quote><literal>=</literal></quote> " | |
4062 "would appear the location of the extension, but since the <literal role=\"hg-" | |
4063 "ext\">fetch</literal> extension is in the standard distribution, Mercurial " | |
4064 "knows where to search for it.)" | |
4065 msgstr "" | |
4066 | |
4067 #. type: Content of: <book><chapter><title> | |
4068 #: ../en/ch04-concepts.xml:5 | |
4069 msgid "Behind the scenes" | |
4070 msgstr "Mercurial 内幕" | |
4071 | |
4072 #. type: Content of: <book><chapter><para> | |
4073 #: ../en/ch04-concepts.xml:7 | |
4074 msgid "" | |
4075 "Unlike many revision control systems, the concepts upon which Mercurial is " | |
4076 "built are simple enough that it's easy to understand how the software really " | |
4077 "works. Knowing this certainly isn't necessary, but I find it useful to have " | |
4078 "a <quote>mental model</quote> of what's going on." | |
4079 msgstr "" | |
4080 | |
4081 #. type: Content of: <book><chapter><para> | |
4082 #: ../en/ch04-concepts.xml:13 | |
4083 msgid "" | |
4084 "This understanding gives me confidence that Mercurial has been carefully " | |
4085 "designed to be both <emphasis>safe</emphasis> and <emphasis>efficient</" | |
4086 "emphasis>. And just as importantly, if it's easy for me to retain a good " | |
4087 "idea of what the software is doing when I perform a revision control task, " | |
4088 "I'm less likely to be surprised by its behaviour." | |
4089 msgstr "" | |
4090 | |
4091 #. type: Content of: <book><chapter><para> | |
4092 #: ../en/ch04-concepts.xml:20 | |
4093 msgid "" | |
4094 "In this chapter, we'll initially cover the core concepts behind Mercurial's " | |
4095 "design, then continue to discuss some of the interesting details of its " | |
4096 "implementation." | |
4097 msgstr "" | |
4098 | |
4099 #. type: Content of: <book><chapter><sect1><title> | |
4100 #: ../en/ch04-concepts.xml:25 | |
4101 msgid "Mercurial's historical record" | |
4102 msgstr "Mercurial 的历史记录" | |
4103 | |
4104 #. type: Content of: <book><chapter><sect1><sect2><title> | |
4105 #: ../en/ch04-concepts.xml:28 | |
4106 msgid "Tracking the history of a single file" | |
4107 msgstr "跟踪单一文件的历史" | |
4108 | |
4109 #. type: Content of: <book><chapter><sect1><sect2><para> | |
4110 #: ../en/ch04-concepts.xml:30 | |
4111 msgid "" | |
4112 "When Mercurial tracks modifications to a file, it stores the history of that " | |
4113 "file in a metadata object called a <emphasis>filelog</emphasis>. Each entry " | |
4114 "in the filelog contains enough information to reconstruct one revision of the " | |
4115 "file that is being tracked. Filelogs are stored as files in the <filename " | |
4116 "role=\"special\" class=\"directory\">.hg/store/data</filename> directory. A " | |
4117 "filelog contains two kinds of information: revision data, and an index to " | |
4118 "help Mercurial to find a revision efficiently." | |
4119 msgstr "" | |
4120 | |
4121 #. type: Content of: <book><chapter><sect1><sect2><para> | |
4122 #: ../en/ch04-concepts.xml:41 | |
4123 msgid "" | |
4124 "A file that is large, or has a lot of history, has its filelog stored in " | |
4125 "separate data (<quote><literal>.d</literal></quote> suffix) and index " | |
4126 "(<quote><literal>.i</literal></quote> suffix) files. For small files without " | |
4127 "much history, the revision data and index are combined in a single " | |
4128 "<quote><literal>.i</literal></quote> file. The correspondence between a file " | |
4129 "in the working directory and the filelog that tracks its history in the " | |
4130 "repository is illustrated in figure <xref linkend=\"fig.concepts.filelog\"/>." | |
4131 msgstr "" | |
4132 | |
4133 #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject> | |
4134 #: ../en/ch04-concepts.xml:53 | |
4135 msgid "<imageobject><imagedata fileref=\"images/filelog.png\"/></imageobject>" | |
4136 msgstr "" | |
4137 | |
4138 #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject><caption><para> | |
4139 #: ../en/ch04-concepts.xml:56 | |
4140 msgid "" | |
4141 "Relationships between files in working directory and filelogs in repository" | |
4142 msgstr "" | |
4143 | |
4144 #. type: Content of: <book><chapter><sect1><sect2><title> | |
4145 #: ../en/ch04-concepts.xml:63 | |
4146 msgid "Managing tracked files" | |
4147 msgstr "管理跟踪的文件" | |
4148 | |
4149 #. type: Content of: <book><chapter><sect1><sect2><para> | |
4150 #: ../en/ch04-concepts.xml:65 | |
4151 msgid "" | |
4152 "Mercurial uses a structure called a <emphasis>manifest</emphasis> to collect " | |
4153 "together information about the files that it tracks. Each entry in the " | |
4154 "manifest contains information about the files present in a single changeset. " | |
4155 "An entry records which files are present in the changeset, the revision of " | |
4156 "each file, and a few other pieces of file metadata." | |
4157 msgstr "" | |
4158 | |
4159 #. type: Content of: <book><chapter><sect1><sect2><title> | |
4160 #: ../en/ch04-concepts.xml:75 | |
4161 msgid "Recording changeset information" | |
4162 msgstr "记录修改集信息" | |
4163 | |
4164 #. type: Content of: <book><chapter><sect1><sect2><para> | |
4165 #: ../en/ch04-concepts.xml:77 | |
4166 msgid "" | |
4167 "The <emphasis>changelog</emphasis> contains information about each " | |
4168 "changeset. Each revision records who committed a change, the changeset " | |
4169 "comment, other pieces of changeset-related information, and the revision of " | |
4170 "the manifest to use." | |
4171 msgstr "" | |
4172 | |
4173 #. type: Content of: <book><chapter><sect1><sect2><title> | |
4174 #: ../en/ch04-concepts.xml:85 | |
4175 msgid "Relationships between revisions" | |
4176 msgstr "版本之间的关系" | |
4177 | |
4178 #. type: Content of: <book><chapter><sect1><sect2><para> | |
4179 #: ../en/ch04-concepts.xml:87 | |
4180 msgid "" | |
4181 "Within a changelog, a manifest, or a filelog, each revision stores a pointer " | |
4182 "to its immediate parent (or to its two parents, if it's a merge revision). " | |
4183 "As I mentioned above, there are also relationships between revisions " | |
4184 "<emphasis>across</emphasis> these structures, and they are hierarchical in " | |
4185 "nature." | |
4186 msgstr "" | |
4187 | |
4188 #. type: Content of: <book><chapter><sect1><sect2><para> | |
4189 #: ../en/ch04-concepts.xml:94 | |
4190 msgid "" | |
4191 "For every changeset in a repository, there is exactly one revision stored in " | |
4192 "the changelog. Each revision of the changelog contains a pointer to a single " | |
4193 "revision of the manifest. A revision of the manifest stores a pointer to a " | |
4194 "single revision of each filelog tracked when that changeset was created. " | |
4195 "These relationships are illustrated in figure <xref linkend=\"fig.concepts." | |
4196 "metadata\"/>." | |
4197 msgstr "" | |
4198 | |
4199 #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject> | |
4200 #: ../en/ch04-concepts.xml:103 | |
4201 msgid "<imageobject><imagedata fileref=\"images/metadata.png\"/></imageobject>" | |
4202 msgstr "" | |
4203 | |
4204 #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject><caption><para> | |
4205 #: ../en/ch04-concepts.xml:105 | |
4206 msgid "Metadata relationships" | |
4207 msgstr "" | |
4208 | |
4209 #. type: Content of: <book><chapter><sect1><sect2><para> | |
4210 #: ../en/ch04-concepts.xml:110 | |
4211 msgid "" | |
4212 "As the illustration shows, there is <emphasis>not</emphasis> a <quote>one to " | |
4213 "one</quote> relationship between revisions in the changelog, manifest, or " | |
4214 "filelog. If the manifest hasn't changed between two changesets, the changelog " | |
4215 "entries for those changesets will point to the same revision of the " | |
4216 "manifest. If a file that Mercurial tracks hasn't changed between two " | |
4217 "changesets, the entry for that file in the two revisions of the manifest will " | |
4218 "point to the same revision of its filelog." | |
4219 msgstr "" | |
4220 | |
4221 #. type: Content of: <book><chapter><sect1><title> | |
4222 #: ../en/ch04-concepts.xml:123 | |
4223 msgid "Safe, efficient storage" | |
4224 msgstr "安全,高效的存储" | |
4225 | |
4226 #. type: Content of: <book><chapter><sect1><para> | |
4227 #: ../en/ch04-concepts.xml:125 | |
4228 msgid "" | |
4229 "The underpinnings of changelogs, manifests, and filelogs are provided by a " | |
4230 "single structure called the <emphasis>revlog</emphasis>." | |
4231 msgstr "" | |
4232 | |
4233 #. type: Content of: <book><chapter><sect1><sect2><title> | |
4234 #: ../en/ch04-concepts.xml:130 | |
4235 msgid "Efficient storage" | |
4236 msgstr "高效存储" | |
4237 | |
4238 #. type: Content of: <book><chapter><sect1><sect2><para> | |
4239 #: ../en/ch04-concepts.xml:132 | |
4240 msgid "" | |
4241 "The revlog provides efficient storage of revisions using a <emphasis>delta</" | |
4242 "emphasis> mechanism. Instead of storing a complete copy of a file for each " | |
4243 "revision, it stores the changes needed to transform an older revision into " | |
4244 "the new revision. For many kinds of file data, these deltas are typically a " | |
4245 "fraction of a percent of the size of a full copy of a file." | |
4246 msgstr "" | |
4247 | |
4248 #. type: Content of: <book><chapter><sect1><sect2><para> | |
4249 #: ../en/ch04-concepts.xml:140 | |
4250 msgid "" | |
4251 "Some obsolete revision control systems can only work with deltas of text " | |
4252 "files. They must either store binary files as complete snapshots or encoded " | |
4253 "into a text representation, both of which are wasteful approaches. Mercurial " | |
4254 "can efficiently handle deltas of files with arbitrary binary contents; it " | |
4255 "doesn't need to treat text as special." | |
4256 msgstr "" | |
4257 | |
4258 #. type: Content of: <book><chapter><sect1><sect2><title> | |
4259 #: ../en/ch04-concepts.xml:149 | |
4260 msgid "Safe operation" | |
4261 msgstr "安全操作" | |
4262 | |
4263 #. type: Content of: <book><chapter><sect1><sect2><para> | |
4264 #: ../en/ch04-concepts.xml:151 | |
4265 msgid "" | |
4266 "Mercurial only ever <emphasis>appends</emphasis> data to the end of a revlog " | |
4267 "file. It never modifies a section of a file after it has written it. This is " | |
4268 "both more robust and efficient than schemes that need to modify or rewrite " | |
4269 "data." | |
4270 msgstr "" | |
4271 | |
4272 #. type: Content of: <book><chapter><sect1><sect2><para> | |
4273 #: ../en/ch04-concepts.xml:157 | |
4274 msgid "" | |
4275 "In addition, Mercurial treats every write as part of a <emphasis>transaction</" | |
4276 "emphasis> that can span a number of files. A transaction is " | |
4277 "<emphasis>atomic</emphasis>: either the entire transaction succeeds and its " | |
4278 "effects are all visible to readers in one go, or the whole thing is undone. " | |
4279 "This guarantee of atomicity means that if you're running two copies of " | |
4280 "Mercurial, where one is reading data and one is writing it, the reader will " | |
4281 "never see a partially written result that might confuse it." | |
4282 msgstr "" | |
4283 | |
4284 #. type: Content of: <book><chapter><sect1><sect2><para> | |
4285 #: ../en/ch04-concepts.xml:167 | |
4286 msgid "" | |
4287 "The fact that Mercurial only appends to files makes it easier to provide this " | |
4288 "transactional guarantee. The easier it is to do stuff like this, the more " | |
4289 "confident you should be that it's done correctly." | |
4290 msgstr "" | |
4291 | |
4292 #. type: Content of: <book><chapter><sect1><sect2><title> | |
4293 #: ../en/ch04-concepts.xml:174 | |
4294 msgid "Fast retrieval" | |
4295 msgstr "快速检索" | |
4296 | |
4297 #. type: Content of: <book><chapter><sect1><sect2><para> | |
4298 #: ../en/ch04-concepts.xml:176 | |
4299 msgid "" | |
4300 "Mercurial cleverly avoids a pitfall common to all earlier revision control " | |
4301 "systems: the problem of <emphasis>inefficient retrieval</emphasis>. Most " | |
4302 "revision control systems store the contents of a revision as an incremental " | |
4303 "series of modifications against a <quote>snapshot</quote>. To reconstruct a " | |
4304 "specific revision, you must first read the snapshot, and then every one of " | |
4305 "the revisions between the snapshot and your target revision. The more " | |
4306 "history that a file accumulates, the more revisions you must read, hence the " | |
4307 "longer it takes to reconstruct a particular revision." | |
4308 msgstr "" | |
4309 | |
4310 #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject> | |
4311 #: ../en/ch04-concepts.xml:188 | |
4312 msgid "<imageobject><imagedata fileref=\"images/snapshot.png\"/></imageobject>" | |
4313 msgstr "" | |
4314 | |
4315 #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject><caption><para> | |
4316 #: ../en/ch04-concepts.xml:190 | |
4317 msgid "Snapshot of a revlog, with incremental deltas" | |
4318 msgstr "" | |
4319 | |
4320 #. type: Content of: <book><chapter><sect1><sect2><para> | |
4321 #: ../en/ch04-concepts.xml:195 | |
4322 msgid "" | |
4323 "The innovation that Mercurial applies to this problem is simple but " | |
4324 "effective. Once the cumulative amount of delta information stored since the " | |
4325 "last snapshot exceeds a fixed threshold, it stores a new snapshot " | |
4326 "(compressed, of course), instead of another delta. This makes it possible to " | |
4327 "reconstruct <emphasis>any</emphasis> revision of a file quickly. This " | |
4328 "approach works so well that it has since been copied by several other " | |
4329 "revision control systems." | |
4330 msgstr "" | |
4331 | |
4332 #. type: Content of: <book><chapter><sect1><sect2><para> | |
4333 #: ../en/ch04-concepts.xml:204 | |
4334 msgid "" | |
4335 "Figure <xref linkend=\"fig.concepts.snapshot\"/> illustrates the idea. In an " | |
4336 "entry in a revlog's index file, Mercurial stores the range of entries from " | |
4337 "the data file that it must read to reconstruct a particular revision." | |
4338 msgstr "" | |
4339 | |
4340 #. type: Content of: <book><chapter><sect1><sect2><sect3><title> | |
4341 #: ../en/ch04-concepts.xml:210 | |
4342 msgid "Aside: the influence of video compression" | |
4343 msgstr "" | |
4344 | |
4345 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
4346 #: ../en/ch04-concepts.xml:212 | |
4347 msgid "" | |
4348 "If you're familiar with video compression or have ever watched a TV feed " | |
4349 "through a digital cable or satellite service, you may know that most video " | |
4350 "compression schemes store each frame of video as a delta against its " | |
4351 "predecessor frame. In addition, these schemes use <quote>lossy</quote> " | |
4352 "compression techniques to increase the compression ratio, so visual errors " | |
4353 "accumulate over the course of a number of inter-frame deltas." | |
4354 msgstr "" | |
4355 | |
4356 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
4357 #: ../en/ch04-concepts.xml:221 | |
4358 msgid "" | |
4359 "Because it's possible for a video stream to <quote>drop out</quote> " | |
4360 "occasionally due to signal glitches, and to limit the accumulation of " | |
4361 "artefacts introduced by the lossy compression process, video encoders " | |
4362 "periodically insert a complete frame (called a <quote>key frame</quote>) into " | |
4363 "the video stream; the next delta is generated against that frame. This means " | |
4364 "that if the video signal gets interrupted, it will resume once the next key " | |
4365 "frame is received. Also, the accumulation of encoding errors restarts anew " | |
4366 "with each key frame." | |
4367 msgstr "" | |
4368 | |
4369 #. type: Content of: <book><chapter><sect1><sect2><title> | |
4370 #: ../en/ch04-concepts.xml:235 | |
4371 msgid "Identification and strong integrity" | |
4372 msgstr "鉴别和强完整性" | |
4373 | |
4374 #. type: Content of: <book><chapter><sect1><sect2><para> | |
4375 #: ../en/ch04-concepts.xml:237 | |
4376 msgid "" | |
4377 "Along with delta or snapshot information, a revlog entry contains a " | |
4378 "cryptographic hash of the data that it represents. This makes it difficult " | |
4379 "to forge the contents of a revision, and easy to detect accidental corruption." | |
4380 msgstr "" | |
4381 | |
4382 #. type: Content of: <book><chapter><sect1><sect2><para> | |
4383 #: ../en/ch04-concepts.xml:242 | |
4384 msgid "" | |
4385 "Hashes provide more than a mere check against corruption; they are used as " | |
4386 "the identifiers for revisions. The changeset identification hashes that you " | |
4387 "see as an end user are from revisions of the changelog. Although filelogs " | |
4388 "and the manifest also use hashes, Mercurial only uses these behind the scenes." | |
4389 msgstr "" | |
4390 | |
4391 #. type: Content of: <book><chapter><sect1><sect2><para> | |
4392 #: ../en/ch04-concepts.xml:249 | |
4393 msgid "" | |
4394 "Mercurial verifies that hashes are correct when it retrieves file revisions " | |
4395 "and when it pulls changes from another repository. If it encounters an " | |
4396 "integrity problem, it will complain and stop whatever it's doing." | |
4397 msgstr "" | |
4398 | |
4399 #. type: Content of: <book><chapter><sect1><sect2><para> | |
4400 #: ../en/ch04-concepts.xml:254 | |
4401 msgid "" | |
4402 "In addition to the effect it has on retrieval efficiency, Mercurial's use of " | |
4403 "periodic snapshots makes it more robust against partial data corruption. If " | |
4404 "a revlog becomes partly corrupted due to a hardware error or system bug, it's " | |
4405 "often possible to reconstruct some or most revisions from the uncorrupted " | |
4406 "sections of the revlog, both before and after the corrupted section. This " | |
4407 "would not be possible with a delta-only storage model." | |
4408 msgstr "" | |
4409 | |
4410 #. type: Content of: <book><chapter><sect1><title> | |
4411 #: ../en/ch04-concepts.xml:266 | |
4412 msgid "Revision history, branching, and merging" | |
4413 msgstr "修订历史,分支与合并" | |
4414 | |
4415 #. type: Content of: <book><chapter><sect1><para> | |
4416 #: ../en/ch04-concepts.xml:268 | |
4417 msgid "" | |
4418 "Every entry in a Mercurial revlog knows the identity of its immediate " | |
4419 "ancestor revision, usually referred to as its <emphasis>parent</emphasis>. " | |
4420 "In fact, a revision contains room for not one parent, but two. Mercurial " | |
4421 "uses a special hash, called the <quote>null ID</quote>, to represent the idea " | |
4422 "<quote>there is no parent here</quote>. This hash is simply a string of " | |
4423 "zeroes." | |
4424 msgstr "" | |
4425 | |
4426 #. type: Content of: <book><chapter><sect1><para> | |
4427 #: ../en/ch04-concepts.xml:276 | |
4428 msgid "" | |
4429 "In figure <xref linkend=\"fig.concepts.revlog\"/>, you can see an example of " | |
4430 "the conceptual structure of a revlog. Filelogs, manifests, and changelogs " | |
4431 "all have this same structure; they differ only in the kind of data stored in " | |
4432 "each delta or snapshot." | |
4433 msgstr "" | |
4434 | |
4435 #. type: Content of: <book><chapter><sect1><para> | |
4436 #: ../en/ch04-concepts.xml:282 | |
4437 msgid "" | |
4438 "The first revision in a revlog (at the bottom of the image) has the null ID " | |
4439 "in both of its parent slots. For a <quote>normal</quote> revision, its first " | |
4440 "parent slot contains the ID of its parent revision, and its second contains " | |
4441 "the null ID, indicating that the revision has only one real parent. Any two " | |
4442 "revisions that have the same parent ID are branches. A revision that " | |
4443 "represents a merge between branches has two normal revision IDs in its parent " | |
4444 "slots." | |
4445 msgstr "" | |
4446 | |
4447 #. type: Content of: <book><chapter><sect1><informalfigure><mediaobject> | |
4448 #: ../en/ch04-concepts.xml:292 | |
4449 msgid "<imageobject><imagedata fileref=\"images/revlog.png\"/></imageobject>" | |
4450 msgstr "" | |
4451 | |
4452 #. type: Content of: <book><chapter><sect1><title> | |
4453 #: ../en/ch04-concepts.xml:299 | |
4454 msgid "The working directory" | |
4455 msgstr "工作目录" | |
4456 | |
4457 #. type: Content of: <book><chapter><sect1><para> | |
4458 #: ../en/ch04-concepts.xml:301 | |
4459 msgid "" | |
4460 "In the working directory, Mercurial stores a snapshot of the files from the " | |
4461 "repository as of a particular changeset." | |
4462 msgstr "" | |
4463 | |
4464 #. type: Content of: <book><chapter><sect1><para> | |
4465 #: ../en/ch04-concepts.xml:304 | |
4466 msgid "" | |
4467 "The working directory <quote>knows</quote> which changeset it contains. When " | |
4468 "you update the working directory to contain a particular changeset, Mercurial " | |
4469 "looks up the appropriate revision of the manifest to find out which files it " | |
4470 "was tracking at the time that changeset was committed, and which revision of " | |
4471 "each file was then current. It then recreates a copy of each of those files, " | |
4472 "with the same contents it had when the changeset was committed." | |
4473 msgstr "" | |
4474 | |
4475 #. type: Content of: <book><chapter><sect1><para> | |
4476 #: ../en/ch04-concepts.xml:313 | |
4477 msgid "" | |
4478 "The <emphasis>dirstate</emphasis> contains Mercurial's knowledge of the " | |
4479 "working directory. This details which changeset the working directory is " | |
4480 "updated to, and all of the files that Mercurial is tracking in the working " | |
4481 "directory." | |
4482 msgstr "" | |
4483 | |
4484 #. type: Content of: <book><chapter><sect1><para> | |
4485 #: ../en/ch04-concepts.xml:319 | |
4486 msgid "" | |
4487 "Just as a revision of a revlog has room for two parents, so that it can " | |
4488 "represent either a normal revision (with one parent) or a merge of two " | |
4489 "earlier revisions, the dirstate has slots for two parents. When you use the " | |
4490 "<command role=\"hg-cmd\">hg update</command> command, the changeset that you " | |
4491 "update to is stored in the <quote>first parent</quote> slot, and the null ID " | |
4492 "in the second. When you <command role=\"hg-cmd\">hg merge</command> with " | |
4493 "another changeset, the first parent remains unchanged, and the second parent " | |
4494 "is filled in with the changeset you're merging with. The <command role=\"hg-" | |
4495 "cmd\">hg parents</command> command tells you what the parents of the dirstate " | |
4496 "are." | |
4497 msgstr "" | |
4498 | |
4499 #. type: Content of: <book><chapter><sect1><sect2><title> | |
4500 #: ../en/ch04-concepts.xml:333 | |
4501 msgid "What happens when you commit" | |
4502 msgstr "当你提交时发生的事情" | |
4503 | |
4504 #. type: Content of: <book><chapter><sect1><sect2><para> | |
4505 #: ../en/ch04-concepts.xml:335 | |
4506 msgid "" | |
4507 "The dirstate stores parent information for more than just book-keeping " | |
4508 "purposes. Mercurial uses the parents of the dirstate as <emphasis>the " | |
4509 "parents of a new changeset</emphasis> when you perform a commit." | |
4510 msgstr "" | |
4511 | |
4512 #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject> | |
4513 #: ../en/ch04-concepts.xml:341 | |
4514 msgid "<imageobject><imagedata fileref=\"images/wdir.png\"/></imageobject>" | |
4515 msgstr "" | |
4516 | |
4517 #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject><caption><para> | |
4518 #: ../en/ch04-concepts.xml:343 | |
4519 msgid "The working directory can have two parents" | |
4520 msgstr "" | |
4521 | |
4522 #. type: Content of: <book><chapter><sect1><sect2><para> | |
4523 #: ../en/ch04-concepts.xml:348 | |
4524 msgid "" | |
4525 "Figure <xref linkend=\"fig.concepts.wdir\"/> shows the normal state of the " | |
4526 "working directory, where it has a single changeset as parent. That changeset " | |
4527 "is the <emphasis>tip</emphasis>, the newest changeset in the repository that " | |
4528 "has no children." | |
4529 msgstr "" | |
4530 | |
4531 #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject> | |
4532 #: ../en/ch04-concepts.xml:355 | |
4533 msgid "" | |
4534 "<imageobject><imagedata fileref=\"images/wdir-after-commit.png\"/></" | |
4535 "imageobject>" | |
4536 msgstr "" | |
4537 | |
4538 #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject><caption><para> | |
4539 #: ../en/ch04-concepts.xml:357 | |
4540 msgid "The working directory gains new parents after a commit" | |
4541 msgstr "" | |
4542 | |
4543 #. type: Content of: <book><chapter><sect1><sect2><para> | |
4544 #: ../en/ch04-concepts.xml:362 | |
4545 msgid "" | |
4546 "It's useful to think of the working directory as <quote>the changeset I'm " | |
4547 "about to commit</quote>. Any files that you tell Mercurial that you've " | |
4548 "added, removed, renamed, or copied will be reflected in that changeset, as " | |
4549 "will modifications to any files that Mercurial is already tracking; the new " | |
4550 "changeset will have the parents of the working directory as its parents." | |
4551 msgstr "" | |
4552 | |
4553 #. type: Content of: <book><chapter><sect1><sect2><para> | |
4554 #: ../en/ch04-concepts.xml:370 | |
4555 msgid "" | |
4556 "After a commit, Mercurial will update the parents of the working directory, " | |
4557 "so that the first parent is the ID of the new changeset, and the second is " | |
4558 "the null ID. This is shown in figure <xref linkend=\"fig.concepts.wdir-after-" | |
4559 "commit\"/>. Mercurial doesn't touch any of the files in the working " | |
4560 "directory when you commit; it just modifies the dirstate to note its new " | |
4561 "parents." | |
4562 msgstr "" | |
4563 | |
4564 #. type: Content of: <book><chapter><sect1><sect2><title> | |
4565 #: ../en/ch04-concepts.xml:381 | |
4566 msgid "Creating a new head" | |
4567 msgstr "创建新顶点" | |
4568 | |
4569 #. type: Content of: <book><chapter><sect1><sect2><para> | |
4570 #: ../en/ch04-concepts.xml:383 | |
4571 msgid "" | |
4572 "It's perfectly normal to update the working directory to a changeset other " | |
4573 "than the current tip. For example, you might want to know what your project " | |
4574 "looked like last Tuesday, or you could be looking through changesets to see " | |
4575 "which one introduced a bug. In cases like this, the natural thing to do is " | |
4576 "update the working directory to the changeset you're interested in, and then " | |
4577 "examine the files in the working directory directly to see their contents as " | |
4578 "they were when you committed that changeset. The effect of this is shown in " | |
4579 "figure <xref linkend=\"fig.concepts.wdir-pre-branch\"/>." | |
4580 msgstr "" | |
4581 | |
4582 #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject> | |
4583 #: ../en/ch04-concepts.xml:395 | |
4584 msgid "" | |
4585 "<imageobject><imagedata fileref=\"images/wdir-pre-branch.png\"/></imageobject>" | |
4586 msgstr "" | |
4587 | |
4588 #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject><caption><para> | |
4589 #: ../en/ch04-concepts.xml:397 | |
4590 msgid "The working directory, updated to an older changeset" | |
4591 msgstr "" | |
4592 | |
4593 #. type: Content of: <book><chapter><sect1><sect2><para> | |
4594 #: ../en/ch04-concepts.xml:402 | |
4595 msgid "" | |
4596 "Having updated the working directory to an older changeset, what happens if " | |
4597 "you make some changes, and then commit? Mercurial behaves in the same way as " | |
4598 "I outlined above. The parents of the working directory become the parents of " | |
4599 "the new changeset. This new changeset has no children, so it becomes the new " | |
4600 "tip. And the repository now contains two changesets that have no children; " | |
4601 "we call these <emphasis>heads</emphasis>. You can see the structure that " | |
4602 "this creates in figure <xref linkend=\"fig.concepts.wdir-branch\"/>." | |
4603 msgstr "" | |
4604 | |
4605 #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject> | |
4606 #: ../en/ch04-concepts.xml:414 | |
4607 msgid "" | |
4608 "<imageobject><imagedata fileref=\"images/wdir-branch.png\"/></imageobject>" | |
4609 msgstr "" | |
4610 | |
4611 #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject><caption><para> | |
4612 #: ../en/ch04-concepts.xml:416 | |
4613 msgid "After a commit made while synced to an older changeset" | |
4614 msgstr "" | |
4615 | |
4616 #. type: Content of: <book><chapter><sect1><sect2><note><para> | |
4617 #: ../en/ch04-concepts.xml:422 | |
4618 msgid "" | |
4619 "If you're new to Mercurial, you should keep in mind a common <quote>error</" | |
4620 "quote>, which is to use the <command role=\"hg-cmd\">hg pull</command> " | |
4621 "command without any options. By default, the <command role=\"hg-cmd\">hg " | |
4622 "pull</command> command <emphasis>does not</emphasis> update the working " | |
4623 "directory, so you'll bring new changesets into your repository, but the " | |
4624 "working directory will stay synced at the same changeset as before the pull. " | |
4625 "If you make some changes and commit afterwards, you'll thus create a new " | |
4626 "head, because your working directory isn't synced to whatever the current tip " | |
4627 "is." | |
4628 msgstr "" | |
4629 | |
4630 #. type: Content of: <book><chapter><sect1><sect2><note><para> | |
4631 #: ../en/ch04-concepts.xml:434 | |
4632 msgid "" | |
4633 "I put the word <quote>error</quote> in quotes because all that you need to do " | |
4634 "to rectify this situation is <command role=\"hg-cmd\">hg merge</command>, " | |
4635 "then <command role=\"hg-cmd\">hg commit</command>. In other words, this " | |
4636 "almost never has negative consequences; it just surprises people. I'll " | |
4637 "discuss other ways to avoid this behaviour, and why Mercurial behaves in this " | |
4638 "initially surprising way, later on." | |
4639 msgstr "" | |
4640 | |
4641 #. type: Content of: <book><chapter><sect1><sect2><title> | |
4642 #: ../en/ch04-concepts.xml:446 | |
4643 msgid "Merging heads" | |
4644 msgstr "合并顶点" | |
4645 | |
4646 #. type: Content of: <book><chapter><sect1><sect2><para> | |
4647 #: ../en/ch04-concepts.xml:448 | |
4648 msgid "" | |
4649 "When you run the <command role=\"hg-cmd\">hg merge</command> command, " | |
4650 "Mercurial leaves the first parent of the working directory unchanged, and " | |
4651 "sets the second parent to the changeset you're merging with, as shown in " | |
4652 "figure <xref linkend=\"fig.concepts.wdir-merge\"/>." | |
4653 msgstr "" | |
4654 | |
4655 #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject> | |
4656 #: ../en/ch04-concepts.xml:455 | |
4657 msgid "" | |
4658 "<imageobject><imagedata fileref=\"images/wdir-merge.png\"/></imageobject>" | |
4659 msgstr "" | |
4660 | |
4661 #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject><caption><para> | |
4662 #: ../en/ch04-concepts.xml:457 | |
4663 msgid "Merging two heads" | |
4664 msgstr "" | |
4665 | |
4666 #. type: Content of: <book><chapter><sect1><sect2><para> | |
4667 #: ../en/ch04-concepts.xml:461 | |
4668 msgid "" | |
4669 "Mercurial also has to modify the working directory, to merge the files " | |
4670 "managed in the two changesets. Simplified a little, the merging process goes " | |
4671 "like this, for every file in the manifests of both changesets." | |
4672 msgstr "" | |
4673 | |
4674 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
4675 #: ../en/ch04-concepts.xml:466 | |
4676 msgid "If neither changeset has modified a file, do nothing with that file." | |
4677 msgstr "" | |
4678 | |
4679 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
4680 #: ../en/ch04-concepts.xml:469 | |
4681 msgid "" | |
4682 "If one changeset has modified a file, and the other hasn't, create the " | |
4683 "modified copy of the file in the working directory." | |
4684 msgstr "" | |
4685 | |
4686 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
4687 #: ../en/ch04-concepts.xml:473 | |
4688 msgid "" | |
4689 "If one changeset has removed a file, and the other hasn't (or has also " | |
4690 "deleted it), delete the file from the working directory." | |
4691 msgstr "" | |
4692 | |
4693 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
4694 #: ../en/ch04-concepts.xml:477 | |
4695 msgid "" | |
4696 "If one changeset has removed a file, but the other has modified the file, ask " | |
4697 "the user what to do: keep the modified file, or remove it?" | |
4698 msgstr "" | |
4699 | |
4700 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
4701 #: ../en/ch04-concepts.xml:481 | |
4702 msgid "" | |
4703 "If both changesets have modified a file, invoke an external merge program to " | |
4704 "choose the new contents for the merged file. This may require input from the " | |
4705 "user." | |
4706 msgstr "" | |
4707 | |
4708 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
4709 #: ../en/ch04-concepts.xml:486 | |
4710 msgid "" | |
4711 "If one changeset has modified a file, and the other has renamed or copied the " | |
4712 "file, make sure that the changes follow the new name of the file." | |
4713 msgstr "" | |
4714 | |
4715 #. type: Content of: <book><chapter><sect1><sect2><para> | |
4716 #: ../en/ch04-concepts.xml:490 | |
4717 msgid "" | |
4718 "There are more details&emdash;merging has plenty of corner cases&emdash;but " | |
4719 "these are the most common choices that are involved in a merge. As you can " | |
4720 "see, most cases are completely automatic, and indeed most merges finish " | |
4721 "automatically, without requiring your input to resolve any conflicts." | |
4722 msgstr "" | |
4723 | |
4724 #. type: Content of: <book><chapter><sect1><sect2><para> | |
4725 #: ../en/ch04-concepts.xml:497 | |
4726 msgid "" | |
4727 "When you're thinking about what happens when you commit after a merge, once " | |
4728 "again the working directory is <quote>the changeset I'm about to commit</" | |
4729 "quote>. After the <command role=\"hg-cmd\">hg merge</command> command " | |
4730 "completes, the working directory has two parents; these will become the " | |
4731 "parents of the new changeset." | |
4732 msgstr "" | |
4733 | |
4734 #. type: Content of: <book><chapter><sect1><sect2><para> | |
4735 #: ../en/ch04-concepts.xml:504 | |
4736 msgid "" | |
4737 "Mercurial lets you perform multiple merges, but you must commit the results " | |
4738 "of each individual merge as you go. This is necessary because Mercurial only " | |
4739 "tracks two parents for both revisions and the working directory. While it " | |
4740 "would be technically possible to merge multiple changesets at once, the " | |
4741 "prospect of user confusion and making a terrible mess of a merge immediately " | |
4742 "becomes overwhelming." | |
4743 msgstr "" | |
4744 | |
4745 #. type: Content of: <book><chapter><sect1><title> | |
4746 #: ../en/ch04-concepts.xml:515 | |
4747 msgid "Other interesting design features" | |
4748 msgstr "其它有趣的设计特性" | |
4749 | |
4750 #. type: Content of: <book><chapter><sect1><para> | |
4751 #: ../en/ch04-concepts.xml:517 | |
4752 msgid "" | |
4753 "In the sections above, I've tried to highlight some of the most important " | |
4754 "aspects of Mercurial's design, to illustrate that it pays careful attention " | |
4755 "to reliability and performance. However, the attention to detail doesn't " | |
4756 "stop there. There are a number of other aspects of Mercurial's construction " | |
4757 "that I personally find interesting. I'll detail a few of them here, separate " | |
4758 "from the <quote>big ticket</quote> items above, so that if you're interested, " | |
4759 "you can gain a better idea of the amount of thinking that goes into a well-" | |
4760 "designed system." | |
4761 msgstr "" | |
4762 | |
4763 #. type: Content of: <book><chapter><sect1><sect2><title> | |
4764 #: ../en/ch04-concepts.xml:528 | |
4765 msgid "Clever compression" | |
4766 msgstr "智能压缩" | |
4767 | |
4768 #. type: Content of: <book><chapter><sect1><sect2><para> | |
4769 #: ../en/ch04-concepts.xml:530 | |
4770 msgid "" | |
4771 "When appropriate, Mercurial will store both snapshots and deltas in " | |
4772 "compressed form. It does this by always <emphasis>trying to</emphasis> " | |
4773 "compress a snapshot or delta, but only storing the compressed version if it's " | |
4774 "smaller than the uncompressed version." | |
4775 msgstr "" | |
4776 | |
4777 #. type: Content of: <book><chapter><sect1><sect2><para> | |
4778 #: ../en/ch04-concepts.xml:536 | |
4779 msgid "" | |
4780 "This means that Mercurial does <quote>the right thing</quote> when storing a " | |
4781 "file whose native form is compressed, such as a <literal>zip</literal> " | |
4782 "archive or a JPEG image. When these types of files are compressed a second " | |
4783 "time, the resulting file is usually bigger than the once-compressed form, and " | |
4784 "so Mercurial will store the plain <literal>zip</literal> or JPEG." | |
4785 msgstr "" | |
4786 | |
4787 #. type: Content of: <book><chapter><sect1><sect2><para> | |
4788 #: ../en/ch04-concepts.xml:544 | |
4789 msgid "" | |
4790 "Deltas between revisions of a compressed file are usually larger than " | |
4791 "snapshots of the file, and Mercurial again does <quote>the right thing</" | |
4792 "quote> in these cases. It finds that such a delta exceeds the threshold at " | |
4793 "which it should store a complete snapshot of the file, so it stores the " | |
4794 "snapshot, again saving space compared to a naive delta-only approach." | |
4795 msgstr "" | |
4796 | |
4797 #. type: Content of: <book><chapter><sect1><sect2><sect3><title> | |
4798 #: ../en/ch04-concepts.xml:553 | |
4799 msgid "Network recompression" | |
4800 msgstr "网络重新压缩" | |
4801 | |
4802 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
4803 #: ../en/ch04-concepts.xml:555 | |
4804 msgid "" | |
4805 "When storing revisions on disk, Mercurial uses the <quote>deflate</quote> " | |
4806 "compression algorithm (the same one used by the popular <literal>zip</" | |
4807 "literal> archive format), which balances good speed with a respectable " | |
4808 "compression ratio. However, when transmitting revision data over a network " | |
4809 "connection, Mercurial uncompresses the compressed revision data." | |
4810 msgstr "" | |
4811 | |
4812 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
4813 #: ../en/ch04-concepts.xml:563 | |
4814 msgid "" | |
4815 "If the connection is over HTTP, Mercurial recompresses the entire stream of " | |
4816 "data using a compression algorithm that gives a better compression ratio (the " | |
4817 "Burrows-Wheeler algorithm from the widely used <literal>bzip2</literal> " | |
4818 "compression package). This combination of algorithm and compression of the " | |
4819 "entire stream (instead of a revision at a time) substantially reduces the " | |
4820 "number of bytes to be transferred, yielding better network performance over " | |
4821 "almost all kinds of network." | |
4822 msgstr "" | |
4823 | |
4824 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
4825 #: ../en/ch04-concepts.xml:573 | |
4826 msgid "" | |
4827 "(If the connection is over <command>ssh</command>, Mercurial " | |
4828 "<emphasis>doesn't</emphasis> recompress the stream, because <command>ssh</" | |
4829 "command> can already do this itself.)" | |
4830 msgstr "" | |
4831 | |
4832 #. type: Content of: <book><chapter><sect1><sect2><title> | |
4833 #: ../en/ch04-concepts.xml:581 | |
4834 msgid "Read/write ordering and atomicity" | |
4835 msgstr "读写顺序与原子性" | |
4836 | |
4837 #. type: Content of: <book><chapter><sect1><sect2><para> | |
4838 #: ../en/ch04-concepts.xml:583 | |
4839 msgid "" | |
4840 "Appending to files isn't the whole story when it comes to guaranteeing that a " | |
4841 "reader won't see a partial write. If you recall figure <xref linkend=\"fig." | |
4842 "concepts.metadata\"/>, revisions in the changelog point to revisions in the " | |
4843 "manifest, and revisions in the manifest point to revisions in filelogs. This " | |
4844 "hierarchy is deliberate." | |
4845 msgstr "" | |
4846 | |
4847 #. type: Content of: <book><chapter><sect1><sect2><para> | |
4848 #: ../en/ch04-concepts.xml:591 | |
4849 msgid "" | |
4850 "A writer starts a transaction by writing filelog and manifest data, and " | |
4851 "doesn't write any changelog data until those are finished. A reader starts " | |
4852 "by reading changelog data, then manifest data, followed by filelog data." | |
4853 msgstr "" | |
4854 | |
4855 #. type: Content of: <book><chapter><sect1><sect2><para> | |
4856 #: ../en/ch04-concepts.xml:596 | |
4857 msgid "" | |
4858 "Since the writer has always finished writing filelog and manifest data before " | |
4859 "it writes to the changelog, a reader will never read a pointer to a partially " | |
4860 "written manifest revision from the changelog, and it will never read a " | |
4861 "pointer to a partially written filelog revision from the manifest." | |
4862 msgstr "" | |
4863 | |
4864 #. type: Content of: <book><chapter><sect1><sect2><title> | |
4865 #: ../en/ch04-concepts.xml:604 | |
4866 msgid "Concurrent access" | |
4867 msgstr "并发访问" | |
4868 | |
4869 #. type: Content of: <book><chapter><sect1><sect2><para> | |
4870 #: ../en/ch04-concepts.xml:606 | |
4871 msgid "" | |
4872 "The read/write ordering and atomicity guarantees mean that Mercurial never " | |
4873 "needs to <emphasis>lock</emphasis> a repository when it's reading data, even " | |
4874 "if the repository is being written to while the read is occurring. This has a " | |
4875 "big effect on scalability; you can have an arbitrary number of Mercurial " | |
4876 "processes safely reading data from a repository safely all at once, no matter " | |
4877 "whether it's being written to or not." | |
4878 msgstr "" | |
4879 | |
4880 #. type: Content of: <book><chapter><sect1><sect2><para> | |
4881 #: ../en/ch04-concepts.xml:615 | |
4882 msgid "" | |
4883 "The lockless nature of reading means that if you're sharing a repository on a " | |
4884 "multi-user system, you don't need to grant other local users permission to " | |
4885 "<emphasis>write</emphasis> to your repository in order for them to be able to " | |
4886 "clone it or pull changes from it; they only need <emphasis>read</emphasis> " | |
4887 "permission. (This is <emphasis>not</emphasis> a common feature among " | |
4888 "revision control systems, so don't take it for granted! Most require readers " | |
4889 "to be able to lock a repository to access it safely, and this requires write " | |
4890 "permission on at least one directory, which of course makes for all kinds of " | |
4891 "nasty and annoying security and administrative problems.)" | |
4892 msgstr "" | |
4893 | |
4894 #. type: Content of: <book><chapter><sect1><sect2><para> | |
4895 #: ../en/ch04-concepts.xml:628 | |
4896 msgid "" | |
4897 "Mercurial uses locks to ensure that only one process can write to a " | |
4898 "repository at a time (the locking mechanism is safe even over filesystems " | |
4899 "that are notoriously hostile to locking, such as NFS). If a repository is " | |
4900 "locked, a writer will wait for a while to retry if the repository becomes " | |
4901 "unlocked, but if the repository remains locked for too long, the process " | |
4902 "attempting to write will time out after a while. This means that your daily " | |
4903 "automated scripts won't get stuck forever and pile up if a system crashes " | |
4904 "unnoticed, for example. (Yes, the timeout is configurable, from zero to " | |
4905 "infinity.)" | |
4906 msgstr "" | |
4907 | |
4908 #. type: Content of: <book><chapter><sect1><sect2><sect3><title> | |
4909 #: ../en/ch04-concepts.xml:640 | |
4910 msgid "Safe dirstate access" | |
4911 msgstr "安全的目录状态访问" | |
4912 | |
4913 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
4914 #: ../en/ch04-concepts.xml:642 | |
4915 msgid "" | |
4916 "As with revision data, Mercurial doesn't take a lock to read the dirstate " | |
4917 "file; it does acquire a lock to write it. To avoid the possibility of " | |
4918 "reading a partially written copy of the dirstate file, Mercurial writes to a " | |
4919 "file with a unique name in the same directory as the dirstate file, then " | |
4920 "renames the temporary file atomically to <filename>dirstate</filename>. The " | |
4921 "file named <filename>dirstate</filename> is thus guaranteed to be complete, " | |
4922 "not partially written." | |
4923 msgstr "" | |
4924 | |
4925 #. type: Content of: <book><chapter><sect1><sect2><title> | |
4926 #: ../en/ch04-concepts.xml:655 | |
4927 msgid "Avoiding seeks" | |
4928 msgstr "避免查找" | |
4929 | |
4930 #. type: Content of: <book><chapter><sect1><sect2><para> | |
4931 #: ../en/ch04-concepts.xml:657 | |
4932 msgid "" | |
4933 "Critical to Mercurial's performance is the avoidance of seeks of the disk " | |
4934 "head, since any seek is far more expensive than even a comparatively large " | |
4935 "read operation." | |
4936 msgstr "" | |
4937 | |
4938 #. type: Content of: <book><chapter><sect1><sect2><para> | |
4939 #: ../en/ch04-concepts.xml:661 | |
4940 msgid "" | |
4941 "This is why, for example, the dirstate is stored in a single file. If there " | |
4942 "were a dirstate file per directory that Mercurial tracked, the disk would " | |
4943 "seek once per directory. Instead, Mercurial reads the entire single dirstate " | |
4944 "file in one step." | |
4945 msgstr "" | |
4946 | |
4947 #. type: Content of: <book><chapter><sect1><sect2><para> | |
4948 #: ../en/ch04-concepts.xml:667 | |
4949 msgid "" | |
4950 "Mercurial also uses a <quote>copy on write</quote> scheme when cloning a " | |
4951 "repository on local storage. Instead of copying every revlog file from the " | |
4952 "old repository into the new repository, it makes a <quote>hard link</quote>, " | |
4953 "which is a shorthand way to say <quote>these two names point to the same " | |
4954 "file</quote>. When Mercurial is about to write to one of a revlog's files, " | |
4955 "it checks to see if the number of names pointing at the file is greater than " | |
4956 "one. If it is, more than one repository is using the file, so Mercurial " | |
4957 "makes a new copy of the file that is private to this repository." | |
4958 msgstr "" | |
4959 | |
4960 #. type: Content of: <book><chapter><sect1><sect2><para> | |
4961 #: ../en/ch04-concepts.xml:678 | |
4962 msgid "" | |
4963 "A few revision control developers have pointed out that this idea of making a " | |
4964 "complete private copy of a file is not very efficient in its use of storage. " | |
4965 "While this is true, storage is cheap, and this method gives the highest " | |
4966 "performance while deferring most book-keeping to the operating system. An " | |
4967 "alternative scheme would most likely reduce performance and increase the " | |
4968 "complexity of the software, each of which is much more important to the " | |
4969 "<quote>feel</quote> of day-to-day use." | |
4970 msgstr "" | |
4971 | |
4972 #. type: Content of: <book><chapter><sect1><sect2><title> | |
4973 #: ../en/ch04-concepts.xml:690 | |
4974 msgid "Other contents of the dirstate" | |
4975 msgstr "目录状态的其它内容" | |
4976 | |
4977 #. type: Content of: <book><chapter><sect1><sect2><para> | |
4978 #: ../en/ch04-concepts.xml:692 | |
4979 msgid "" | |
4980 "Because Mercurial doesn't force you to tell it when you're modifying a file, " | |
4981 "it uses the dirstate to store some extra information so it can determine " | |
4982 "efficiently whether you have modified a file. For each file in the working " | |
4983 "directory, it stores the time that it last modified the file itself, and the " | |
4984 "size of the file at that time." | |
4985 msgstr "" | |
4986 | |
4987 #. type: Content of: <book><chapter><sect1><sect2><para> | |
4988 #: ../en/ch04-concepts.xml:699 | |
4989 msgid "" | |
4990 "When you explicitly <command role=\"hg-cmd\">hg add</command>, <command role=" | |
4991 "\"hg-cmd\">hg remove</command>, <command role=\"hg-cmd\">hg rename</command> " | |
4992 "or <command role=\"hg-cmd\">hg copy</command> files, Mercurial updates the " | |
4993 "dirstate so that it knows what to do with those files when you commit." | |
4994 msgstr "" | |
4995 | |
4996 #. type: Content of: <book><chapter><sect1><sect2><para> | |
4997 #: ../en/ch04-concepts.xml:706 | |
4998 msgid "" | |
4999 "When Mercurial is checking the states of files in the working directory, it " | |
5000 "first checks a file's modification time. If that has not changed, the file " | |
5001 "must not have been modified. If the file's size has changed, the file must " | |
5002 "have been modified. If the modification time has changed, but the size has " | |
5003 "not, only then does Mercurial need to read the actual contents of the file to " | |
5004 "see if they've changed. Storing these few extra pieces of information " | |
5005 "dramatically reduces the amount of data that Mercurial needs to read, which " | |
5006 "yields large performance improvements compared to other revision control " | |
5007 "systems." | |
5008 msgstr "" | |
5009 | |
5010 #. type: Content of: <book><chapter><title> | |
5011 #: ../en/ch05-daily.xml:5 | |
5012 msgid "Mercurial in daily use" | |
5013 msgstr "Mercurial 的日常使用" | |
5014 | |
5015 #. type: Content of: <book><chapter><sect1><title> | |
5016 #: ../en/ch05-daily.xml:8 | |
5017 msgid "Telling Mercurial which files to track" | |
5018 msgstr "告诉 Mercurial 要跟踪哪些文件" | |
5019 | |
5020 #. type: Content of: <book><chapter><sect1><para> | |
5021 #: ../en/ch05-daily.xml:10 | |
5022 msgid "" | |
5023 "Mercurial does not work with files in your repository unless you tell it to " | |
5024 "manage them. The <command role=\"hg-cmd\">hg status</command> command will " | |
5025 "tell you which files Mercurial doesn't know about; it uses a <quote><literal>?" | |
5026 "</literal></quote> to display such files." | |
5027 msgstr "" | |
5028 | |
5029 # | |
5030 #. type: Content of: <book><chapter><sect1><para> | |
5031 #: ../en/ch05-daily.xml:17 | |
5032 msgid "" | |
5033 "To tell Mercurial to track a file, use the <command role=\"hg-cmd\">hg add</" | |
5034 "command> command. Once you have added a file, the entry in the output of " | |
5035 "<command role=\"hg-cmd\">hg status</command> for that file changes from " | |
5036 "<quote><literal>?</literal></quote> to <quote><literal>A</literal></quote>." | |
5037 msgstr "" | |
5038 | |
5039 #. type: Content of: <book><chapter><sect1><para> | |
5040 #: ../en/ch05-daily.xml:26 | |
5041 msgid "" | |
5042 "After you run a <command role=\"hg-cmd\">hg commit</command>, the files that " | |
5043 "you added before the commit will no longer be listed in the output of " | |
5044 "<command role=\"hg-cmd\">hg status</command>. The reason for this is that " | |
5045 "<command role=\"hg-cmd\">hg status</command> only tells you about " | |
5046 "<quote>interesting</quote> files&emdash;those that you have modified or told " | |
5047 "Mercurial to do something with&emdash;by default. If you have a repository " | |
5048 "that contains thousands of files, you will rarely want to know about files " | |
5049 "that Mercurial is tracking, but that have not changed. (You can still get " | |
5050 "this information; we'll return to this later.)" | |
5051 msgstr "" | |
5052 | |
5053 #. type: Content of: <book><chapter><sect1><para> | |
5054 #: ../en/ch05-daily.xml:38 | |
5055 msgid "" | |
5056 "Once you add a file, Mercurial doesn't do anything with it immediately. " | |
5057 "Instead, it will take a snapshot of the file's state the next time you " | |
5058 "perform a commit. It will then continue to track the changes you make to the " | |
5059 "file every time you commit, until you remove the file." | |
5060 msgstr "" | |
5061 | |
5062 #. type: Content of: <book><chapter><sect1><sect2><title> | |
5063 #: ../en/ch05-daily.xml:45 | |
5064 msgid "Explicit versus implicit file naming" | |
5065 msgstr "明确与隐含文件命名" | |
5066 | |
5067 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5068 #: ../en/ch05-daily.xml:47 | |
5069 msgid "" | |
5070 "A useful behaviour that Mercurial has is that if you pass the name of a " | |
5071 "directory to a command, every Mercurial command will treat this as <quote>I " | |
5072 "want to operate on every file in this directory and its subdirectories</" | |
5073 "quote>." | |
5074 msgstr "" | |
5075 | |
5076 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5077 #: ../en/ch05-daily.xml:54 | |
5078 msgid "" | |
5079 "Notice in this example that Mercurial printed the names of the files it " | |
5080 "added, whereas it didn't do so when we added the file named <filename>a</" | |
5081 "filename> in the earlier example." | |
5082 msgstr "" | |
5083 | |
5084 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5085 #: ../en/ch05-daily.xml:59 | |
5086 msgid "" | |
5087 "What's going on is that in the former case, we explicitly named the file to " | |
5088 "add on the command line, so the assumption that Mercurial makes in such cases " | |
5089 "is that you know what you were doing, and it doesn't print any output." | |
5090 msgstr "" | |
5091 | |
5092 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5093 #: ../en/ch05-daily.xml:64 | |
5094 msgid "" | |
5095 "However, when we <emphasis>imply</emphasis> the names of files by giving the " | |
5096 "name of a directory, Mercurial takes the extra step of printing the name of " | |
5097 "each file that it does something with. This makes it more clear what is " | |
5098 "happening, and reduces the likelihood of a silent and nasty surprise. This " | |
5099 "behaviour is common to most Mercurial commands." | |
5100 msgstr "" | |
5101 | |
5102 #. type: Content of: <book><chapter><sect1><sect2><title> | |
5103 #: ../en/ch05-daily.xml:73 | |
5104 msgid "Aside: Mercurial tracks files, not directories" | |
5105 msgstr "旁白: Mercurial 只跟踪文件,不跟踪目录" | |
5106 | |
5107 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5108 #: ../en/ch05-daily.xml:75 | |
5109 msgid "" | |
5110 "Mercurial does not track directory information. Instead, it tracks the path " | |
5111 "to a file. Before creating a file, it first creates any missing directory " | |
5112 "components of the path. After it deletes a file, it then deletes any empty " | |
5113 "directories that were in the deleted file's path. This sounds like a trivial " | |
5114 "distinction, but it has one minor practical consequence: it is not possible " | |
5115 "to represent a completely empty directory in Mercurial." | |
5116 msgstr "" | |
5117 | |
5118 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5119 #: ../en/ch05-daily.xml:84 | |
5120 msgid "" | |
5121 "Empty directories are rarely useful, and there are unintrusive workarounds " | |
5122 "that you can use to achieve an appropriate effect. The developers of " | |
5123 "Mercurial thus felt that the complexity that would be required to manage " | |
5124 "empty directories was not worth the limited benefit this feature would bring." | |
5125 msgstr "" | |
5126 | |
5127 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5128 #: ../en/ch05-daily.xml:91 | |
5129 msgid "" | |
5130 "If you need an empty directory in your repository, there are a few ways to " | |
5131 "achieve this. One is to create a directory, then <command role=\"hg-cmd\">hg " | |
5132 "add</command> a <quote>hidden</quote> file to that directory. On Unix-like " | |
5133 "systems, any file name that begins with a period (<quote><literal>.</" | |
5134 "literal></quote>) is treated as hidden by most commands and GUI tools. This " | |
5135 "approach is illustrated below." | |
5136 msgstr "" | |
5137 | |
5138 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5139 #: ../en/ch05-daily.xml:102 | |
5140 msgid "" | |
5141 "Another way to tackle a need for an empty directory is to simply create one " | |
5142 "in your automated build scripts before they will need it." | |
5143 msgstr "" | |
5144 | |
5145 #. type: Content of: <book><chapter><sect1><title> | |
5146 #: ../en/ch05-daily.xml:109 | |
5147 msgid "How to stop tracking a file" | |
5148 msgstr "如何停止跟踪文件" | |
5149 | |
5150 # | |
5151 #. type: Content of: <book><chapter><sect1><para> | |
5152 #: ../en/ch05-daily.xml:111 | |
5153 msgid "" | |
5154 "Once you decide that a file no longer belongs in your repository, use the " | |
5155 "<command role=\"hg-cmd\">hg remove</command> command; this deletes the file, " | |
5156 "and tells Mercurial to stop tracking it. A removed file is represented in " | |
5157 "the output of <command role=\"hg-cmd\">hg status</command> with a " | |
5158 "<quote><literal>R</literal></quote>." | |
5159 msgstr "" | |
5160 | |
5161 #. type: Content of: <book><chapter><sect1><para> | |
5162 #: ../en/ch05-daily.xml:120 | |
5163 msgid "" | |
5164 "After you <command role=\"hg-cmd\">hg remove</command> a file, Mercurial will " | |
5165 "no longer track changes to that file, even if you recreate a file with the " | |
5166 "same name in your working directory. If you do recreate a file with the same " | |
5167 "name and want Mercurial to track the new file, simply <command role=\"hg-cmd" | |
5168 "\">hg add</command> it. Mercurial will know that the newly added file is not " | |
5169 "related to the old file of the same name." | |
5170 msgstr "" | |
5171 | |
5172 #. type: Content of: <book><chapter><sect1><sect2><title> | |
5173 #: ../en/ch05-daily.xml:129 | |
5174 msgid "Removing a file does not affect its history" | |
5175 msgstr "删除文件不影响历史" | |
5176 | |
5177 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5178 #: ../en/ch05-daily.xml:131 | |
5179 msgid "It is important to understand that removing a file has only two effects." | |
5180 msgstr "" | |
5181 | |
5182 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
5183 #: ../en/ch05-daily.xml:134 | |
5184 msgid "It removes the current version of the file from the working directory." | |
5185 msgstr "" | |
5186 | |
5187 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
5188 #: ../en/ch05-daily.xml:137 | |
5189 msgid "" | |
5190 "It stops Mercurial from tracking changes to the file, from the time of the " | |
5191 "next commit." | |
5192 msgstr "" | |
5193 | |
5194 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5195 #: ../en/ch05-daily.xml:140 | |
5196 msgid "" | |
5197 "Removing a file <emphasis>does not</emphasis> in any way alter the " | |
5198 "<emphasis>history</emphasis> of the file." | |
5199 msgstr "" | |
5200 | |
5201 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5202 #: ../en/ch05-daily.xml:143 | |
5203 msgid "" | |
5204 "If you update the working directory to a changeset in which a file that you " | |
5205 "have removed was still tracked, it will reappear in the working directory, " | |
5206 "with the contents it had when you committed that changeset. If you then " | |
5207 "update the working directory to a later changeset, in which the file had been " | |
5208 "removed, Mercurial will once again remove the file from the working directory." | |
5209 msgstr "" | |
5210 | |
5211 #. type: Content of: <book><chapter><sect1><sect2><title> | |
5212 #: ../en/ch05-daily.xml:153 | |
5213 msgid "Missing files" | |
5214 msgstr "丢失的文件" | |
5215 | |
5216 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5217 #: ../en/ch05-daily.xml:155 | |
5218 msgid "" | |
5219 "Mercurial considers a file that you have deleted, but not used <command role=" | |
5220 "\"hg-cmd\">hg remove</command> to delete, to be <emphasis>missing</" | |
5221 "emphasis>. A missing file is represented with <quote><literal>!</literal></" | |
5222 "quote> in the output of <command role=\"hg-cmd\">hg status</command>. " | |
5223 "Mercurial commands will not generally do anything with missing files." | |
5224 msgstr "" | |
5225 | |
5226 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5227 #: ../en/ch05-daily.xml:165 | |
5228 msgid "" | |
5229 "If your repository contains a file that <command role=\"hg-cmd\">hg status</" | |
5230 "command> reports as missing, and you want the file to stay gone, you can run " | |
5231 "<command role=\"hg-cmd\">hg remove <option role=\"hg-opt-remove\">--after</" | |
5232 "option></command> at any time later on, to tell Mercurial that you really did " | |
5233 "mean to remove the file." | |
5234 msgstr "" | |
5235 | |
5236 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5237 #: ../en/ch05-daily.xml:175 | |
5238 msgid "" | |
5239 "On the other hand, if you deleted the missing file by accident, give <command " | |
5240 "role=\"hg-cmd\">hg revert</command> the name of the file to recover. It will " | |
5241 "reappear, in unmodified form." | |
5242 msgstr "" | |
5243 | |
5244 #. type: Content of: <book><chapter><sect1><sect2><title> | |
5245 #: ../en/ch05-daily.xml:184 | |
5246 msgid "Aside: why tell Mercurial explicitly to remove a file?" | |
5247 msgstr "旁白: 为什么要明确告诉 Mercurial 删除文件?" | |
5248 | |
5249 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5250 #: ../en/ch05-daily.xml:187 | |
5251 msgid "" | |
5252 "You might wonder why Mercurial requires you to explicitly tell it that you " | |
5253 "are deleting a file. Early during the development of Mercurial, it let you " | |
5254 "delete a file however you pleased; Mercurial would notice the absence of the " | |
5255 "file automatically when you next ran a <command role=\"hg-cmd\">hg commit</" | |
5256 "command>, and stop tracking the file. In practice, this made it too easy to " | |
5257 "accidentally remove a file without noticing." | |
5258 msgstr "" | |
5259 | |
5260 #. type: Content of: <book><chapter><sect1><sect2><title> | |
5261 #: ../en/ch05-daily.xml:198 | |
5262 msgid "Useful shorthand&emdash;adding and removing files in one step" | |
5263 msgstr "有用的速记&emdash;一个步骤添加和删除文件" | |
5264 | |
5265 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5266 #: ../en/ch05-daily.xml:201 | |
5267 msgid "" | |
5268 "Mercurial offers a combination command, <command role=\"hg-cmd\">hg " | |
5269 "addremove</command>, that adds untracked files and marks missing files as " | |
5270 "removed." | |
5271 msgstr "" | |
5272 | |
5273 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5274 #: ../en/ch05-daily.xml:207 | |
5275 msgid "" | |
5276 "The <command role=\"hg-cmd\">hg commit</command> command also provides a " | |
5277 "<option role=\"hg-opt-commit\">-A</option> option that performs this same add-" | |
5278 "and-remove, immediately followed by a commit." | |
5279 msgstr "" | |
5280 | |
5281 #. type: Content of: <book><chapter><sect1><title> | |
5282 #: ../en/ch05-daily.xml:217 | |
5283 msgid "Copying files" | |
5284 msgstr "复制文件" | |
5285 | |
5286 #. type: Content of: <book><chapter><sect1><para> | |
5287 #: ../en/ch05-daily.xml:219 | |
5288 msgid "" | |
5289 "Mercurial provides a <command role=\"hg-cmd\">hg copy</command> command that " | |
5290 "lets you make a new copy of a file. When you copy a file using this command, " | |
5291 "Mercurial makes a record of the fact that the new file is a copy of the " | |
5292 "original file. It treats these copied files specially when you merge your " | |
5293 "work with someone else's." | |
5294 msgstr "" | |
5295 | |
5296 #. type: Content of: <book><chapter><sect1><sect2><title> | |
5297 #: ../en/ch05-daily.xml:227 | |
5298 msgid "The results of copying during a merge" | |
5299 msgstr "合并期间的复制结果" | |
5300 | |
5301 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5302 #: ../en/ch05-daily.xml:229 | |
5303 msgid "" | |
5304 "What happens during a merge is that changes <quote>follow</quote> a copy. To " | |
5305 "best illustrate what this means, let's create an example. We'll start with " | |
5306 "the usual tiny repository that contains a single file." | |
5307 msgstr "" | |
5308 | |
5309 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5310 #: ../en/ch05-daily.xml:236 | |
5311 msgid "" | |
5312 "We need to do some work in parallel, so that we'll have something to merge. " | |
5313 "So let's clone our repository." | |
5314 msgstr "" | |
5315 | |
5316 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5317 #: ../en/ch05-daily.xml:242 | |
5318 msgid "" | |
5319 "Back in our initial repository, let's use the <command role=\"hg-cmd\">hg " | |
5320 "copy</command> command to make a copy of the first file we created." | |
5321 msgstr "" | |
5322 | |
5323 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5324 #: ../en/ch05-daily.xml:248 | |
5325 msgid "" | |
5326 "If we look at the output of the <command role=\"hg-cmd\">hg status</command> " | |
5327 "command afterwards, the copied file looks just like a normal added file." | |
5328 msgstr "" | |
5329 | |
5330 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5331 #: ../en/ch05-daily.xml:254 | |
5332 msgid "" | |
5333 "But if we pass the <option role=\"hg-opt-status\">-C</option> option to " | |
5334 "<command role=\"hg-cmd\">hg status</command>, it prints another line of " | |
5335 "output: this is the file that our newly-added file was copied <emphasis>from</" | |
5336 "emphasis>." | |
5337 msgstr "" | |
5338 | |
5339 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5340 #: ../en/ch05-daily.xml:262 | |
5341 msgid "" | |
5342 "Now, back in the repository we cloned, let's make a change in parallel. " | |
5343 "We'll add a line of content to the original file that we created." | |
5344 msgstr "" | |
5345 | |
5346 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5347 #: ../en/ch05-daily.xml:268 | |
5348 msgid "" | |
5349 "Now we have a modified <filename>file</filename> in this repository. When we " | |
5350 "pull the changes from the first repository, and merge the two heads, " | |
5351 "Mercurial will propagate the changes that we made locally to <filename>file</" | |
5352 "filename> into its copy, <filename>new-file</filename>." | |
5353 msgstr "" | |
5354 | |
5355 #. type: Content of: <book><chapter><sect1><sect2><title> | |
5356 #: ../en/ch05-daily.xml:278 | |
5357 msgid "Why should changes follow copies?" | |
5358 msgstr "为什么复制后需要后续修改?" | |
5359 | |
5360 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5361 #: ../en/ch05-daily.xml:280 | |
5362 msgid "" | |
5363 "This behaviour, of changes to a file propagating out to copies of the file, " | |
5364 "might seem esoteric, but in most cases it's highly desirable." | |
5365 msgstr "" | |
5366 | |
5367 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5368 #: ../en/ch05-daily.xml:284 | |
5369 msgid "" | |
5370 "First of all, remember that this propagation <emphasis>only</emphasis> " | |
5371 "happens when you merge. So if you <command role=\"hg-cmd\">hg copy</command> " | |
5372 "a file, and subsequently modify the original file during the normal course of " | |
5373 "your work, nothing will happen." | |
5374 msgstr "" | |
5375 | |
5376 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5377 #: ../en/ch05-daily.xml:290 | |
5378 msgid "" | |
5379 "The second thing to know is that modifications will only propagate across a " | |
5380 "copy as long as the repository that you're pulling changes from " | |
5381 "<emphasis>doesn't know</emphasis> about the copy." | |
5382 msgstr "" | |
5383 | |
5384 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5385 #: ../en/ch05-daily.xml:295 | |
5386 msgid "" | |
5387 "The reason that Mercurial does this is as follows. Let's say I make an " | |
5388 "important bug fix in a source file, and commit my changes. Meanwhile, you've " | |
5389 "decided to <command role=\"hg-cmd\">hg copy</command> the file in your " | |
5390 "repository, without knowing about the bug or having seen the fix, and you " | |
5391 "have started hacking on your copy of the file." | |
5392 msgstr "" | |
5393 | |
5394 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5395 #: ../en/ch05-daily.xml:302 | |
5396 msgid "" | |
5397 "If you pulled and merged my changes, and Mercurial <emphasis>didn't</" | |
5398 "emphasis> propagate changes across copies, your source file would now contain " | |
5399 "the bug, and unless you remembered to propagate the bug fix by hand, the bug " | |
5400 "would <emphasis>remain</emphasis> in your copy of the file." | |
5401 msgstr "" | |
5402 | |
5403 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5404 #: ../en/ch05-daily.xml:308 | |
5405 msgid "" | |
5406 "By automatically propagating the change that fixed the bug from the original " | |
5407 "file to the copy, Mercurial prevents this class of problem. To my knowledge, " | |
5408 "Mercurial is the <emphasis>only</emphasis> revision control system that " | |
5409 "propagates changes across copies like this." | |
5410 msgstr "" | |
5411 | |
5412 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5413 #: ../en/ch05-daily.xml:314 | |
5414 msgid "" | |
5415 "Once your change history has a record that the copy and subsequent merge " | |
5416 "occurred, there's usually no further need to propagate changes from the " | |
5417 "original file to the copied file, and that's why Mercurial only propagates " | |
5418 "changes across copies until this point, and no further." | |
5419 msgstr "" | |
5420 | |
5421 #. type: Content of: <book><chapter><sect1><sect2><title> | |
5422 #: ../en/ch05-daily.xml:322 | |
5423 msgid "How to make changes <emphasis>not</emphasis> follow a copy" | |
5424 msgstr "如何让复制后<emphasis>不</emphasis>修改?" | |
5425 | |
5426 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5427 #: ../en/ch05-daily.xml:325 | |
5428 msgid "" | |
5429 "If, for some reason, you decide that this business of automatically " | |
5430 "propagating changes across copies is not for you, simply use your system's " | |
5431 "normal file copy command (on Unix-like systems, that's <command>cp</command>) " | |
5432 "to make a copy of a file, then <command role=\"hg-cmd\">hg add</command> the " | |
5433 "new copy by hand. Before you do so, though, please do reread section <xref " | |
5434 "linkend=\"sec.daily.why-copy\"/>, and make an informed decision that this " | |
5435 "behaviour is not appropriate to your specific case." | |
5436 msgstr "" | |
5437 | |
5438 #. type: Content of: <book><chapter><sect1><sect2><title> | |
5439 #: ../en/ch05-daily.xml:338 | |
5440 msgid "Behaviour of the <command role=\"hg-cmd\">hg copy</command> command" | |
5441 msgstr "命令 <command role=\"hg-cmd\">hg copy</command> 的特性" | |
5442 | |
5443 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5444 #: ../en/ch05-daily.xml:341 | |
5445 msgid "" | |
5446 "When you use the <command role=\"hg-cmd\">hg copy</command> command, " | |
5447 "Mercurial makes a copy of each source file as it currently stands in the " | |
5448 "working directory. This means that if you make some modifications to a file, " | |
5449 "then <command role=\"hg-cmd\">hg copy</command> it without first having " | |
5450 "committed those changes, the new copy will also contain the modifications you " | |
5451 "have made up until that point. (I find this behaviour a little " | |
5452 "counterintuitive, which is why I mention it here.)" | |
5453 msgstr "" | |
5454 | |
5455 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5456 #: ../en/ch05-daily.xml:351 | |
5457 msgid "" | |
5458 "The <command role=\"hg-cmd\">hg copy</command> command acts similarly to the " | |
5459 "Unix <command>cp</command> command (you can use the <command role=\"hg-cmd" | |
5460 "\">hg cp</command> alias if you prefer). The last argument is the " | |
5461 "<emphasis>destination</emphasis>, and all prior arguments are " | |
5462 "<emphasis>sources</emphasis>. If you pass it a single file as the source, " | |
5463 "and the destination does not exist, it creates a new file with that name." | |
5464 msgstr "" | |
5465 | |
5466 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5467 #: ../en/ch05-daily.xml:362 | |
5468 msgid "" | |
5469 "If the destination is a directory, Mercurial copies its sources into that " | |
5470 "directory." | |
5471 msgstr "" | |
5472 | |
5473 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5474 #: ../en/ch05-daily.xml:367 | |
5475 msgid "" | |
5476 "Copying a directory is recursive, and preserves the directory structure of " | |
5477 "the source." | |
5478 msgstr "" | |
5479 | |
5480 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5481 #: ../en/ch05-daily.xml:373 | |
5482 msgid "" | |
5483 "If the source and destination are both directories, the source tree is " | |
5484 "recreated in the destination directory." | |
5485 msgstr "" | |
5486 | |
5487 # | |
5488 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5489 #: ../en/ch05-daily.xml:378 | |
5490 msgid "" | |
5491 "As with the <command role=\"hg-cmd\">hg rename</command> command, if you copy " | |
5492 "a file manually and then want Mercurial to know that you've copied the file, " | |
5493 "simply use the <option role=\"hg-opt-copy\">--after</option> option to " | |
5494 "<command role=\"hg-cmd\">hg copy</command>." | |
5495 msgstr "" | |
5496 | |
5497 #. type: Content of: <book><chapter><sect1><title> | |
5498 #: ../en/ch05-daily.xml:389 | |
5499 msgid "Renaming files" | |
5500 msgstr "改名文件" | |
5501 | |
5502 #. type: Content of: <book><chapter><sect1><para> | |
5503 #: ../en/ch05-daily.xml:391 | |
5504 msgid "" | |
5505 "It's rather more common to need to rename a file than to make a copy of it. " | |
5506 "The reason I discussed the <command role=\"hg-cmd\">hg copy</command> command " | |
5507 "before talking about renaming files is that Mercurial treats a rename in " | |
5508 "essentially the same way as a copy. Therefore, knowing what Mercurial does " | |
5509 "when you copy a file tells you what to expect when you rename a file." | |
5510 msgstr "" | |
5511 | |
5512 #. type: Content of: <book><chapter><sect1><para> | |
5513 #: ../en/ch05-daily.xml:399 | |
5514 msgid "" | |
5515 "When you use the <command role=\"hg-cmd\">hg rename</command> command, " | |
5516 "Mercurial makes a copy of each source file, then deletes it and marks the " | |
5517 "file as removed." | |
5518 msgstr "" | |
5519 | |
5520 #. type: Content of: <book><chapter><sect1><para> | |
5521 #: ../en/ch05-daily.xml:405 | |
5522 msgid "" | |
5523 "The <command role=\"hg-cmd\">hg status</command> command shows the newly " | |
5524 "copied file as added, and the copied-from file as removed." | |
5525 msgstr "" | |
5526 | |
5527 #. type: Content of: <book><chapter><sect1><para> | |
5528 #: ../en/ch05-daily.xml:411 | |
5529 msgid "" | |
5530 "As with the results of a <command role=\"hg-cmd\">hg copy</command>, we must " | |
5531 "use the <option role=\"hg-opt-status\">-C</option> option to <command role=" | |
5532 "\"hg-cmd\">hg status</command> to see that the added file is really being " | |
5533 "tracked by Mercurial as a copy of the original, now removed, file." | |
5534 msgstr "" | |
5535 | |
5536 #. type: Content of: <book><chapter><sect1><para> | |
5537 #: ../en/ch05-daily.xml:420 | |
5538 msgid "" | |
5539 "As with <command role=\"hg-cmd\">hg remove</command> and <command role=\"hg-" | |
5540 "cmd\">hg copy</command>, you can tell Mercurial about a rename after the fact " | |
5541 "using the <option role=\"hg-opt-rename\">--after</option> option. In most " | |
5542 "other respects, the behaviour of the <command role=\"hg-cmd\">hg rename</" | |
5543 "command> command, and the options it accepts, are similar to the <command " | |
5544 "role=\"hg-cmd\">hg copy</command> command." | |
5545 msgstr "" | |
5546 | |
5547 #. type: Content of: <book><chapter><sect1><sect2><title> | |
5548 #: ../en/ch05-daily.xml:430 | |
5549 msgid "Renaming files and merging changes" | |
5550 msgstr "改名文件与合并修改" | |
5551 | |
5552 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5553 #: ../en/ch05-daily.xml:432 | |
5554 msgid "" | |
5555 "Since Mercurial's rename is implemented as copy-and-remove, the same " | |
5556 "propagation of changes happens when you merge after a rename as after a copy." | |
5557 msgstr "" | |
5558 | |
5559 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5560 #: ../en/ch05-daily.xml:436 | |
5561 msgid "" | |
5562 "If I modify a file, and you rename it to a new name, and then we merge our " | |
5563 "respective changes, my modifications to the file under its original name will " | |
5564 "be propagated into the file under its new name. (This is something you might " | |
5565 "expect to <quote>simply work,</quote> but not all revision control systems " | |
5566 "actually do this.)" | |
5567 msgstr "" | |
5568 | |
5569 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5570 #: ../en/ch05-daily.xml:443 | |
5571 msgid "" | |
5572 "Whereas having changes follow a copy is a feature where you can perhaps nod " | |
5573 "and say <quote>yes, that might be useful,</quote> it should be clear that " | |
5574 "having them follow a rename is definitely important. Without this facility, " | |
5575 "it would simply be too easy for changes to become orphaned when files are " | |
5576 "renamed." | |
5577 msgstr "" | |
5578 | |
5579 #. type: Content of: <book><chapter><sect1><sect2><title> | |
5580 #: ../en/ch05-daily.xml:452 | |
5581 msgid "Divergent renames and merging" | |
5582 msgstr "改名与合并的分歧" | |
5583 | |
5584 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5585 #: ../en/ch05-daily.xml:454 | |
5586 msgid "" | |
5587 "The case of diverging names occurs when two developers start with a " | |
5588 "file&emdash;let's call it <filename>foo</filename>&emdash;in their respective " | |
5589 "repositories." | |
5590 msgstr "" | |
5591 | |
5592 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5593 #: ../en/ch05-daily.xml:461 | |
5594 msgid "Anne renames the file to <filename>bar</filename>." | |
5595 msgstr "" | |
5596 | |
5597 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5598 #: ../en/ch05-daily.xml:465 | |
5599 msgid "Meanwhile, Bob renames it to <filename>quux</filename>." | |
5600 msgstr "" | |
5601 | |
5602 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5603 #: ../en/ch05-daily.xml:470 | |
5604 msgid "" | |
5605 "I like to think of this as a conflict because each developer has expressed " | |
5606 "different intentions about what the file ought to be named." | |
5607 msgstr "" | |
5608 | |
5609 # | |
5610 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5611 #: ../en/ch05-daily.xml:474 | |
5612 msgid "" | |
5613 "What do you think should happen when they merge their work? Mercurial's " | |
5614 "actual behaviour is that it always preserves <emphasis>both</emphasis> names " | |
5615 "when it merges changesets that contain divergent renames." | |
5616 msgstr "" | |
5617 | |
5618 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5619 #: ../en/ch05-daily.xml:481 | |
5620 msgid "" | |
5621 "Notice that Mercurial does warn about the divergent renames, but it leaves it " | |
5622 "up to you to do something about the divergence after the merge." | |
5623 msgstr "" | |
5624 | |
5625 #. type: Content of: <book><chapter><sect1><sect2><title> | |
5626 #: ../en/ch05-daily.xml:487 | |
5627 msgid "Convergent renames and merging" | |
5628 msgstr "收敛改名与合并" | |
5629 | |
5630 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5631 #: ../en/ch05-daily.xml:489 | |
5632 msgid "" | |
5633 "Another kind of rename conflict occurs when two people choose to rename " | |
5634 "different <emphasis>source</emphasis> files to the same " | |
5635 "<emphasis>destination</emphasis>. In this case, Mercurial runs its normal " | |
5636 "merge machinery, and lets you guide it to a suitable resolution." | |
5637 msgstr "" | |
5638 | |
5639 #. type: Content of: <book><chapter><sect1><sect2><title> | |
5640 #: ../en/ch05-daily.xml:497 | |
5641 msgid "Other name-related corner cases" | |
5642 msgstr "其它名称相关的角落" | |
5643 | |
5644 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5645 #: ../en/ch05-daily.xml:499 | |
5646 msgid "" | |
5647 "Mercurial has a longstanding bug in which it fails to handle a merge where " | |
5648 "one side has a file with a given name, while another has a directory with the " | |
5649 "same name. This is documented as <ulink role=\"hg-bug\" url=\"http://www." | |
5650 "selenic.com/mercurial/bts/issue29\">issue 29</ulink>." | |
5651 msgstr "" | |
5652 | |
5653 #. type: Content of: <book><chapter><sect1><title> | |
5654 #: ../en/ch05-daily.xml:511 | |
5655 msgid "Recovering from mistakes" | |
5656 msgstr "从错误恢复" | |
5657 | |
5658 #. type: Content of: <book><chapter><sect1><para> | |
5659 #: ../en/ch05-daily.xml:513 | |
5660 msgid "" | |
5661 "Mercurial has some useful commands that will help you to recover from some " | |
5662 "common mistakes." | |
5663 msgstr "" | |
5664 | |
5665 #. type: Content of: <book><chapter><sect1><para> | |
5666 #: ../en/ch05-daily.xml:516 | |
5667 msgid "" | |
5668 "The <command role=\"hg-cmd\">hg revert</command> command lets you undo " | |
5669 "changes that you have made to your working directory. For example, if you " | |
5670 "<command role=\"hg-cmd\">hg add</command> a file by accident, just run " | |
5671 "<command role=\"hg-cmd\">hg revert</command> with the name of the file you " | |
5672 "added, and while the file won't be touched in any way, it won't be tracked " | |
5673 "for adding by Mercurial any longer, either. You can also use <command role=" | |
5674 "\"hg-cmd\">hg revert</command> to get rid of erroneous changes to a file." | |
5675 msgstr "" | |
5676 | |
5677 #. type: Content of: <book><chapter><sect1><para> | |
5678 #: ../en/ch05-daily.xml:526 | |
5679 msgid "" | |
5680 "It's useful to remember that the <command role=\"hg-cmd\">hg revert</command> " | |
5681 "command is useful for changes that you have not yet committed. Once you've " | |
5682 "committed a change, if you decide it was a mistake, you can still do " | |
5683 "something about it, though your options may be more limited." | |
5684 msgstr "" | |
5685 | |
5686 #. type: Content of: <book><chapter><sect1><para> | |
5687 #: ../en/ch05-daily.xml:532 | |
5688 msgid "" | |
5689 "For more information about the <command role=\"hg-cmd\">hg revert</command> " | |
5690 "command, and details about how to deal with changes you have already " | |
5691 "committed, see chapter <xref linkend=\"chap.undo\"/>." | |
5692 msgstr "" | |
5693 | |
5694 #. type: Content of: <book><chapter><title> | |
5695 #: ../en/ch06-collab.xml:5 | |
5696 msgid "Collaborating with other people" | |
5697 msgstr "团体协作" | |
5698 | |
5699 #. type: Content of: <book><chapter><para> | |
5700 #: ../en/ch06-collab.xml:7 | |
5701 msgid "" | |
5702 "As a completely decentralised tool, Mercurial doesn't impose any policy on " | |
5703 "how people ought to work with each other. However, if you're new to " | |
5704 "distributed revision control, it helps to have some tools and examples in " | |
5705 "mind when you're thinking about possible workflow models." | |
5706 msgstr "" | |
5707 | |
5708 #. type: Content of: <book><chapter><sect1><title> | |
5709 #: ../en/ch06-collab.xml:14 | |
5710 msgid "Mercurial's web interface" | |
5711 msgstr "" | |
5712 | |
5713 #. type: Content of: <book><chapter><sect1><para> | |
5714 #: ../en/ch06-collab.xml:16 | |
5715 msgid "" | |
5716 "Mercurial has a powerful web interface that provides several useful " | |
5717 "capabilities." | |
5718 msgstr "" | |
5719 | |
5720 #. type: Content of: <book><chapter><sect1><para> | |
5721 #: ../en/ch06-collab.xml:19 | |
5722 msgid "" | |
5723 "For interactive use, the web interface lets you browse a single repository or " | |
5724 "a collection of repositories. You can view the history of a repository, " | |
5725 "examine each change (comments and diffs), and view the contents of each " | |
5726 "directory and file." | |
5727 msgstr "" | |
5728 | |
5729 #. type: Content of: <book><chapter><sect1><para> | |
5730 #: ../en/ch06-collab.xml:24 | |
5731 msgid "" | |
5732 "Also for human consumption, the web interface provides an RSS feed of the " | |
5733 "changes in a repository. This lets you <quote>subscribe</quote> to a " | |
5734 "repository using your favourite feed reader, and be automatically notified of " | |
5735 "activity in that repository as soon as it happens. I find this capability " | |
5736 "much more convenient than the model of subscribing to a mailing list to which " | |
5737 "notifications are sent, as it requires no additional configuration on the " | |
5738 "part of whoever is serving the repository." | |
5739 msgstr "" | |
5740 | |
5741 #. type: Content of: <book><chapter><sect1><para> | |
5742 #: ../en/ch06-collab.xml:34 | |
5743 msgid "" | |
5744 "The web interface also lets remote users clone a repository, pull changes " | |
5745 "from it, and (when the server is configured to permit it) push changes back " | |
5746 "to it. Mercurial's HTTP tunneling protocol aggressively compresses data, so " | |
5747 "that it works efficiently even over low-bandwidth network connections." | |
5748 msgstr "" | |
5749 | |
5750 #. type: Content of: <book><chapter><sect1><para> | |
5751 #: ../en/ch06-collab.xml:40 | |
5752 msgid "" | |
5753 "The easiest way to get started with the web interface is to use your web " | |
5754 "browser to visit an existing repository, such as the master Mercurial " | |
5755 "repository at <ulink url=\"http://www.selenic.com/repo/hg?style=gitweb" | |
5756 "\">http://www.selenic.com/repo/hg?style=gitweb</ulink>." | |
5757 msgstr "" | |
5758 | |
5759 #. type: Content of: <book><chapter><sect1><para> | |
5760 #: ../en/ch06-collab.xml:45 | |
5761 msgid "" | |
5762 "If you're interested in providing a web interface to your own repositories, " | |
5763 "Mercurial provides two ways to do this. The first is using the <command role=" | |
5764 "\"hg-cmd\">hg serve</command> command, which is best suited to short-term " | |
5765 "<quote>lightweight</quote> serving. See section <xref linkend=\"sec.collab." | |
5766 "serve\"/> below for details of how to use this command. If you have a long-" | |
5767 "lived repository that you'd like to make permanently available, Mercurial has " | |
5768 "built-in support for the CGI (Common Gateway Interface) standard, which all " | |
5769 "common web servers support. See section <xref linkend=\"sec.collab.cgi\"/> " | |
5770 "for details of CGI configuration." | |
5771 msgstr "" | |
5772 | |
5773 #. type: Content of: <book><chapter><sect1><title> | |
5774 #: ../en/ch06-collab.xml:60 | |
5775 msgid "Collaboration models" | |
5776 msgstr "" | |
5777 | |
5778 #. type: Content of: <book><chapter><sect1><para> | |
5779 #: ../en/ch06-collab.xml:62 | |
5780 msgid "" | |
5781 "With a suitably flexible tool, making decisions about workflow is much more " | |
5782 "of a social engineering challenge than a technical one. Mercurial imposes few " | |
5783 "limitations on how you can structure the flow of work in a project, so it's " | |
5784 "up to you and your group to set up and live with a model that matches your " | |
5785 "own particular needs." | |
5786 msgstr "" | |
5787 | |
5788 #. type: Content of: <book><chapter><sect1><sect2><title> | |
5789 #: ../en/ch06-collab.xml:70 | |
5790 msgid "Factors to keep in mind" | |
5791 msgstr "" | |
5792 | |
5793 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5794 #: ../en/ch06-collab.xml:72 | |
5795 msgid "" | |
5796 "The most important aspect of any model that you must keep in mind is how well " | |
5797 "it matches the needs and capabilities of the people who will be using it. " | |
5798 "This might seem self-evident; even so, you still can't afford to forget it " | |
5799 "for a moment." | |
5800 msgstr "" | |
5801 | |
5802 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5803 #: ../en/ch06-collab.xml:78 | |
5804 msgid "" | |
5805 "I once put together a workflow model that seemed to make perfect sense to me, " | |
5806 "but that caused a considerable amount of consternation and strife within my " | |
5807 "development team. In spite of my attempts to explain why we needed a complex " | |
5808 "set of branches, and how changes ought to flow between them, a few team " | |
5809 "members revolted. Even though they were smart people, they didn't want to " | |
5810 "pay attention to the constraints we were operating under, or face the " | |
5811 "consequences of those constraints in the details of the model that I was " | |
5812 "advocating." | |
5813 msgstr "" | |
5814 | |
5815 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5816 #: ../en/ch06-collab.xml:88 | |
5817 msgid "" | |
5818 "Don't sweep foreseeable social or technical problems under the rug. Whatever " | |
5819 "scheme you put into effect, you should plan for mistakes and problem " | |
5820 "scenarios. Consider adding automated machinery to prevent, or quickly " | |
5821 "recover from, trouble that you can anticipate. As an example, if you intend " | |
5822 "to have a branch with not-for-release changes in it, you'd do well to think " | |
5823 "early about the possibility that someone might accidentally merge those " | |
5824 "changes into a release branch. You could avoid this particular problem by " | |
5825 "writing a hook that prevents changes from being merged from an inappropriate " | |
5826 "branch." | |
5827 msgstr "" | |
5828 | |
5829 #. type: Content of: <book><chapter><sect1><sect2><title> | |
5830 #: ../en/ch06-collab.xml:102 | |
5831 msgid "Informal anarchy" | |
5832 msgstr "" | |
5833 | |
5834 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5835 #: ../en/ch06-collab.xml:104 | |
5836 msgid "" | |
5837 "I wouldn't suggest an <quote>anything goes</quote> approach as something " | |
5838 "sustainable, but it's a model that's easy to grasp, and it works perfectly " | |
5839 "well in a few unusual situations." | |
5840 msgstr "" | |
5841 | |
5842 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5843 #: ../en/ch06-collab.xml:109 | |
5844 msgid "" | |
5845 "As one example, many projects have a loose-knit group of collaborators who " | |
5846 "rarely physically meet each other. Some groups like to overcome the " | |
5847 "isolation of working at a distance by organising occasional <quote>sprints</" | |
5848 "quote>. In a sprint, a number of people get together in a single location (a " | |
5849 "company's conference room, a hotel meeting room, that kind of place) and " | |
5850 "spend several days more or less locked in there, hacking intensely on a " | |
5851 "handful of projects." | |
5852 msgstr "" | |
5853 | |
5854 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5855 #: ../en/ch06-collab.xml:118 | |
5856 msgid "" | |
5857 "A sprint is the perfect place to use the <command role=\"hg-cmd\">hg serve</" | |
5858 "command> command, since <command role=\"hg-cmd\">hg serve</command> does not " | |
5859 "require any fancy server infrastructure. You can get started with <command " | |
5860 "role=\"hg-cmd\">hg serve</command> in moments, by reading section <xref " | |
5861 "linkend=\"sec.collab.serve\"/> below. Then simply tell the person next to " | |
5862 "you that you're running a server, send the URL to them in an instant message, " | |
5863 "and you immediately have a quick-turnaround way to work together. They can " | |
5864 "type your URL into their web browser and quickly review your changes; or they " | |
5865 "can pull a bugfix from you and verify it; or they can clone a branch " | |
5866 "containing a new feature and try it out." | |
5867 msgstr "" | |
5868 | |
5869 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5870 #: ../en/ch06-collab.xml:132 | |
5871 msgid "" | |
5872 "The charm, and the problem, with doing things in an ad hoc fashion like this " | |
5873 "is that only people who know about your changes, and where they are, can see " | |
5874 "them. Such an informal approach simply doesn't scale beyond a handful " | |
5875 "people, because each individual needs to know about $n$ different " | |
5876 "repositories to pull from." | |
5877 msgstr "" | |
5878 | |
5879 #. type: Content of: <book><chapter><sect1><sect2><title> | |
5880 #: ../en/ch06-collab.xml:141 | |
5881 msgid "A single central repository" | |
5882 msgstr "" | |
5883 | |
5884 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5885 #: ../en/ch06-collab.xml:143 | |
5886 msgid "" | |
5887 "For smaller projects migrating from a centralised revision control tool, " | |
5888 "perhaps the easiest way to get started is to have changes flow through a " | |
5889 "single shared central repository. This is also the most common " | |
5890 "<quote>building block</quote> for more ambitious workflow schemes." | |
5891 msgstr "" | |
5892 | |
5893 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5894 #: ../en/ch06-collab.xml:149 | |
5895 msgid "" | |
5896 "Contributors start by cloning a copy of this repository. They can pull " | |
5897 "changes from it whenever they need to, and some (perhaps all) developers have " | |
5898 "permission to push a change back when they're ready for other people to see " | |
5899 "it." | |
5900 msgstr "" | |
5901 | |
5902 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5903 #: ../en/ch06-collab.xml:154 | |
5904 msgid "" | |
5905 "Under this model, it can still often make sense for people to pull changes " | |
5906 "directly from each other, without going through the central repository. " | |
5907 "Consider a case in which I have a tentative bug fix, but I am worried that if " | |
5908 "I were to publish it to the central repository, it might subsequently break " | |
5909 "everyone else's trees as they pull it. To reduce the potential for damage, I " | |
5910 "can ask you to clone my repository into a temporary repository of your own " | |
5911 "and test it. This lets us put off publishing the potentially unsafe change " | |
5912 "until it has had a little testing." | |
5913 msgstr "" | |
5914 | |
5915 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5916 #: ../en/ch06-collab.xml:165 | |
5917 msgid "" | |
5918 "In this kind of scenario, people usually use the <command>ssh</command> " | |
5919 "protocol to securely push changes to the central repository, as documented in " | |
5920 "section <xref linkend=\"sec.collab.ssh\"/>. It's also usual to publish a " | |
5921 "read-only copy of the repository over HTTP using CGI, as in section <xref " | |
5922 "linkend=\"sec.collab.cgi\"/>. Publishing over HTTP satisfies the needs of " | |
5923 "people who don't have push access, and those who want to use web browsers to " | |
5924 "browse the repository's history." | |
5925 msgstr "" | |
5926 | |
5927 #. type: Content of: <book><chapter><sect1><sect2><title> | |
5928 #: ../en/ch06-collab.xml:178 | |
5929 msgid "Working with multiple branches" | |
5930 msgstr "" | |
5931 | |
5932 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5933 #: ../en/ch06-collab.xml:180 | |
5934 msgid "" | |
5935 "Projects of any significant size naturally tend to make progress on several " | |
5936 "fronts simultaneously. In the case of software, it's common for a project to " | |
5937 "go through periodic official releases. A release might then go into " | |
5938 "<quote>maintenance mode</quote> for a while after its first publication; " | |
5939 "maintenance releases tend to contain only bug fixes, not new features. In " | |
5940 "parallel with these maintenance releases, one or more future releases may be " | |
5941 "under development. People normally use the word <quote>branch</quote> to " | |
5942 "refer to one of these many slightly different directions in which development " | |
5943 "is proceeding." | |
5944 msgstr "" | |
5945 | |
5946 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5947 #: ../en/ch06-collab.xml:193 | |
5948 msgid "" | |
5949 "Mercurial is particularly well suited to managing a number of simultaneous, " | |
5950 "but not identical, branches. Each <quote>development direction</quote> can " | |
5951 "live in its own central repository, and you can merge changes from one to " | |
5952 "another as the need arises. Because repositories are independent of each " | |
5953 "other, unstable changes in a development branch will never affect a stable " | |
5954 "branch unless someone explicitly merges those changes in." | |
5955 msgstr "" | |
5956 | |
5957 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5958 #: ../en/ch06-collab.xml:202 | |
5959 msgid "" | |
5960 "Here's an example of how this can work in practice. Let's say you have one " | |
5961 "<quote>main branch</quote> on a central server." | |
5962 msgstr "" | |
5963 | |
5964 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5965 #: ../en/ch06-collab.xml:208 | |
5966 msgid "People clone it, make changes locally, test them, and push them back." | |
5967 msgstr "" | |
5968 | |
5969 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5970 #: ../en/ch06-collab.xml:211 | |
5971 msgid "" | |
5972 "Once the main branch reaches a release milestone, you can use the <command " | |
5973 "role=\"hg-cmd\">hg tag</command> command to give a permanent name to the " | |
5974 "milestone revision." | |
5975 msgstr "" | |
5976 | |
5977 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5978 #: ../en/ch06-collab.xml:217 | |
5979 msgid "Let's say some ongoing development occurs on the main branch." | |
5980 msgstr "" | |
5981 | |
5982 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5983 #: ../en/ch06-collab.xml:222 | |
5984 msgid "" | |
5985 "Using the tag that was recorded at the milestone, people who clone that " | |
5986 "repository at any time in the future can use <command role=\"hg-cmd\">hg " | |
5987 "update</command> to get a copy of the working directory exactly as it was " | |
5988 "when that tagged revision was committed." | |
5989 msgstr "" | |
5990 | |
5991 # | |
5992 #. type: Content of: <book><chapter><sect1><sect2><para> | |
5993 #: ../en/ch06-collab.xml:230 | |
5994 msgid "" | |
5995 "In addition, immediately after the main branch is tagged, someone can then " | |
5996 "clone the main branch on the server to a new <quote>stable</quote> branch, " | |
5997 "also on the server." | |
5998 msgstr "" | |
5999 | |
6000 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6001 #: ../en/ch06-collab.xml:236 | |
6002 msgid "" | |
6003 "Someone who needs to make a change to the stable branch can then clone " | |
6004 "<emphasis>that</emphasis> repository, make their changes, commit, and push " | |
6005 "their changes back there." | |
6006 msgstr "" | |
6007 | |
6008 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6009 #: ../en/ch06-collab.xml:242 | |
6010 msgid "" | |
6011 "Because Mercurial repositories are independent, and Mercurial doesn't move " | |
6012 "changes around automatically, the stable and main branches are " | |
6013 "<emphasis>isolated</emphasis> from each other. The changes that you made on " | |
6014 "the main branch don't <quote>leak</quote> to the stable branch, and vice " | |
6015 "versa." | |
6016 msgstr "" | |
6017 | |
6018 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6019 #: ../en/ch06-collab.xml:249 | |
6020 msgid "" | |
6021 "You'll often want all of your bugfixes on the stable branch to show up on the " | |
6022 "main branch, too. Rather than rewrite a bugfix on the main branch, you can " | |
6023 "simply pull and merge changes from the stable to the main branch, and " | |
6024 "Mercurial will bring those bugfixes in for you." | |
6025 msgstr "" | |
6026 | |
6027 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6028 #: ../en/ch06-collab.xml:257 | |
6029 msgid "" | |
6030 "The main branch will still contain changes that are not on the stable branch, " | |
6031 "but it will also contain all of the bugfixes from the stable branch. The " | |
6032 "stable branch remains unaffected by these changes." | |
6033 msgstr "" | |
6034 | |
6035 #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject><caption><para> | |
6036 #: ../en/ch06-collab.xml:264 ../en/ch06-collab.xml:276 | |
6037 msgid "Feature branches" | |
6038 msgstr "" | |
6039 | |
6040 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6041 #: ../en/ch06-collab.xml:266 | |
6042 msgid "" | |
6043 "For larger projects, an effective way to manage change is to break up a team " | |
6044 "into smaller groups. Each group has a shared branch of its own, cloned from " | |
6045 "a single <quote>master</quote> branch used by the entire project. People " | |
6046 "working on an individual branch are typically quite isolated from " | |
6047 "developments on other branches." | |
6048 msgstr "" | |
6049 | |
6050 #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject> | |
6051 #: ../en/ch06-collab.xml:274 | |
6052 msgid "" | |
6053 "<imageobject><imagedata fileref=\"images/feature-branches.png\"/></" | |
6054 "imageobject>" | |
6055 msgstr "" | |
6056 | |
6057 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6058 #: ../en/ch06-collab.xml:280 | |
6059 msgid "" | |
6060 "When a particular feature is deemed to be in suitable shape, someone on that " | |
6061 "feature team pulls and merges from the master branch into the feature branch, " | |
6062 "then pushes back up to the master branch." | |
6063 msgstr "" | |
6064 | |
6065 #. type: Content of: <book><chapter><sect1><sect2><title> | |
6066 #: ../en/ch06-collab.xml:287 | |
6067 msgid "The release train" | |
6068 msgstr "" | |
6069 | |
6070 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6071 #: ../en/ch06-collab.xml:289 | |
6072 msgid "" | |
6073 "Some projects are organised on a <quote>train</quote> basis: a release is " | |
6074 "scheduled to happen every few months, and whatever features are ready when " | |
6075 "the <quote>train</quote> is ready to leave are allowed in." | |
6076 msgstr "" | |
6077 | |
6078 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6079 #: ../en/ch06-collab.xml:294 | |
6080 msgid "" | |
6081 "This model resembles working with feature branches. The difference is that " | |
6082 "when a feature branch misses a train, someone on the feature team pulls and " | |
6083 "merges the changes that went out on that train release into the feature " | |
6084 "branch, and the team continues its work on top of that release so that their " | |
6085 "feature can make the next release." | |
6086 msgstr "" | |
6087 | |
6088 #. type: Content of: <book><chapter><sect1><sect2><title> | |
6089 #: ../en/ch06-collab.xml:303 | |
6090 msgid "The Linux kernel model" | |
6091 msgstr "" | |
6092 | |
6093 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6094 #: ../en/ch06-collab.xml:305 | |
6095 msgid "" | |
6096 "The development of the Linux kernel has a shallow hierarchical structure, " | |
6097 "surrounded by a cloud of apparent chaos. Because most Linux developers use " | |
6098 "<command>git</command>, a distributed revision control tool with capabilities " | |
6099 "similar to Mercurial, it's useful to describe the way work flows in that " | |
6100 "environment; if you like the ideas, the approach translates well across tools." | |
6101 msgstr "" | |
6102 | |
6103 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6104 #: ../en/ch06-collab.xml:313 | |
6105 msgid "" | |
6106 "At the center of the community sits Linus Torvalds, the creator of Linux. He " | |
6107 "publishes a single source repository that is considered the " | |
6108 "<quote>authoritative</quote> current tree by the entire developer community. " | |
6109 "Anyone can clone Linus's tree, but he is very choosy about whose trees he " | |
6110 "pulls from." | |
6111 msgstr "" | |
6112 | |
6113 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6114 #: ../en/ch06-collab.xml:320 | |
6115 msgid "" | |
6116 "Linus has a number of <quote>trusted lieutenants</quote>. As a general rule, " | |
6117 "he pulls whatever changes they publish, in most cases without even reviewing " | |
6118 "those changes. Some of those lieutenants are generally agreed to be " | |
6119 "<quote>maintainers</quote>, responsible for specific subsystems within the " | |
6120 "kernel. If a random kernel hacker wants to make a change to a subsystem that " | |
6121 "they want to end up in Linus's tree, they must find out who the subsystem's " | |
6122 "maintainer is, and ask that maintainer to take their change. If the " | |
6123 "maintainer reviews their changes and agrees to take them, they'll pass them " | |
6124 "along to Linus in due course." | |
6125 msgstr "" | |
6126 | |
6127 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6128 #: ../en/ch06-collab.xml:332 | |
6129 msgid "" | |
6130 "Individual lieutenants have their own approaches to reviewing, accepting, and " | |
6131 "publishing changes; and for deciding when to feed them to Linus. In " | |
6132 "addition, there are several well known branches that people use for different " | |
6133 "purposes. For example, a few people maintain <quote>stable</quote> " | |
6134 "repositories of older versions of the kernel, to which they apply critical " | |
6135 "fixes as needed. Some maintainers publish multiple trees: one for " | |
6136 "experimental changes; one for changes that they are about to feed upstream; " | |
6137 "and so on. Others just publish a single tree." | |
6138 msgstr "" | |
6139 | |
6140 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6141 #: ../en/ch06-collab.xml:343 | |
6142 msgid "" | |
6143 "This model has two notable features. The first is that it's <quote>pull " | |
6144 "only</quote>. You have to ask, convince, or beg another developer to take a " | |
6145 "change from you, because there are almost no trees to which more than one " | |
6146 "person can push, and there's no way to push changes into a tree that someone " | |
6147 "else controls." | |
6148 msgstr "" | |
6149 | |
6150 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6151 #: ../en/ch06-collab.xml:350 | |
6152 msgid "" | |
6153 "The second is that it's based on reputation and acclaim. If you're an " | |
6154 "unknown, Linus will probably ignore changes from you without even " | |
6155 "responding. But a subsystem maintainer will probably review them, and will " | |
6156 "likely take them if they pass their criteria for suitability. The more " | |
6157 "<quote>good</quote> changes you contribute to a maintainer, the more likely " | |
6158 "they are to trust your judgment and accept your changes. If you're well-" | |
6159 "known and maintain a long-lived branch for something Linus hasn't yet " | |
6160 "accepted, people with similar interests may pull your changes regularly to " | |
6161 "keep up with your work." | |
6162 msgstr "" | |
6163 | |
6164 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6165 #: ../en/ch06-collab.xml:361 | |
6166 msgid "" | |
6167 "Reputation and acclaim don't necessarily cross subsystem or <quote>people</" | |
6168 "quote> boundaries. If you're a respected but specialised storage hacker, and " | |
6169 "you try to fix a networking bug, that change will receive a level of scrutiny " | |
6170 "from a network maintainer comparable to a change from a complete stranger." | |
6171 msgstr "" | |
6172 | |
6173 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6174 #: ../en/ch06-collab.xml:368 | |
6175 msgid "" | |
6176 "To people who come from more orderly project backgrounds, the comparatively " | |
6177 "chaotic Linux kernel development process often seems completely insane. It's " | |
6178 "subject to the whims of individuals; people make sweeping changes whenever " | |
6179 "they deem it appropriate; and the pace of development is astounding. And yet " | |
6180 "Linux is a highly successful, well-regarded piece of software." | |
6181 msgstr "" | |
6182 | |
6183 #. type: Content of: <book><chapter><sect1><sect2><title> | |
6184 #: ../en/ch06-collab.xml:378 | |
6185 msgid "Pull-only versus shared-push collaboration" | |
6186 msgstr "" | |
6187 | |
6188 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6189 #: ../en/ch06-collab.xml:380 | |
6190 msgid "" | |
6191 "A perpetual source of heat in the open source community is whether a " | |
6192 "development model in which people only ever pull changes from others is " | |
6193 "<quote>better than</quote> one in which multiple people can push changes to a " | |
6194 "shared repository." | |
6195 msgstr "" | |
6196 | |
6197 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6198 #: ../en/ch06-collab.xml:386 | |
6199 msgid "" | |
6200 "Typically, the backers of the shared-push model use tools that actively " | |
6201 "enforce this approach. If you're using a centralised revision control tool " | |
6202 "such as Subversion, there's no way to make a choice over which model you'll " | |
6203 "use: the tool gives you shared-push, and if you want to do anything else, " | |
6204 "you'll have to roll your own approach on top (such as applying a patch by " | |
6205 "hand)." | |
6206 msgstr "" | |
6207 | |
6208 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6209 #: ../en/ch06-collab.xml:394 | |
6210 msgid "" | |
6211 "A good distributed revision control tool, such as Mercurial, will support " | |
6212 "both models. You and your collaborators can then structure how you work " | |
6213 "together based on your own needs and preferences, not on what contortions " | |
6214 "your tools force you into." | |
6215 msgstr "" | |
6216 | |
6217 #. type: Content of: <book><chapter><sect1><sect2><title> | |
6218 #: ../en/ch06-collab.xml:402 | |
6219 msgid "Where collaboration meets branch management" | |
6220 msgstr "" | |
6221 | |
6222 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6223 #: ../en/ch06-collab.xml:404 | |
6224 msgid "" | |
6225 "Once you and your team set up some shared repositories and start propagating " | |
6226 "changes back and forth between local and shared repos, you begin to face a " | |
6227 "related, but slightly different challenge: that of managing the multiple " | |
6228 "directions in which your team may be moving at once. Even though this " | |
6229 "subject is intimately related to how your team collaborates, it's dense " | |
6230 "enough to merit treatment of its own, in chapter <xref linkend=\"chap.branch" | |
6231 "\"/>." | |
6232 msgstr "" | |
6233 | |
6234 #. type: Content of: <book><chapter><sect1><title> | |
6235 #: ../en/ch06-collab.xml:416 | |
6236 msgid "The technical side of sharing" | |
6237 msgstr "" | |
6238 | |
6239 #. type: Content of: <book><chapter><sect1><para> | |
6240 #: ../en/ch06-collab.xml:418 | |
6241 msgid "" | |
6242 "The remainder of this chapter is devoted to the question of serving data to " | |
6243 "your collaborators." | |
6244 msgstr "" | |
6245 | |
6246 #. type: Content of: <book><chapter><sect1><title> | |
6247 #: ../en/ch06-collab.xml:423 | |
6248 msgid "Informal sharing with <command role=\"hg-cmd\">hg serve</command>" | |
6249 msgstr "" | |
6250 | |
6251 #. type: Content of: <book><chapter><sect1><para> | |
6252 #: ../en/ch06-collab.xml:426 | |
6253 msgid "" | |
6254 "Mercurial's <command role=\"hg-cmd\">hg serve</command> command is " | |
6255 "wonderfully suited to small, tight-knit, and fast-paced group environments. " | |
6256 "It also provides a great way to get a feel for using Mercurial commands over " | |
6257 "a network." | |
6258 msgstr "" | |
6259 | |
6260 #. type: Content of: <book><chapter><sect1><para> | |
6261 #: ../en/ch06-collab.xml:431 | |
6262 msgid "" | |
6263 "Run <command role=\"hg-cmd\">hg serve</command> inside a repository, and in " | |
6264 "under a second it will bring up a specialised HTTP server; this will accept " | |
6265 "connections from any client, and serve up data for that repository until you " | |
6266 "terminate it. Anyone who knows the URL of the server you just started, and " | |
6267 "can talk to your computer over the network, can then use a web browser or " | |
6268 "Mercurial to read data from that repository. A URL for a <command role=\"hg-" | |
6269 "cmd\">hg serve</command> instance running on a laptop is likely to look " | |
6270 "something like <literal>http://my-laptop.local:8000/</literal>." | |
6271 msgstr "" | |
6272 | |
6273 #. type: Content of: <book><chapter><sect1><para> | |
6274 #: ../en/ch06-collab.xml:442 | |
6275 msgid "" | |
6276 "The <command role=\"hg-cmd\">hg serve</command> command is <emphasis>not</" | |
6277 "emphasis> a general-purpose web server. It can do only two things:" | |
6278 msgstr "" | |
6279 | |
6280 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
6281 #: ../en/ch06-collab.xml:446 | |
6282 msgid "" | |
6283 "Allow people to browse the history of the repository it's serving, from their " | |
6284 "normal web browsers." | |
6285 msgstr "" | |
6286 | |
6287 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
6288 #: ../en/ch06-collab.xml:450 | |
6289 msgid "" | |
6290 "Speak Mercurial's wire protocol, so that people can <command role=\"hg-cmd" | |
6291 "\">hg clone</command> or <command role=\"hg-cmd\">hg pull</command> changes " | |
6292 "from that repository." | |
6293 msgstr "" | |
6294 | |
6295 #. type: Content of: <book><chapter><sect1><para> | |
6296 #: ../en/ch06-collab.xml:455 | |
6297 msgid "" | |
6298 "In particular, <command role=\"hg-cmd\">hg serve</command> won't allow remote " | |
6299 "users to <emphasis>modify</emphasis> your repository. It's intended for read-" | |
6300 "only use." | |
6301 msgstr "" | |
6302 | |
6303 #. type: Content of: <book><chapter><sect1><para> | |
6304 #: ../en/ch06-collab.xml:459 | |
6305 msgid "" | |
6306 "If you're getting started with Mercurial, there's nothing to prevent you from " | |
6307 "using <command role=\"hg-cmd\">hg serve</command> to serve up a repository on " | |
6308 "your own computer, then use commands like <command role=\"hg-cmd\">hg clone</" | |
6309 "command>, <command role=\"hg-cmd\">hg incoming</command>, and so on to talk " | |
6310 "to that server as if the repository was hosted remotely. This can help you to " | |
6311 "quickly get acquainted with using commands on network-hosted repositories." | |
6312 msgstr "" | |
6313 | |
6314 #. type: Content of: <book><chapter><sect1><sect2><title> | |
6315 #: ../en/ch06-collab.xml:469 | |
6316 msgid "A few things to keep in mind" | |
6317 msgstr "" | |
6318 | |
6319 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6320 #: ../en/ch06-collab.xml:471 | |
6321 msgid "" | |
6322 "Because it provides unauthenticated read access to all clients, you should " | |
6323 "only use <command role=\"hg-cmd\">hg serve</command> in an environment where " | |
6324 "you either don't care, or have complete control over, who can access your " | |
6325 "network and pull data from your repository." | |
6326 msgstr "" | |
6327 | |
6328 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6329 #: ../en/ch06-collab.xml:477 | |
6330 msgid "" | |
6331 "The <command role=\"hg-cmd\">hg serve</command> command knows nothing about " | |
6332 "any firewall software you might have installed on your system or network. It " | |
6333 "cannot detect or control your firewall software. If other people are unable " | |
6334 "to talk to a running <command role=\"hg-cmd\">hg serve</command> instance, " | |
6335 "the second thing you should do (<emphasis>after</emphasis> you make sure that " | |
6336 "they're using the correct URL) is check your firewall configuration." | |
6337 msgstr "" | |
6338 | |
6339 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6340 #: ../en/ch06-collab.xml:486 | |
6341 msgid "" | |
6342 "By default, <command role=\"hg-cmd\">hg serve</command> listens for incoming " | |
6343 "connections on port 8000. If another process is already listening on the " | |
6344 "port you want to use, you can specify a different port to listen on using the " | |
6345 "<option role=\"hg-opt-serve\">-p</option> option." | |
6346 msgstr "" | |
6347 | |
6348 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6349 #: ../en/ch06-collab.xml:492 | |
6350 msgid "" | |
6351 "Normally, when <command role=\"hg-cmd\">hg serve</command> starts, it prints " | |
6352 "no output, which can be a bit unnerving. If you'd like to confirm that it is " | |
6353 "indeed running correctly, and find out what URL you should send to your " | |
6354 "collaborators, start it with the <option role=\"hg-opt-global\">-v</option> " | |
6355 "option." | |
6356 msgstr "" | |
6357 | |
6358 #. type: Content of: <book><chapter><sect1><title> | |
6359 #: ../en/ch06-collab.xml:502 | |
6360 msgid "Using the Secure Shell (ssh) protocol" | |
6361 msgstr "" | |
6362 | |
6363 #. type: Content of: <book><chapter><sect1><para> | |
6364 #: ../en/ch06-collab.xml:504 | |
6365 msgid "" | |
6366 "You can pull and push changes securely over a network connection using the " | |
6367 "Secure Shell (<literal>ssh</literal>) protocol. To use this successfully, " | |
6368 "you may have to do a little bit of configuration on the client or server " | |
6369 "sides." | |
6370 msgstr "" | |
6371 | |
6372 #. type: Content of: <book><chapter><sect1><para> | |
6373 #: ../en/ch06-collab.xml:509 | |
6374 msgid "" | |
6375 "If you're not familiar with ssh, it's a network protocol that lets you " | |
6376 "securely communicate with another computer. To use it with Mercurial, you'll " | |
6377 "be setting up one or more user accounts on a server so that remote users can " | |
6378 "log in and execute commands." | |
6379 msgstr "" | |
6380 | |
6381 #. type: Content of: <book><chapter><sect1><para> | |
6382 #: ../en/ch06-collab.xml:515 | |
6383 msgid "" | |
6384 "(If you <emphasis>are</emphasis> familiar with ssh, you'll probably find some " | |
6385 "of the material that follows to be elementary in nature.)" | |
6386 msgstr "" | |
6387 | |
6388 #. type: Content of: <book><chapter><sect1><sect2><title> | |
6389 #: ../en/ch06-collab.xml:520 | |
6390 msgid "How to read and write ssh URLs" | |
6391 msgstr "" | |
6392 | |
6393 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6394 #: ../en/ch06-collab.xml:522 | |
6395 msgid "An ssh URL tends to look like this:" | |
6396 msgstr "" | |
6397 | |
6398 #. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para> | |
6399 #: ../en/ch06-collab.xml:525 | |
6400 msgid "" | |
6401 "The <quote><literal>ssh://</literal></quote> part tells Mercurial to use the " | |
6402 "ssh protocol." | |
6403 msgstr "" | |
6404 | |
6405 #. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para> | |
6406 #: ../en/ch06-collab.xml:528 | |
6407 msgid "" | |
6408 "The <quote><literal>bos@</literal></quote> component indicates what username " | |
6409 "to log into the server as. You can leave this out if the remote username is " | |
6410 "the same as your local username." | |
6411 msgstr "" | |
6412 | |
6413 #. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para> | |
6414 #: ../en/ch06-collab.xml:533 | |
6415 msgid "" | |
6416 "The <quote><literal>hg.serpentine.com</literal></quote> gives the hostname of " | |
6417 "the server to log into." | |
6418 msgstr "" | |
6419 | |
6420 #. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para> | |
6421 #: ../en/ch06-collab.xml:537 | |
6422 msgid "" | |
6423 "The <quote>:22</quote> identifies the port number to connect to the server " | |
6424 "on. The default port is 22, so you only need to specify this part if you're " | |
6425 "<emphasis>not</emphasis> using port 22." | |
6426 msgstr "" | |
6427 | |
6428 #. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para> | |
6429 #: ../en/ch06-collab.xml:542 | |
6430 msgid "" | |
6431 "The remainder of the URL is the local path to the repository on the server." | |
6432 msgstr "" | |
6433 | |
6434 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6435 #: ../en/ch06-collab.xml:546 | |
6436 msgid "" | |
6437 "There's plenty of scope for confusion with the path component of ssh URLs, as " | |
6438 "there is no standard way for tools to interpret it. Some programs behave " | |
6439 "differently than others when dealing with these paths. This isn't an ideal " | |
6440 "situation, but it's unlikely to change. Please read the following paragraphs " | |
6441 "carefully." | |
6442 msgstr "" | |
6443 | |
6444 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6445 #: ../en/ch06-collab.xml:553 | |
6446 msgid "" | |
6447 "Mercurial treats the path to a repository on the server as relative to the " | |
6448 "remote user's home directory. For example, if user <literal>foo</literal> on " | |
6449 "the server has a home directory of <filename class=\"directory\">/home/foo</" | |
6450 "filename>, then an ssh URL that contains a path component of <filename class=" | |
6451 "\"directory\">bar</filename> <emphasis>really</emphasis> refers to the " | |
6452 "directory <filename class=\"directory\">/home/foo/bar</filename>." | |
6453 msgstr "" | |
6454 | |
6455 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6456 #: ../en/ch06-collab.xml:562 | |
6457 msgid "" | |
6458 "If you want to specify a path relative to another user's home directory, you " | |
6459 "can use a path that starts with a tilde character followed by the user's name " | |
6460 "(let's call them <literal>otheruser</literal>), like this." | |
6461 msgstr "" | |
6462 | |
6463 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6464 #: ../en/ch06-collab.xml:568 | |
6465 msgid "" | |
6466 "And if you really want to specify an <emphasis>absolute</emphasis> path on " | |
6467 "the server, begin the path component with two slashes, as in this example." | |
6468 msgstr "" | |
6469 | |
6470 #. type: Content of: <book><chapter><sect1><sect2><title> | |
6471 #: ../en/ch06-collab.xml:575 | |
6472 msgid "Finding an ssh client for your system" | |
6473 msgstr "" | |
6474 | |
6475 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6476 #: ../en/ch06-collab.xml:577 | |
6477 msgid "" | |
6478 "Almost every Unix-like system comes with OpenSSH preinstalled. If you're " | |
6479 "using such a system, run <literal>which ssh</literal> to find out if the " | |
6480 "<command>ssh</command> command is installed (it's usually in <filename class=" | |
6481 "\"directory\">/usr/bin</filename>). In the unlikely event that it isn't " | |
6482 "present, take a look at your system documentation to figure out how to " | |
6483 "install it." | |
6484 msgstr "" | |
6485 | |
6486 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6487 #: ../en/ch06-collab.xml:585 | |
6488 msgid "" | |
6489 "On Windows, you'll first need to download a suitable ssh client. There are " | |
6490 "two alternatives." | |
6491 msgstr "" | |
6492 | |
6493 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
6494 #: ../en/ch06-collab.xml:588 | |
6495 msgid "" | |
6496 "Simon Tatham's excellent PuTTY package <citation>web:putty</citation> " | |
6497 "provides a complete suite of ssh client commands." | |
6498 msgstr "" | |
6499 | |
6500 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
6501 #: ../en/ch06-collab.xml:592 | |
6502 msgid "" | |
6503 "If you have a high tolerance for pain, you can use the Cygwin port of OpenSSH." | |
6504 msgstr "" | |
6505 | |
6506 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6507 #: ../en/ch06-collab.xml:595 | |
6508 msgid "" | |
6509 "In either case, you'll need to edit your \\hgini\\ file to tell Mercurial " | |
6510 "where to find the actual client command. For example, if you're using PuTTY, " | |
6511 "you'll need to use the <command>plink</command> command as a command-line ssh " | |
6512 "client." | |
6513 msgstr "" | |
6514 | |
6515 #. type: Content of: <book><chapter><sect1><sect2><note><para> | |
6516 #: ../en/ch06-collab.xml:604 | |
6517 msgid "" | |
6518 "The path to <command>plink</command> shouldn't contain any whitespace " | |
6519 "characters, or Mercurial may not be able to run it correctly (so putting it " | |
6520 "in <filename class=\"directory\">C:\\\\Program Files</filename> is probably " | |
6521 "not a good idea)." | |
6522 msgstr "" | |
6523 | |
6524 #. type: Content of: <book><chapter><sect1><sect2><title> | |
6525 #: ../en/ch06-collab.xml:613 | |
6526 msgid "Generating a key pair" | |
6527 msgstr "" | |
6528 | |
6529 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6530 #: ../en/ch06-collab.xml:615 | |
6531 msgid "" | |
6532 "To avoid the need to repetitively type a password every time you need to use " | |
6533 "your ssh client, I recommend generating a key pair. On a Unix-like system, " | |
6534 "the <command>ssh-keygen</command> command will do the trick. On Windows, if " | |
6535 "you're using PuTTY, the <command>puttygen</command> command is what you'll " | |
6536 "need." | |
6537 msgstr "" | |
6538 | |
6539 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6540 #: ../en/ch06-collab.xml:623 | |
6541 msgid "" | |
6542 "When you generate a key pair, it's usually <emphasis>highly</emphasis> " | |
6543 "advisable to protect it with a passphrase. (The only time that you might not " | |
6544 "want to do this is when you're using the ssh protocol for automated tasks on " | |
6545 "a secure network.)" | |
6546 msgstr "" | |
6547 | |
6548 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6549 #: ../en/ch06-collab.xml:629 | |
6550 msgid "" | |
6551 "Simply generating a key pair isn't enough, however. You'll need to add the " | |
6552 "public key to the set of authorised keys for whatever user you're logging in " | |
6553 "remotely as. For servers using OpenSSH (the vast majority), this will mean " | |
6554 "adding the public key to a list in a file called <filename role=\"special" | |
6555 "\">authorized_keys</filename> in their <filename role=\"special\" class=" | |
6556 "\"directory\">.ssh</filename> directory." | |
6557 msgstr "" | |
6558 | |
6559 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6560 #: ../en/ch06-collab.xml:638 | |
6561 msgid "" | |
6562 "On a Unix-like system, your public key will have a <filename>.pub</filename> " | |
6563 "extension. If you're using <command>puttygen</command> on Windows, you can " | |
6564 "save the public key to a file of your choosing, or paste it from the window " | |
6565 "it's displayed in straight into the <filename role=\"special" | |
6566 "\">authorized_keys</filename> file." | |
6567 msgstr "" | |
6568 | |
6569 #. type: Content of: <book><chapter><sect1><sect2><title> | |
6570 #: ../en/ch06-collab.xml:647 | |
6571 msgid "Using an authentication agent" | |
6572 msgstr "" | |
6573 | |
6574 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6575 #: ../en/ch06-collab.xml:649 | |
6576 msgid "" | |
6577 "An authentication agent is a daemon that stores passphrases in memory (so it " | |
6578 "will forget passphrases if you log out and log back in again). An ssh client " | |
6579 "will notice if it's running, and query it for a passphrase. If there's no " | |
6580 "authentication agent running, or the agent doesn't store the necessary " | |
6581 "passphrase, you'll have to type your passphrase every time Mercurial tries to " | |
6582 "communicate with a server on your behalf (e.g. whenever you pull or push " | |
6583 "changes)." | |
6584 msgstr "" | |
6585 | |
6586 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6587 #: ../en/ch06-collab.xml:658 | |
6588 msgid "" | |
6589 "The downside of storing passphrases in an agent is that it's possible for a " | |
6590 "well-prepared attacker to recover the plain text of your passphrases, in some " | |
6591 "cases even if your system has been power-cycled. You should make your own " | |
6592 "judgment as to whether this is an acceptable risk. It certainly saves a lot " | |
6593 "of repeated typing." | |
6594 msgstr "" | |
6595 | |
6596 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6597 #: ../en/ch06-collab.xml:665 | |
6598 msgid "" | |
6599 "On Unix-like systems, the agent is called <command>ssh-agent</command>, and " | |
6600 "it's often run automatically for you when you log in. You'll need to use the " | |
6601 "<command>ssh-add</command> command to add passphrases to the agent's store. " | |
6602 "On Windows, if you're using PuTTY, the <command>pageant</command> command " | |
6603 "acts as the agent. It adds an icon to your system tray that will let you " | |
6604 "manage stored passphrases." | |
6605 msgstr "" | |
6606 | |
6607 #. type: Content of: <book><chapter><sect1><sect2><title> | |
6608 #: ../en/ch06-collab.xml:676 | |
6609 msgid "Configuring the server side properly" | |
6610 msgstr "" | |
6611 | |
6612 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6613 #: ../en/ch06-collab.xml:678 | |
6614 msgid "" | |
6615 "Because ssh can be fiddly to set up if you're new to it, there's a variety of " | |
6616 "things that can go wrong. Add Mercurial on top, and there's plenty more " | |
6617 "scope for head-scratching. Most of these potential problems occur on the " | |
6618 "server side, not the client side. The good news is that once you've gotten a " | |
6619 "configuration working, it will usually continue to work indefinitely." | |
6620 msgstr "" | |
6621 | |
6622 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6623 #: ../en/ch06-collab.xml:686 | |
6624 msgid "" | |
6625 "Before you try using Mercurial to talk to an ssh server, it's best to make " | |
6626 "sure that you can use the normal <command>ssh</command> or <command>putty</" | |
6627 "command> command to talk to the server first. If you run into problems with " | |
6628 "using these commands directly, Mercurial surely won't work. Worse, it will " | |
6629 "obscure the underlying problem. Any time you want to debug ssh-related " | |
6630 "Mercurial problems, you should drop back to making sure that plain ssh client " | |
6631 "commands work first, <emphasis>before</emphasis> you worry about whether " | |
6632 "there's a problem with Mercurial." | |
6633 msgstr "" | |
6634 | |
6635 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6636 #: ../en/ch06-collab.xml:697 | |
6637 msgid "" | |
6638 "The first thing to be sure of on the server side is that you can actually log " | |
6639 "in from another machine at all. If you can't use <command>ssh</command> or " | |
6640 "<command>putty</command> to log in, the error message you get may give you a " | |
6641 "few hints as to what's wrong. The most common problems are as follows." | |
6642 msgstr "" | |
6643 | |
6644 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
6645 #: ../en/ch06-collab.xml:704 | |
6646 msgid "" | |
6647 "If you get a <quote>connection refused</quote> error, either there isn't an " | |
6648 "SSH daemon running on the server at all, or it's inaccessible due to firewall " | |
6649 "configuration." | |
6650 msgstr "" | |
6651 | |
6652 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
6653 #: ../en/ch06-collab.xml:709 | |
6654 msgid "" | |
6655 "If you get a <quote>no route to host</quote> error, you either have an " | |
6656 "incorrect address for the server or a seriously locked down firewall that " | |
6657 "won't admit its existence at all." | |
6658 msgstr "" | |
6659 | |
6660 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
6661 #: ../en/ch06-collab.xml:714 | |
6662 msgid "" | |
6663 "If you get a <quote>permission denied</quote> error, you may have mistyped " | |
6664 "the username on the server, or you could have mistyped your key's passphrase " | |
6665 "or the remote user's password." | |
6666 msgstr "" | |
6667 | |
6668 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6669 #: ../en/ch06-collab.xml:719 | |
6670 msgid "" | |
6671 "In summary, if you're having trouble talking to the server's ssh daemon, " | |
6672 "first make sure that one is running at all. On many systems it will be " | |
6673 "installed, but disabled, by default. Once you're done with this step, you " | |
6674 "should then check that the server's firewall is configured to allow incoming " | |
6675 "connections on the port the ssh daemon is listening on (usually 22). Don't " | |
6676 "worry about more exotic possibilities for misconfiguration until you've " | |
6677 "checked these two first." | |
6678 msgstr "" | |
6679 | |
6680 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6681 #: ../en/ch06-collab.xml:729 | |
6682 msgid "" | |
6683 "If you're using an authentication agent on the client side to store " | |
6684 "passphrases for your keys, you ought to be able to log into the server " | |
6685 "without being prompted for a passphrase or a password. If you're prompted " | |
6686 "for a passphrase, there are a few possible culprits." | |
6687 msgstr "" | |
6688 | |
6689 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
6690 #: ../en/ch06-collab.xml:735 | |
6691 msgid "" | |
6692 "You might have forgotten to use <command>ssh-add</command> or " | |
6693 "<command>pageant</command> to store the passphrase." | |
6694 msgstr "" | |
6695 | |
6696 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
6697 #: ../en/ch06-collab.xml:739 | |
6698 msgid "You might have stored the passphrase for the wrong key." | |
6699 msgstr "" | |
6700 | |
6701 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6702 #: ../en/ch06-collab.xml:742 | |
6703 msgid "" | |
6704 "If you're being prompted for the remote user's password, there are another " | |
6705 "few possible problems to check." | |
6706 msgstr "" | |
6707 | |
6708 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
6709 #: ../en/ch06-collab.xml:745 | |
6710 msgid "" | |
6711 "Either the user's home directory or their <filename role=\"special\" class=" | |
6712 "\"directory\">.ssh</filename> directory might have excessively liberal " | |
6713 "permissions. As a result, the ssh daemon will not trust or read their " | |
6714 "<filename role=\"special\">authorized_keys</filename> file. For example, a " | |
6715 "group-writable home or <filename role=\"special\" class=\"directory\">.ssh</" | |
6716 "filename> directory will often cause this symptom." | |
6717 msgstr "" | |
6718 | |
6719 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
6720 #: ../en/ch06-collab.xml:754 | |
6721 msgid "" | |
6722 "The user's <filename role=\"special\">authorized_keys</filename> file may " | |
6723 "have a problem. If anyone other than the user owns or can write to that file, " | |
6724 "the ssh daemon will not trust or read it." | |
6725 msgstr "" | |
6726 | |
6727 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6728 #: ../en/ch06-collab.xml:761 | |
6729 msgid "" | |
6730 "In the ideal world, you should be able to run the following command " | |
6731 "successfully, and it should print exactly one line of output, the current " | |
6732 "date and time." | |
6733 msgstr "" | |
6734 | |
6735 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6736 #: ../en/ch06-collab.xml:766 | |
6737 msgid "" | |
6738 "If, on your server, you have login scripts that print banners or other junk " | |
6739 "even when running non-interactive commands like this, you should fix them " | |
6740 "before you continue, so that they only print output if they're run " | |
6741 "interactively. Otherwise these banners will at least clutter up Mercurial's " | |
6742 "output. Worse, they could potentially cause problems with running Mercurial " | |
6743 "commands remotely. Mercurial makes tries to detect and ignore banners in non-" | |
6744 "interactive <command>ssh</command> sessions, but it is not foolproof. (If " | |
6745 "you're editing your login scripts on your server, the usual way to see if a " | |
6746 "login script is running in an interactive shell is to check the return code " | |
6747 "from the command <literal>tty -s</literal>.)" | |
6748 msgstr "" | |
6749 | |
6750 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6751 #: ../en/ch06-collab.xml:780 | |
6752 msgid "" | |
6753 "Once you've verified that plain old ssh is working with your server, the next " | |
6754 "step is to ensure that Mercurial runs on the server. The following command " | |
6755 "should run successfully:" | |
6756 msgstr "" | |
6757 | |
6758 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6759 #: ../en/ch06-collab.xml:785 | |
6760 msgid "" | |
6761 "If you see an error message instead of normal <command role=\"hg-cmd\">hg " | |
6762 "version</command> output, this is usually because you haven't installed " | |
6763 "Mercurial to <filename class=\"directory\">/usr/bin</filename>. Don't worry " | |
6764 "if this is the case; you don't need to do that. But you should check for a " | |
6765 "few possible problems." | |
6766 msgstr "" | |
6767 | |
6768 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
6769 #: ../en/ch06-collab.xml:792 | |
6770 msgid "" | |
6771 "Is Mercurial really installed on the server at all? I know this sounds " | |
6772 "trivial, but it's worth checking!" | |
6773 msgstr "" | |
6774 | |
6775 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
6776 #: ../en/ch06-collab.xml:796 | |
6777 msgid "" | |
6778 "Maybe your shell's search path (usually set via the <envar>PATH</envar> " | |
6779 "environment variable) is simply misconfigured." | |
6780 msgstr "" | |
6781 | |
6782 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
6783 #: ../en/ch06-collab.xml:800 | |
6784 msgid "" | |
6785 "Perhaps your <envar>PATH</envar> environment variable is only being set to " | |
6786 "point to the location of the <command>hg</command> executable if the login " | |
6787 "session is interactive. This can happen if you're setting the path in the " | |
6788 "wrong shell login script. See your shell's documentation for details." | |
6789 msgstr "" | |
6790 | |
6791 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
6792 #: ../en/ch06-collab.xml:807 | |
6793 msgid "" | |
6794 "The <envar>PYTHONPATH</envar> environment variable may need to contain the " | |
6795 "path to the Mercurial Python modules. It might not be set at all; it could " | |
6796 "be incorrect; or it may be set only if the login is interactive." | |
6797 msgstr "" | |
6798 | |
6799 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6800 #: ../en/ch06-collab.xml:814 | |
6801 msgid "" | |
6802 "If you can run <command role=\"hg-cmd\">hg version</command> over an ssh " | |
6803 "connection, well done! You've got the server and client sorted out. You " | |
6804 "should now be able to use Mercurial to access repositories hosted by that " | |
6805 "username on that server. If you run into problems with Mercurial and ssh at " | |
6806 "this point, try using the <option role=\"hg-opt-global\">--debug</option> " | |
6807 "option to get a clearer picture of what's going on." | |
6808 msgstr "" | |
6809 | |
6810 #. type: Content of: <book><chapter><sect1><sect2><title> | |
6811 #: ../en/ch06-collab.xml:824 | |
6812 msgid "Using compression with ssh" | |
6813 msgstr "" | |
6814 | |
6815 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6816 #: ../en/ch06-collab.xml:826 | |
6817 msgid "" | |
6818 "Mercurial does not compress data when it uses the ssh protocol, because the " | |
6819 "ssh protocol can transparently compress data. However, the default behaviour " | |
6820 "of ssh clients is <emphasis>not</emphasis> to request compression." | |
6821 msgstr "" | |
6822 | |
6823 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6824 #: ../en/ch06-collab.xml:831 | |
6825 msgid "" | |
6826 "Over any network other than a fast LAN (even a wireless network), using " | |
6827 "compression is likely to significantly speed up Mercurial's network " | |
6828 "operations. For example, over a WAN, someone measured compression as " | |
6829 "reducing the amount of time required to clone a particularly large repository " | |
6830 "from 51 minutes to 17 minutes." | |
6831 msgstr "" | |
6832 | |
6833 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6834 #: ../en/ch06-collab.xml:838 | |
6835 msgid "" | |
6836 "Both <command>ssh</command> and <command>plink</command> accept a <option " | |
6837 "role=\"cmd-opt-ssh\">-C</option> option which turns on compression. You can " | |
6838 "easily edit your <filename role=\"special\"> /.hgrc</filename>\\ to enable " | |
6839 "compression for all of Mercurial's uses of the ssh protocol." | |
6840 msgstr "" | |
6841 | |
6842 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6843 #: ../en/ch06-collab.xml:845 | |
6844 msgid "" | |
6845 "If you use <command>ssh</command>, you can configure it to always use " | |
6846 "compression when talking to your server. To do this, edit your <filename " | |
6847 "role=\"special\">.ssh/config</filename> file (which may not yet exist), as " | |
6848 "follows." | |
6849 msgstr "" | |
6850 | |
6851 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6852 #: ../en/ch06-collab.xml:852 | |
6853 msgid "" | |
6854 "This defines an alias, <literal>hg</literal>. When you use it on the " | |
6855 "<command>ssh</command> command line or in a Mercurial <literal>ssh</literal>-" | |
6856 "protocol URL, it will cause <command>ssh</command> to connect to <literal>hg." | |
6857 "example.com</literal> and use compression. This gives you both a shorter " | |
6858 "name to type and compression, each of which is a good thing in its own right." | |
6859 msgstr "" | |
6860 | |
6861 #. type: Content of: <book><chapter><sect1><title> | |
6862 #: ../en/ch06-collab.xml:863 | |
6863 msgid "Serving over HTTP using CGI" | |
6864 msgstr "" | |
6865 | |
6866 #. type: Content of: <book><chapter><sect1><para> | |
6867 #: ../en/ch06-collab.xml:865 | |
6868 msgid "" | |
6869 "Depending on how ambitious you are, configuring Mercurial's CGI interface can " | |
6870 "take anything from a few moments to several hours." | |
6871 msgstr "" | |
6872 | |
6873 #. type: Content of: <book><chapter><sect1><para> | |
6874 #: ../en/ch06-collab.xml:869 | |
6875 msgid "" | |
6876 "We'll begin with the simplest of examples, and work our way towards a more " | |
6877 "complex configuration. Even for the most basic case, you're almost certainly " | |
6878 "going to need to read and modify your web server's configuration." | |
6879 msgstr "" | |
6880 | |
6881 #. type: Content of: <book><chapter><sect1><note><para> | |
6882 #: ../en/ch06-collab.xml:875 | |
6883 msgid "" | |
6884 "Configuring a web server is a complex, fiddly, and highly system-dependent " | |
6885 "activity. I can't possibly give you instructions that will cover anything " | |
6886 "like all of the cases you will encounter. Please use your discretion and " | |
6887 "judgment in following the sections below. Be prepared to make plenty of " | |
6888 "mistakes, and to spend a lot of time reading your server's error logs." | |
6889 msgstr "" | |
6890 | |
6891 #. type: Content of: <book><chapter><sect1><sect2><title> | |
6892 #: ../en/ch06-collab.xml:885 | |
6893 msgid "Web server configuration checklist" | |
6894 msgstr "" | |
6895 | |
6896 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6897 #: ../en/ch06-collab.xml:887 | |
6898 msgid "" | |
6899 "Before you continue, do take a few moments to check a few aspects of your " | |
6900 "system's setup." | |
6901 msgstr "" | |
6902 | |
6903 #. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para> | |
6904 #: ../en/ch06-collab.xml:891 | |
6905 msgid "" | |
6906 "Do you have a web server installed at all? Mac OS X ships with Apache, but " | |
6907 "many other systems may not have a web server installed." | |
6908 msgstr "" | |
6909 | |
6910 #. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para> | |
6911 #: ../en/ch06-collab.xml:895 | |
6912 msgid "" | |
6913 "If you have a web server installed, is it actually running? On most systems, " | |
6914 "even if one is present, it will be disabled by default." | |
6915 msgstr "" | |
6916 | |
6917 #. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para> | |
6918 #: ../en/ch06-collab.xml:899 | |
6919 msgid "" | |
6920 "Is your server configured to allow you to run CGI programs in the directory " | |
6921 "where you plan to do so? Most servers default to explicitly disabling the " | |
6922 "ability to run CGI programs." | |
6923 msgstr "" | |
6924 | |
6925 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6926 #: ../en/ch06-collab.xml:905 | |
6927 msgid "" | |
6928 "If you don't have a web server installed, and don't have substantial " | |
6929 "experience configuring Apache, you should consider using the " | |
6930 "<literal>lighttpd</literal> web server instead of Apache. Apache has a well-" | |
6931 "deserved reputation for baroque and confusing configuration. While " | |
6932 "<literal>lighttpd</literal> is less capable in some ways than Apache, most of " | |
6933 "these capabilities are not relevant to serving Mercurial repositories. And " | |
6934 "<literal>lighttpd</literal> is undeniably <emphasis>much</emphasis> easier to " | |
6935 "get started with than Apache." | |
6936 msgstr "" | |
6937 | |
6938 #. type: Content of: <book><chapter><sect1><sect2><title> | |
6939 #: ../en/ch06-collab.xml:918 | |
6940 msgid "Basic CGI configuration" | |
6941 msgstr "" | |
6942 | |
6943 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6944 #: ../en/ch06-collab.xml:920 | |
6945 msgid "" | |
6946 "On Unix-like systems, it's common for users to have a subdirectory named " | |
6947 "something like <filename class=\"directory\">public_html</filename> in their " | |
6948 "home directory, from which they can serve up web pages. A file named " | |
6949 "<filename>foo</filename> in this directory will be accessible at a URL of the " | |
6950 "form <literal>http://www.example.com/\\ {</literal>username/foo}." | |
6951 msgstr "" | |
6952 | |
6953 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6954 #: ../en/ch06-collab.xml:929 | |
6955 msgid "" | |
6956 "To get started, find the <filename role=\"special\">hgweb.cgi</filename> " | |
6957 "script that should be present in your Mercurial installation. If you can't " | |
6958 "quickly find a local copy on your system, simply download one from the master " | |
6959 "Mercurial repository at <ulink url=\"http://www.selenic.com/repo/hg/raw-file/" | |
6960 "tip/hgweb.cgi\">http://www.selenic.com/repo/hg/raw-file/tip/hgweb.cgi</ulink>." | |
6961 msgstr "" | |
6962 | |
6963 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6964 #: ../en/ch06-collab.xml:936 ../en/ch06-collab.xml:1109 | |
6965 msgid "" | |
6966 "You'll need to copy this script into your <filename class=\"directory" | |
6967 "\">public_html</filename> directory, and ensure that it's executable." | |
6968 msgstr "" | |
6969 | |
6970 #. type: Content of: <book><chapter><sect1><sect2><para> | |
6971 #: ../en/ch06-collab.xml:941 | |
6972 msgid "" | |
6973 "The <literal>755</literal> argument to <command>chmod</command> is a little " | |
6974 "more general than just making the script executable: it ensures that the " | |
6975 "script is executable by anyone, and that <quote>group</quote> and " | |
6976 "<quote>other</quote> write permissions are <emphasis>not</emphasis> set. If " | |
6977 "you were to leave those write permissions enabled, Apache's <literal>suexec</" | |
6978 "literal> subsystem would likely refuse to execute the script. In fact, " | |
6979 "<literal>suexec</literal> also insists that the <emphasis>directory</" | |
6980 "emphasis> in which the script resides must not be writable by others." | |
6981 msgstr "" | |
6982 | |
6983 #. type: Content of: <book><chapter><sect1><sect2><sect3><title> | |
6984 #: ../en/ch06-collab.xml:955 | |
6985 msgid "What could <emphasis>possibly</emphasis> go wrong?" | |
6986 msgstr "" | |
6987 | |
6988 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
6989 #: ../en/ch06-collab.xml:958 | |
6990 msgid "" | |
6991 "Once you've copied the CGI script into place, go into a web browser, and try " | |
6992 "to open the URL <ulink url=\"http://myhostname/ myuser/hgweb.cgi\">http://" | |
6993 "myhostname/ myuser/hgweb.cgi</ulink>, <emphasis>but</emphasis> brace yourself " | |
6994 "for instant failure. There's a high probability that trying to visit this " | |
6995 "URL will fail, and there are many possible reasons for this. In fact, you're " | |
6996 "likely to stumble over almost every one of the possible errors below, so " | |
6997 "please read carefully. The following are all of the problems I ran into on a " | |
6998 "system running Fedora 7, with a fresh installation of Apache, and a user " | |
6999 "account that I created specially to perform this exercise." | |
7000 msgstr "" | |
7001 | |
7002 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
7003 #: ../en/ch06-collab.xml:972 | |
7004 msgid "" | |
7005 "Your web server may have per-user directories disabled. If you're using " | |
7006 "Apache, search your config file for a <literal>UserDir</literal> directive. " | |
7007 "If there's none present, per-user directories will be disabled. If one " | |
7008 "exists, but its value is <literal>disabled</literal>, then per-user " | |
7009 "directories will be disabled. Otherwise, the string after <literal>UserDir</" | |
7010 "literal> gives the name of the subdirectory that Apache will look in under " | |
7011 "your home directory, for example <filename class=\"directory\">public_html</" | |
7012 "filename>." | |
7013 msgstr "" | |
7014 | |
7015 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
7016 #: ../en/ch06-collab.xml:983 | |
7017 msgid "" | |
7018 "Your file access permissions may be too restrictive. The web server must be " | |
7019 "able to traverse your home directory and directories under your <filename " | |
7020 "class=\"directory\">public_html</filename> directory, and read files under " | |
7021 "the latter too. Here's a quick recipe to help you to make your permissions " | |
7022 "more appropriate." | |
7023 msgstr "" | |
7024 | |
7025 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
7026 #: ../en/ch06-collab.xml:993 | |
7027 msgid "" | |
7028 "The other possibility with permissions is that you might get a completely " | |
7029 "empty window when you try to load the script. In this case, it's likely that " | |
7030 "your access permissions are <emphasis>too permissive</emphasis>. Apache's " | |
7031 "<literal>suexec</literal> subsystem won't execute a script that's group- or " | |
7032 "world-writable, for example." | |
7033 msgstr "" | |
7034 | |
7035 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
7036 #: ../en/ch06-collab.xml:1000 | |
7037 msgid "" | |
7038 "Your web server may be configured to disallow execution of CGI programs in " | |
7039 "your per-user web directory. Here's Apache's default per-user configuration " | |
7040 "from my Fedora system." | |
7041 msgstr "" | |
7042 | |
7043 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
7044 #: ../en/ch06-collab.xml:1011 | |
7045 msgid "" | |
7046 "If you find a similar-looking <literal>Directory</literal> group in your " | |
7047 "Apache configuration, the directive to look at inside it is <literal>Options</" | |
7048 "literal>. Add <literal>ExecCGI</literal> to the end of this list if it's " | |
7049 "missing, and restart the web server." | |
7050 msgstr "" | |
7051 | |
7052 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
7053 #: ../en/ch06-collab.xml:1018 | |
7054 msgid "" | |
7055 "If you find that Apache serves you the text of the CGI script instead of " | |
7056 "executing it, you may need to either uncomment (if already present) or add a " | |
7057 "directive like this." | |
7058 msgstr "" | |
7059 | |
7060 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
7061 #: ../en/ch06-collab.xml:1024 | |
7062 msgid "" | |
7063 "The next possibility is that you might be served with a colourful Python " | |
7064 "backtrace claiming that it can't import a <literal>mercurial</literal>-" | |
7065 "related module. This is actually progress! The server is now capable of " | |
7066 "executing your CGI script. This error is only likely to occur if you're " | |
7067 "running a private installation of Mercurial, instead of a system-wide " | |
7068 "version. Remember that the web server runs the CGI program without any of " | |
7069 "the environment variables that you take for granted in an interactive " | |
7070 "session. If this error happens to you, edit your copy of <filename role=" | |
7071 "\"special\">hgweb.cgi</filename> and follow the directions inside it to " | |
7072 "correctly set your <envar>PYTHONPATH</envar> environment variable." | |
7073 msgstr "" | |
7074 | |
7075 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
7076 #: ../en/ch06-collab.xml:1038 | |
7077 msgid "" | |
7078 "Finally, you are <emphasis>certain</emphasis> to by served with another " | |
7079 "colourful Python backtrace: this one will complain that it can't find " | |
7080 "<filename class=\"directory\">/path/to/repository</filename>. Edit your " | |
7081 "<filename role=\"special\">hgweb.cgi</filename> script and replace the " | |
7082 "<filename class=\"directory\">/path/to/repository</filename> string with the " | |
7083 "complete path to the repository you want to serve up." | |
7084 msgstr "" | |
7085 | |
7086 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
7087 #: ../en/ch06-collab.xml:1048 | |
7088 msgid "" | |
7089 "At this point, when you try to reload the page, you should be presented with " | |
7090 "a nice HTML view of your repository's history. Whew!" | |
7091 msgstr "" | |
7092 | |
7093 #. type: Content of: <book><chapter><sect1><sect2><sect3><title> | |
7094 #: ../en/ch06-collab.xml:1054 | |
7095 msgid "Configuring lighttpd" | |
7096 msgstr "" | |
7097 | |
7098 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
7099 #: ../en/ch06-collab.xml:1056 | |
7100 msgid "" | |
7101 "To be exhaustive in my experiments, I tried configuring the increasingly " | |
7102 "popular <literal>lighttpd</literal> web server to serve the same repository " | |
7103 "as I described with Apache above. I had already overcome all of the problems " | |
7104 "I outlined with Apache, many of which are not server-specific. As a result, " | |
7105 "I was fairly sure that my file and directory permissions were good, and that " | |
7106 "my <filename role=\"special\">hgweb.cgi</filename> script was properly edited." | |
7107 msgstr "" | |
7108 | |
7109 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
7110 #: ../en/ch06-collab.xml:1066 | |
7111 msgid "" | |
7112 "Once I had Apache running, getting <literal>lighttpd</literal> to serve the " | |
7113 "repository was a snap (in other words, even if you're trying to use " | |
7114 "<literal>lighttpd</literal>, you should read the Apache section). I first " | |
7115 "had to edit the <literal>mod_access</literal> section of its config file to " | |
7116 "enable <literal>mod_cgi</literal> and <literal>mod_userdir</literal>, both of " | |
7117 "which were disabled by default on my system. I then added a few lines to the " | |
7118 "end of the config file, to configure these modules." | |
7119 msgstr "" | |
7120 | |
7121 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
7122 #: ../en/ch06-collab.xml:1078 | |
7123 msgid "" | |
7124 "With this done, <literal>lighttpd</literal> ran immediately for me. If I had " | |
7125 "configured <literal>lighttpd</literal> before Apache, I'd almost certainly " | |
7126 "have run into many of the same system-level configuration problems as I did " | |
7127 "with Apache. However, I found <literal>lighttpd</literal> to be noticeably " | |
7128 "easier to configure than Apache, even though I've used Apache for over a " | |
7129 "decade, and this was my first exposure to <literal>lighttpd</literal>." | |
7130 msgstr "" | |
7131 | |
7132 #. type: Content of: <book><chapter><sect1><sect2><title> | |
7133 #: ../en/ch06-collab.xml:1091 | |
7134 msgid "Sharing multiple repositories with one CGI script" | |
7135 msgstr "" | |
7136 | |
7137 #. type: Content of: <book><chapter><sect1><sect2><para> | |
7138 #: ../en/ch06-collab.xml:1093 | |
7139 msgid "" | |
7140 "The <filename role=\"special\">hgweb.cgi</filename> script only lets you " | |
7141 "publish a single repository, which is an annoying restriction. If you want " | |
7142 "to publish more than one without wracking yourself with multiple copies of " | |
7143 "the same script, each with different names, a better choice is to use the " | |
7144 "<filename role=\"special\">hgwebdir.cgi</filename> script." | |
7145 msgstr "" | |
7146 | |
7147 #. type: Content of: <book><chapter><sect1><sect2><para> | |
7148 #: ../en/ch06-collab.xml:1101 | |
7149 msgid "" | |
7150 "The procedure to configure <filename role=\"special\">hgwebdir.cgi</filename> " | |
7151 "is only a little more involved than for <filename role=\"special\">hgweb.cgi</" | |
7152 "filename>. First, you must obtain a copy of the script. If you don't have " | |
7153 "one handy, you can download a copy from the master Mercurial repository at " | |
7154 "<ulink url=\"http://www.selenic.com/repo/hg/raw-file/tip/hgwebdir.cgi" | |
7155 "\">http://www.selenic.com/repo/hg/raw-file/tip/hgwebdir.cgi</ulink>." | |
7156 msgstr "" | |
7157 | |
7158 #. type: Content of: <book><chapter><sect1><sect2><para> | |
7159 #: ../en/ch06-collab.xml:1114 | |
7160 msgid "" | |
7161 "With basic configuration out of the way, try to visit <ulink url=\"http://" | |
7162 "myhostname/ myuser/hgwebdir.cgi\">http://myhostname/ myuser/hgwebdir.cgi</" | |
7163 "ulink> in your browser. It should display an empty list of repositories. If " | |
7164 "you get a blank window or error message, try walking through the list of " | |
7165 "potential problems in section <xref linkend=\"sec.collab.wtf\"/>." | |
7166 msgstr "" | |
7167 | |
7168 #. type: Content of: <book><chapter><sect1><sect2><para> | |
7169 #: ../en/ch06-collab.xml:1123 | |
7170 msgid "" | |
7171 "The <filename role=\"special\">hgwebdir.cgi</filename> script relies on an " | |
7172 "external configuration file. By default, it searches for a file named " | |
7173 "<filename role=\"special\">hgweb.config</filename> in the same directory as " | |
7174 "itself. You'll need to create this file, and make it world-readable. The " | |
7175 "format of the file is similar to a Windows <quote>ini</quote> file, as " | |
7176 "understood by Python's <literal>ConfigParser</literal> <citation>web:" | |
7177 "configparser</citation> module." | |
7178 msgstr "" | |
7179 | |
7180 #. type: Content of: <book><chapter><sect1><sect2><para> | |
7181 #: ../en/ch06-collab.xml:1133 | |
7182 msgid "" | |
7183 "The easiest way to configure <filename role=\"special\">hgwebdir.cgi</" | |
7184 "filename> is with a section named <literal>collections</literal>. This will " | |
7185 "automatically publish <emphasis>every</emphasis> repository under the " | |
7186 "directories you name. The section should look like this:" | |
7187 msgstr "" | |
7188 | |
7189 #. type: Content of: <book><chapter><sect1><sect2><para> | |
7190 #: ../en/ch06-collab.xml:1141 | |
7191 msgid "" | |
7192 "Mercurial interprets this by looking at the directory name on the " | |
7193 "<emphasis>right</emphasis> hand side of the <quote><literal>=</literal></" | |
7194 "quote> sign; finding repositories in that directory hierarchy; and using the " | |
7195 "text on the <emphasis>left</emphasis> to strip off matching text from the " | |
7196 "names it will actually list in the web interface. The remaining component of " | |
7197 "a path after this stripping has occurred is called a <quote>virtual path</" | |
7198 "quote>." | |
7199 msgstr "" | |
7200 | |
7201 #. type: Content of: <book><chapter><sect1><sect2><para> | |
7202 #: ../en/ch06-collab.xml:1150 | |
7203 msgid "" | |
7204 "Given the example above, if we have a repository whose local path is " | |
7205 "<filename class=\"directory\">/my/root/this/repo</filename>, the CGI script " | |
7206 "will strip the leading <filename class=\"directory\">/my/root</filename> from " | |
7207 "the name, and publish the repository with a virtual path of <filename class=" | |
7208 "\"directory\">this/repo</filename>. If the base URL for our CGI script is " | |
7209 "<ulink url=\"http://myhostname/ myuser/hgwebdir.cgi\">http://myhostname/ " | |
7210 "myuser/hgwebdir.cgi</ulink>, the complete URL for that repository will be " | |
7211 "<ulink url=\"http://myhostname/ myuser/hgwebdir.cgi/this/repo\">http://" | |
7212 "myhostname/ myuser/hgwebdir.cgi/this/repo</ulink>." | |
7213 msgstr "" | |
7214 | |
7215 #. type: Content of: <book><chapter><sect1><sect2><para> | |
7216 #: ../en/ch06-collab.xml:1164 | |
7217 msgid "" | |
7218 "If we replace <filename class=\"directory\">/my/root</filename> on the left " | |
7219 "hand side of this example with <filename class=\"directory\">/my</filename>, " | |
7220 "then <filename role=\"special\">hgwebdir.cgi</filename> will only strip off " | |
7221 "<filename class=\"directory\">/my</filename> from the repository name, and " | |
7222 "will give us a virtual path of <filename class=\"directory\">root/this/repo</" | |
7223 "filename> instead of <filename class=\"directory\">this/repo</filename>." | |
7224 msgstr "" | |
7225 | |
7226 #. type: Content of: <book><chapter><sect1><sect2><para> | |
7227 #: ../en/ch06-collab.xml:1174 | |
7228 msgid "" | |
7229 "The <filename role=\"special\">hgwebdir.cgi</filename> script will " | |
7230 "recursively search each directory listed in the <literal>collections</" | |
7231 "literal> section of its configuration file, but it will <literal>not</" | |
7232 "literal> recurse into the repositories it finds." | |
7233 msgstr "" | |
7234 | |
7235 #. type: Content of: <book><chapter><sect1><sect2><para> | |
7236 #: ../en/ch06-collab.xml:1180 | |
7237 msgid "" | |
7238 "The <literal>collections</literal> mechanism makes it easy to publish many " | |
7239 "repositories in a <quote>fire and forget</quote> manner. You only need to " | |
7240 "set up the CGI script and configuration file one time. Afterwards, you can " | |
7241 "publish or unpublish a repository at any time by simply moving it into, or " | |
7242 "out of, the directory hierarchy in which you've configured <filename role=" | |
7243 "\"special\">hgwebdir.cgi</filename> to look." | |
7244 msgstr "" | |
7245 | |
7246 #. type: Content of: <book><chapter><sect1><sect2><sect3><title> | |
7247 #: ../en/ch06-collab.xml:1190 | |
7248 msgid "Explicitly specifying which repositories to publish" | |
7249 msgstr "" | |
7250 | |
7251 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
7252 #: ../en/ch06-collab.xml:1193 | |
7253 msgid "" | |
7254 "In addition to the <literal>collections</literal> mechanism, the <filename " | |
7255 "role=\"special\">hgwebdir.cgi</filename> script allows you to publish a " | |
7256 "specific list of repositories. To do so, create a <literal>paths</literal> " | |
7257 "section, with contents of the following form." | |
7258 msgstr "" | |
7259 | |
7260 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
7261 #: ../en/ch06-collab.xml:1201 | |
7262 msgid "" | |
7263 "In this case, the virtual path (the component that will appear in a URL) is " | |
7264 "on the left hand side of each definition, while the path to the repository is " | |
7265 "on the right. Notice that there does not need to be any relationship between " | |
7266 "the virtual path you choose and the location of a repository in your " | |
7267 "filesystem." | |
7268 msgstr "" | |
7269 | |
7270 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
7271 #: ../en/ch06-collab.xml:1208 | |
7272 msgid "" | |
7273 "If you wish, you can use both the <literal>collections</literal> and " | |
7274 "<literal>paths</literal> mechanisms simultaneously in a single configuration " | |
7275 "file." | |
7276 msgstr "" | |
7277 | |
7278 #. type: Content of: <book><chapter><sect1><sect2><sect3><note><para> | |
7279 #: ../en/ch06-collab.xml:1214 | |
7280 msgid "" | |
7281 "If multiple repositories have the same virtual path, <filename role=\"special" | |
7282 "\">hgwebdir.cgi</filename> will not report an error. Instead, it will behave " | |
7283 "unpredictably." | |
7284 msgstr "" | |
7285 | |
7286 #. type: Content of: <book><chapter><sect1><sect2><title> | |
7287 #: ../en/ch06-collab.xml:1223 | |
7288 msgid "Downloading source archives" | |
7289 msgstr "" | |
7290 | |
7291 #. type: Content of: <book><chapter><sect1><sect2><para> | |
7292 #: ../en/ch06-collab.xml:1225 | |
7293 msgid "" | |
7294 "Mercurial's web interface lets users download an archive of any revision. " | |
7295 "This archive will contain a snapshot of the working directory as of that " | |
7296 "revision, but it will not contain a copy of the repository data." | |
7297 msgstr "" | |
7298 | |
7299 #. type: Content of: <book><chapter><sect1><sect2><para> | |
7300 #: ../en/ch06-collab.xml:1230 | |
7301 msgid "" | |
7302 "By default, this feature is not enabled. To enable it, you'll need to add an " | |
7303 "<envar role=\"rc-item-web\">allow_archive</envar> item to the <literal role=" | |
7304 "\"rc-web\">web</literal> section of your <filename role=\"special\"> /.hgrc</" | |
7305 "filename>." | |
7306 msgstr "" | |
7307 | |
7308 #. type: Content of: <book><chapter><sect1><sect2><title> | |
7309 #: ../en/ch06-collab.xml:1238 | |
7310 msgid "Web configuration options" | |
7311 msgstr "" | |
7312 | |
7313 #. type: Content of: <book><chapter><sect1><sect2><para> | |
7314 #: ../en/ch06-collab.xml:1240 | |
7315 msgid "" | |
7316 "Mercurial's web interfaces (the <command role=\"hg-cmd\">hg serve</command> " | |
7317 "command, and the <filename role=\"special\">hgweb.cgi</filename> and " | |
7318 "<filename role=\"special\">hgwebdir.cgi</filename> scripts) have a number of " | |
7319 "configuration options that you can set. These belong in a section named " | |
7320 "<literal role=\"rc-web\">web</literal>." | |
7321 msgstr "" | |
7322 | |
7323 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
7324 #: ../en/ch06-collab.xml:1248 | |
7325 msgid "" | |
7326 "<envar role=\"rc-item-web\">allow_archive</envar>: Determines which (if any) " | |
7327 "archive download mechanisms Mercurial supports. If you enable this feature, " | |
7328 "users of the web interface will be able to download an archive of whatever " | |
7329 "revision of a repository they are viewing. To enable the archive feature, " | |
7330 "this item must take the form of a sequence of words drawn from the list below." | |
7331 msgstr "" | |
7332 | |
7333 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><itemizedlist><listitem><para> | |
7334 #: ../en/ch06-collab.xml:1257 | |
7335 msgid "" | |
7336 "<literal>bz2</literal>: A <command>tar</command> archive, compressed using " | |
7337 "<literal>bzip2</literal> compression. This has the best compression ratio, " | |
7338 "but uses the most CPU time on the server." | |
7339 msgstr "" | |
7340 | |
7341 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><itemizedlist><listitem><para> | |
7342 #: ../en/ch06-collab.xml:1263 | |
7343 msgid "" | |
7344 "<literal>gz</literal>: A <command>tar</command> archive, compressed using " | |
7345 "<literal>gzip</literal> compression." | |
7346 msgstr "" | |
7347 | |
7348 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><itemizedlist><listitem><para> | |
7349 #: ../en/ch06-collab.xml:1267 | |
7350 msgid "" | |
7351 "<literal>zip</literal>: A <command>zip</command> archive, compressed using " | |
7352 "LZW compression. This format has the worst compression ratio, but is widely " | |
7353 "used in the Windows world." | |
7354 msgstr "" | |
7355 | |
7356 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
7357 #: ../en/ch06-collab.xml:1273 | |
7358 msgid "" | |
7359 "If you provide an empty list, or don't have an <envar role=\"rc-item-web" | |
7360 "\">allow_archive</envar> entry at all, this feature will be disabled. Here " | |
7361 "is an example of how to enable all three supported formats." | |
7362 msgstr "" | |
7363 | |
7364 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
7365 #: ../en/ch06-collab.xml:1280 | |
7366 msgid "" | |
7367 "<envar role=\"rc-item-web\">allowpull</envar>: Boolean. Determines whether " | |
7368 "the web interface allows remote users to <command role=\"hg-cmd\">hg pull</" | |
7369 "command> and <command role=\"hg-cmd\">hg clone</command> this repository over " | |
7370 "HTTP. If set to <literal>no</literal> or <literal>false</literal>, only the " | |
7371 "<quote>human-oriented</quote> portion of the web interface is available." | |
7372 msgstr "" | |
7373 | |
7374 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
7375 #: ../en/ch06-collab.xml:1289 | |
7376 msgid "" | |
7377 "<envar role=\"rc-item-web\">contact</envar>: String. A free-form (but " | |
7378 "preferably brief) string identifying the person or group in charge of the " | |
7379 "repository. This often contains the name and email address of a person or " | |
7380 "mailing list. It often makes sense to place this entry in a repository's own " | |
7381 "<filename role=\"special\">.hg/hgrc</filename> file, but it can make sense to " | |
7382 "use in a global <filename role=\"special\"> /.hgrc</filename>\\ if every " | |
7383 "repository has a single maintainer." | |
7384 msgstr "" | |
7385 | |
7386 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
7387 #: ../en/ch06-collab.xml:1300 | |
7388 msgid "" | |
7389 "<envar role=\"rc-item-web\">maxchanges</envar>: Integer. The default maximum " | |
7390 "number of changesets to display in a single page of output." | |
7391 msgstr "" | |
7392 | |
7393 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
7394 #: ../en/ch06-collab.xml:1304 | |
7395 msgid "" | |
7396 "<envar role=\"rc-item-web\">maxfiles</envar>: Integer. The default maximum " | |
7397 "number of modified files to display in a single page of output." | |
7398 msgstr "" | |
7399 | |
7400 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
7401 #: ../en/ch06-collab.xml:1308 | |
7402 msgid "" | |
7403 "<envar role=\"rc-item-web\">stripes</envar>: Integer. If the web interface " | |
7404 "displays alternating <quote>stripes</quote> to make it easier to visually " | |
7405 "align rows when you are looking at a table, this number controls the number " | |
7406 "of rows in each stripe." | |
7407 msgstr "" | |
7408 | |
7409 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
7410 #: ../en/ch06-collab.xml:1314 | |
7411 msgid "" | |
7412 "<envar role=\"rc-item-web\">style</envar>: Controls the template Mercurial " | |
7413 "uses to display the web interface. Mercurial ships with two web templates, " | |
7414 "named <literal>default</literal> and <literal>gitweb</literal> (the latter is " | |
7415 "much more visually attractive). You can also specify a custom template of " | |
7416 "your own; see chapter <xref linkend=\"chap.template\"/> for details. Here, " | |
7417 "you can see how to enable the <literal>gitweb</literal> style." | |
7418 msgstr "" | |
7419 | |
7420 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
7421 #: ../en/ch06-collab.xml:1325 | |
7422 msgid "" | |
7423 "<envar role=\"rc-item-web\">templates</envar>: Path. The directory in which " | |
7424 "to search for template files. By default, Mercurial searches in the " | |
7425 "directory in which it was installed." | |
7426 msgstr "" | |
7427 | |
7428 #. type: Content of: <book><chapter><sect1><sect2><para> | |
7429 #: ../en/ch06-collab.xml:1330 | |
7430 msgid "" | |
7431 "If you are using <filename role=\"special\">hgwebdir.cgi</filename>, you can " | |
7432 "place a few configuration items in a <literal role=\"rc-web\">web</literal> " | |
7433 "section of the <filename role=\"special\">hgweb.config</filename> file " | |
7434 "instead of a <filename role=\"special\"> /.hgrc</filename>\\ file, for " | |
7435 "convenience. These items are <envar role=\"rc-item-web\">motd</envar> and " | |
7436 "<envar role=\"rc-item-web\">style</envar>." | |
7437 msgstr "" | |
7438 | |
7439 #. type: Content of: <book><chapter><sect1><sect2><sect3><title> | |
7440 #: ../en/ch06-collab.xml:1341 | |
7441 msgid "Options specific to an individual repository" | |
7442 msgstr "" | |
7443 | |
7444 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
7445 #: ../en/ch06-collab.xml:1343 | |
7446 msgid "" | |
7447 "A few <literal role=\"rc-web\">web</literal> configuration items ought to be " | |
7448 "placed in a repository's local <filename role=\"special\">.hg/hgrc</" | |
7449 "filename>, rather than a user's or global <filename role=\"special\"> /.hgrc</" | |
7450 "filename>." | |
7451 msgstr "" | |
7452 | |
7453 #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para> | |
7454 #: ../en/ch06-collab.xml:1349 | |
7455 msgid "" | |
7456 "<envar role=\"rc-item-web\">description</envar>: String. A free-form (but " | |
7457 "preferably brief) string that describes the contents or purpose of the " | |
7458 "repository." | |
7459 msgstr "" | |
7460 | |
7461 #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para> | |
7462 #: ../en/ch06-collab.xml:1354 | |
7463 msgid "" | |
7464 "<envar role=\"rc-item-web\">name</envar>: String. The name to use for the " | |
7465 "repository in the web interface. This overrides the default name, which is " | |
7466 "the last component of the repository's path." | |
7467 msgstr "" | |
7468 | |
7469 #. type: Content of: <book><chapter><sect1><sect2><sect3><title> | |
7470 #: ../en/ch06-collab.xml:1362 | |
7471 msgid "" | |
7472 "Options specific to the <command role=\"hg-cmd\">hg serve</command> command" | |
7473 msgstr "" | |
7474 | |
7475 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
7476 #: ../en/ch06-collab.xml:1365 | |
7477 msgid "" | |
7478 "Some of the items in the <literal role=\"rc-web\">web</literal> section of a " | |
7479 "<filename role=\"special\"> /.hgrc</filename>\\ file are only for use with " | |
7480 "the <command role=\"hg-cmd\">hg serve</command> command." | |
7481 msgstr "" | |
7482 | |
7483 #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para> | |
7484 #: ../en/ch06-collab.xml:1371 | |
7485 msgid "" | |
7486 "<envar role=\"rc-item-web\">accesslog</envar>: Path. The name of a file into " | |
7487 "which to write an access log. By default, the <command role=\"hg-cmd\">hg " | |
7488 "serve</command> command writes this information to standard output, not to a " | |
7489 "file. Log entries are written in the standard <quote>combined</quote> file " | |
7490 "format used by almost all web servers." | |
7491 msgstr "" | |
7492 | |
7493 #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para> | |
7494 #: ../en/ch06-collab.xml:1379 | |
7495 msgid "" | |
7496 "<envar role=\"rc-item-web\">address</envar>: String. The local address on " | |
7497 "which the server should listen for incoming connections. By default, the " | |
7498 "server listens on all addresses." | |
7499 msgstr "" | |
7500 | |
7501 #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para> | |
7502 #: ../en/ch06-collab.xml:1384 | |
7503 msgid "" | |
7504 "<envar role=\"rc-item-web\">errorlog</envar>: Path. The name of a file into " | |
7505 "which to write an error log. By default, the <command role=\"hg-cmd\">hg " | |
7506 "serve</command> command writes this information to standard error, not to a " | |
7507 "file." | |
7508 msgstr "" | |
7509 | |
7510 #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para> | |
7511 #: ../en/ch06-collab.xml:1390 | |
7512 msgid "" | |
7513 "<envar role=\"rc-item-web\">ipv6</envar>: Boolean. Whether to use the IPv6 " | |
7514 "protocol. By default, IPv6 is not used." | |
7515 msgstr "" | |
7516 | |
7517 #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para> | |
7518 #: ../en/ch06-collab.xml:1394 | |
7519 msgid "" | |
7520 "<envar role=\"rc-item-web\">port</envar>: Integer. The TCP port number on " | |
7521 "which the server should listen. The default port number used is 8000." | |
7522 msgstr "" | |
7523 | |
7524 #. type: Content of: <book><chapter><sect1><sect2><sect3><title> | |
7525 #: ../en/ch06-collab.xml:1401 | |
7526 msgid "" | |
7527 "Choosing the right <filename role=\"special\"> /.hgrc</filename>\\ file to " | |
7528 "add <literal role=\"rc-web\">web</literal> items to" | |
7529 msgstr "" | |
7530 | |
7531 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
7532 #: ../en/ch06-collab.xml:1405 | |
7533 msgid "" | |
7534 "It is important to remember that a web server like Apache or " | |
7535 "<literal>lighttpd</literal> will run under a user ID that is different to " | |
7536 "yours. CGI scripts run by your server, such as <filename role=\"special" | |
7537 "\">hgweb.cgi</filename>, will usually also run under that user ID." | |
7538 msgstr "" | |
7539 | |
7540 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
7541 #: ../en/ch06-collab.xml:1412 | |
7542 msgid "" | |
7543 "If you add <literal role=\"rc-web\">web</literal> items to your own personal " | |
7544 "<filename role=\"special\"> /.hgrc</filename>\\ file, CGI scripts won't read " | |
7545 "that <filename role=\"special\"> /.hgrc</filename>\\ file. Those settings " | |
7546 "will thus only affect the behaviour of the <command role=\"hg-cmd\">hg serve</" | |
7547 "command> command when you run it. To cause CGI scripts to see your settings, " | |
7548 "either create a <filename role=\"special\"> /.hgrc</filename>\\ file in the " | |
7549 "home directory of the user ID that runs your web server, or add those " | |
7550 "settings to a system-wide <filename role=\"special\"> /.hgrc</filename>\\ " | |
7551 "file." | |
7552 msgstr "" | |
7553 | |
7554 #. type: Content of: <book><chapter><title> | |
7555 #: ../en/ch07-filenames.xml:5 | |
7556 msgid "File names and pattern matching" | |
7557 msgstr "文件名称与模式匹配" | |
7558 | |
7559 #. type: Content of: <book><chapter><para> | |
7560 #: ../en/ch07-filenames.xml:7 | |
7561 msgid "" | |
7562 "Mercurial provides mechanisms that let you work with file names in a " | |
7563 "consistent and expressive way." | |
7564 msgstr "" | |
7565 | |
7566 #. type: Content of: <book><chapter><sect1><title> | |
7567 #: ../en/ch07-filenames.xml:11 | |
7568 msgid "Simple file naming" | |
7569 msgstr "" | |
7570 | |
7571 #. type: Content of: <book><chapter><sect1><para> | |
7572 #: ../en/ch07-filenames.xml:13 | |
7573 msgid "" | |
7574 "Mercurial uses a unified piece of machinery <quote>under the hood</quote> to " | |
7575 "handle file names. Every command behaves uniformly with respect to file " | |
7576 "names. The way in which commands work with file names is as follows." | |
7577 msgstr "" | |
7578 | |
7579 #. type: Content of: <book><chapter><sect1><para> | |
7580 #: ../en/ch07-filenames.xml:18 | |
7581 msgid "" | |
7582 "If you explicitly name real files on the command line, Mercurial works with " | |
7583 "exactly those files, as you would expect. &interaction.filenames.files;" | |
7584 msgstr "" | |
7585 | |
7586 # | |
7587 #. type: Content of: <book><chapter><sect1><para> | |
7588 #: ../en/ch07-filenames.xml:22 | |
7589 msgid "" | |
7590 "When you provide a directory name, Mercurial will interpret this as " | |
7591 "<quote>operate on every file in this directory and its subdirectories</" | |
7592 "quote>. Mercurial traverses the files and subdirectories in a directory in " | |
7593 "alphabetical order. When it encounters a subdirectory, it will traverse that " | |
7594 "subdirectory before continuing with the current directory." | |
7595 msgstr "" | |
7596 | |
7597 #. type: Content of: <book><chapter><sect1><title> | |
7598 #: ../en/ch07-filenames.xml:33 | |
7599 msgid "Running commands without any file names" | |
7600 msgstr "" | |
7601 | |
7602 #. type: Content of: <book><chapter><sect1><para> | |
7603 #: ../en/ch07-filenames.xml:35 | |
7604 msgid "" | |
7605 "Mercurial's commands that work with file names have useful default behaviours " | |
7606 "when you invoke them without providing any file names or patterns. What kind " | |
7607 "of behaviour you should expect depends on what the command does. Here are a " | |
7608 "few rules of thumb you can use to predict what a command is likely to do if " | |
7609 "you don't give it any names to work with." | |
7610 msgstr "" | |
7611 | |
7612 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
7613 #: ../en/ch07-filenames.xml:42 | |
7614 msgid "" | |
7615 "Most commands will operate on the entire working directory. This is what the " | |
7616 "<command role=\"hg-cmd\">hg add</command> command does, for example." | |
7617 msgstr "" | |
7618 | |
7619 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
7620 #: ../en/ch07-filenames.xml:46 | |
7621 msgid "" | |
7622 "If the command has effects that are difficult or impossible to reverse, it " | |
7623 "will force you to explicitly provide at least one name or pattern (see " | |
7624 "below). This protects you from accidentally deleting files by running " | |
7625 "<command role=\"hg-cmd\">hg remove</command> with no arguments, for example." | |
7626 msgstr "" | |
7627 | |
7628 # | |
7629 #. type: Content of: <book><chapter><sect1><para> | |
7630 #: ../en/ch07-filenames.xml:54 | |
7631 msgid "" | |
7632 "It's easy to work around these default behaviours if they don't suit you. If " | |
7633 "a command normally operates on the whole working directory, you can invoke it " | |
7634 "on just the current directory and its subdirectories by giving it the name " | |
7635 "<quote><filename class=\"directory\">.</filename></quote>." | |
7636 msgstr "" | |
7637 | |
7638 # | |
7639 #. type: Content of: <book><chapter><sect1><para> | |
7640 #: ../en/ch07-filenames.xml:62 | |
7641 msgid "" | |
7642 "Along the same lines, some commands normally print file names relative to the " | |
7643 "root of the repository, even if you're invoking them from a subdirectory. " | |
7644 "Such a command will print file names relative to your subdirectory if you " | |
7645 "give it explicit names. Here, we're going to run <command role=\"hg-cmd\">hg " | |
7646 "status</command> from a subdirectory, and get it to operate on the entire " | |
7647 "working directory while printing file names relative to our subdirectory, by " | |
7648 "passing it the output of the <command role=\"hg-cmd\">hg root</command> " | |
7649 "command." | |
7650 msgstr "" | |
7651 | |
7652 #. type: Content of: <book><chapter><sect1><title> | |
7653 #: ../en/ch07-filenames.xml:76 | |
7654 msgid "Telling you what's going on" | |
7655 msgstr "" | |
7656 | |
7657 #. type: Content of: <book><chapter><sect1><para> | |
7658 #: ../en/ch07-filenames.xml:78 | |
7659 msgid "" | |
7660 "The <command role=\"hg-cmd\">hg add</command> example in the preceding " | |
7661 "section illustrates something else that's helpful about Mercurial commands. " | |
7662 "If a command operates on a file that you didn't name explicitly on the " | |
7663 "command line, it will usually print the name of the file, so that you will " | |
7664 "not be surprised what's going on." | |
7665 msgstr "" | |
7666 | |
7667 #. type: Content of: <book><chapter><sect1><para> | |
7668 #: ../en/ch07-filenames.xml:85 | |
7669 msgid "" | |
7670 "The principle here is of <emphasis>least surprise</emphasis>. If you've " | |
7671 "exactly named a file on the command line, there's no point in repeating it " | |
7672 "back at you. If Mercurial is acting on a file <emphasis>implicitly</" | |
7673 "emphasis>, because you provided no names, or a directory, or a pattern (see " | |
7674 "below), it's safest to tell you what it's doing." | |
7675 msgstr "" | |
7676 | |
7677 #. type: Content of: <book><chapter><sect1><para> | |
7678 #: ../en/ch07-filenames.xml:92 | |
7679 msgid "" | |
7680 "For commands that behave this way, you can silence them using the <option " | |
7681 "role=\"hg-opt-global\">-q</option> option. You can also get them to print " | |
7682 "the name of every file, even those you've named explicitly, using the <option " | |
7683 "role=\"hg-opt-global\">-v</option> option." | |
7684 msgstr "" | |
7685 | |
7686 #. type: Content of: <book><chapter><sect1><title> | |
7687 #: ../en/ch07-filenames.xml:100 | |
7688 msgid "Using patterns to identify files" | |
7689 msgstr "" | |
7690 | |
7691 #. type: Content of: <book><chapter><sect1><para> | |
7692 #: ../en/ch07-filenames.xml:102 | |
7693 msgid "" | |
7694 "In addition to working with file and directory names, Mercurial lets you use " | |
7695 "<emphasis>patterns</emphasis> to identify files. Mercurial's pattern " | |
7696 "handling is expressive." | |
7697 msgstr "" | |
7698 | |
7699 #. type: Content of: <book><chapter><sect1><para> | |
7700 #: ../en/ch07-filenames.xml:106 | |
7701 msgid "" | |
7702 "On Unix-like systems (Linux, MacOS, etc.), the job of matching file names to " | |
7703 "patterns normally falls to the shell. On these systems, you must explicitly " | |
7704 "tell Mercurial that a name is a pattern. On Windows, the shell does not " | |
7705 "expand patterns, so Mercurial will automatically identify names that are " | |
7706 "patterns, and expand them for you." | |
7707 msgstr "" | |
7708 | |
7709 #. type: Content of: <book><chapter><sect1><para> | |
7710 #: ../en/ch07-filenames.xml:113 | |
7711 msgid "" | |
7712 "To provide a pattern in place of a regular name on the command line, the " | |
7713 "mechanism is simple:" | |
7714 msgstr "" | |
7715 | |
7716 #. type: Content of: <book><chapter><sect1><para> | |
7717 #: ../en/ch07-filenames.xml:116 | |
7718 msgid "" | |
7719 "That is, a pattern is identified by a short text string that says what kind " | |
7720 "of pattern this is, followed by a colon, followed by the actual pattern." | |
7721 msgstr "" | |
7722 | |
7723 #. type: Content of: <book><chapter><sect1><para> | |
7724 #: ../en/ch07-filenames.xml:120 | |
7725 msgid "" | |
7726 "Mercurial supports two kinds of pattern syntax. The most frequently used is " | |
7727 "called <literal>glob</literal>; this is the same kind of pattern matching " | |
7728 "used by the Unix shell, and should be familiar to Windows command prompt " | |
7729 "users, too." | |
7730 msgstr "" | |
7731 | |
7732 #. type: Content of: <book><chapter><sect1><para> | |
7733 #: ../en/ch07-filenames.xml:125 | |
7734 msgid "" | |
7735 "When Mercurial does automatic pattern matching on Windows, it uses " | |
7736 "<literal>glob</literal> syntax. You can thus omit the <quote><literal>glob:</" | |
7737 "literal></quote> prefix on Windows, but it's safe to use it, too." | |
7738 msgstr "" | |
7739 | |
7740 #. type: Content of: <book><chapter><sect1><para> | |
7741 #: ../en/ch07-filenames.xml:130 | |
7742 msgid "" | |
7743 "The <literal>re</literal> syntax is more powerful; it lets you specify " | |
7744 "patterns using regular expressions, also known as regexps." | |
7745 msgstr "" | |
7746 | |
7747 #. type: Content of: <book><chapter><sect1><para> | |
7748 #: ../en/ch07-filenames.xml:134 | |
7749 msgid "" | |
7750 "By the way, in the examples that follow, notice that I'm careful to wrap all " | |
7751 "of my patterns in quote characters, so that they won't get expanded by the " | |
7752 "shell before Mercurial sees them." | |
7753 msgstr "" | |
7754 | |
7755 #. type: Content of: <book><chapter><sect1><sect2><title> | |
7756 #: ../en/ch07-filenames.xml:140 | |
7757 msgid "Shell-style <literal>glob</literal> patterns" | |
7758 msgstr "" | |
7759 | |
7760 #. type: Content of: <book><chapter><sect1><sect2><para> | |
7761 #: ../en/ch07-filenames.xml:142 | |
7762 msgid "" | |
7763 "This is an overview of the kinds of patterns you can use when you're matching " | |
7764 "on glob patterns." | |
7765 msgstr "" | |
7766 | |
7767 # | |
7768 #. type: Content of: <book><chapter><sect1><sect2><para> | |
7769 #: ../en/ch07-filenames.xml:145 | |
7770 msgid "" | |
7771 "The <quote><literal>*</literal></quote> character matches any string, within " | |
7772 "a single directory." | |
7773 msgstr "" | |
7774 | |
7775 # | |
7776 #. type: Content of: <book><chapter><sect1><sect2><para> | |
7777 #: ../en/ch07-filenames.xml:150 | |
7778 msgid "" | |
7779 "The <quote><literal>**</literal></quote> pattern matches any string, and " | |
7780 "crosses directory boundaries. It's not a standard Unix glob token, but it's " | |
7781 "accepted by several popular Unix shells, and is very useful." | |
7782 msgstr "" | |
7783 | |
7784 # | |
7785 #. type: Content of: <book><chapter><sect1><sect2><para> | |
7786 #: ../en/ch07-filenames.xml:157 | |
7787 msgid "" | |
7788 "The <quote><literal>?</literal></quote> pattern matches any single character." | |
7789 msgstr "" | |
7790 | |
7791 #. type: Content of: <book><chapter><sect1><sect2><para> | |
7792 #: ../en/ch07-filenames.xml:162 | |
7793 msgid "" | |
7794 "The <quote><literal>[</literal></quote> character begins a " | |
7795 "<emphasis>character class</emphasis>. This matches any single character " | |
7796 "within the class. The class ends with a <quote><literal>]</literal></quote> " | |
7797 "character. A class may contain multiple <emphasis>range</emphasis>s of the " | |
7798 "form <quote><literal>a-f</literal></quote>, which is shorthand for " | |
7799 "<quote><literal>abcdef</literal></quote>." | |
7800 msgstr "" | |
7801 | |
7802 #. type: Content of: <book><chapter><sect1><sect2><para> | |
7803 #: ../en/ch07-filenames.xml:172 | |
7804 msgid "" | |
7805 "If the first character after the <quote><literal>[</literal></quote> in a " | |
7806 "character class is a <quote><literal>!</literal></quote>, it " | |
7807 "<emphasis>negates</emphasis> the class, making it match any single character " | |
7808 "not in the class." | |
7809 msgstr "" | |
7810 | |
7811 #. type: Content of: <book><chapter><sect1><sect2><para> | |
7812 #: ../en/ch07-filenames.xml:178 | |
7813 msgid "" | |
7814 "A <quote><literal>{</literal></quote> begins a group of subpatterns, where " | |
7815 "the whole group matches if any subpattern in the group matches. The " | |
7816 "<quote><literal>,</literal></quote> character separates subpatterns, and " | |
7817 "<quote><literal>}</literal></quote> ends the group." | |
7818 msgstr "" | |
7819 | |
7820 #. type: Content of: <book><chapter><sect1><sect2><sect3><title> | |
7821 #: ../en/ch07-filenames.xml:187 | |
7822 msgid "Watch out!" | |
7823 msgstr "" | |
7824 | |
7825 # | |
7826 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
7827 #: ../en/ch07-filenames.xml:189 | |
7828 msgid "" | |
7829 "Don't forget that if you want to match a pattern in any directory, you should " | |
7830 "not be using the <quote><literal>*</literal></quote> match-any token, as this " | |
7831 "will only match within one directory. Instead, use the <quote><literal>**</" | |
7832 "literal></quote> token. This small example illustrates the difference " | |
7833 "between the two." | |
7834 msgstr "" | |
7835 | |
7836 #. type: Content of: <book><chapter><sect1><sect2><title> | |
7837 #: ../en/ch07-filenames.xml:201 | |
7838 msgid "Regular expression matching with <literal>re</literal> patterns" | |
7839 msgstr "" | |
7840 | |
7841 #. type: Content of: <book><chapter><sect1><sect2><para> | |
7842 #: ../en/ch07-filenames.xml:204 | |
7843 msgid "" | |
7844 "Mercurial accepts the same regular expression syntax as the Python " | |
7845 "programming language (it uses Python's regexp engine internally). This is " | |
7846 "based on the Perl language's regexp syntax, which is the most popular dialect " | |
7847 "in use (it's also used in Java, for example)." | |
7848 msgstr "" | |
7849 | |
7850 #. type: Content of: <book><chapter><sect1><sect2><para> | |
7851 #: ../en/ch07-filenames.xml:210 | |
7852 msgid "" | |
7853 "I won't discuss Mercurial's regexp dialect in any detail here, as regexps are " | |
7854 "not often used. Perl-style regexps are in any case already exhaustively " | |
7855 "documented on a multitude of web sites, and in many books. Instead, I will " | |
7856 "focus here on a few things you should know if you find yourself needing to " | |
7857 "use regexps with Mercurial." | |
7858 msgstr "" | |
7859 | |
7860 #. type: Content of: <book><chapter><sect1><sect2><para> | |
7861 #: ../en/ch07-filenames.xml:217 | |
7862 msgid "" | |
7863 "A regexp is matched against an entire file name, relative to the root of the " | |
7864 "repository. In other words, even if you're already in subbdirectory " | |
7865 "<filename class=\"directory\">foo</filename>, if you want to match files " | |
7866 "under this directory, your pattern must start with <quote><literal>foo/</" | |
7867 "literal></quote>." | |
7868 msgstr "" | |
7869 | |
7870 #. type: Content of: <book><chapter><sect1><sect2><para> | |
7871 #: ../en/ch07-filenames.xml:224 | |
7872 msgid "" | |
7873 "One thing to note, if you're familiar with Perl-style regexps, is that " | |
7874 "Mercurial's are <emphasis>rooted</emphasis>. That is, a regexp starts " | |
7875 "matching against the beginning of a string; it doesn't look for a match " | |
7876 "anywhere within the string. To match anywhere in a string, start your " | |
7877 "pattern with <quote><literal>.*</literal></quote>." | |
7878 msgstr "" | |
7879 | |
7880 #. type: Content of: <book><chapter><sect1><title> | |
7881 #: ../en/ch07-filenames.xml:234 | |
7882 msgid "Filtering files" | |
7883 msgstr "" | |
7884 | |
7885 #. type: Content of: <book><chapter><sect1><para> | |
7886 #: ../en/ch07-filenames.xml:236 | |
7887 msgid "" | |
7888 "Not only does Mercurial give you a variety of ways to specify files; it lets " | |
7889 "you further winnow those files using <emphasis>filters</emphasis>. Commands " | |
7890 "that work with file names accept two filtering options." | |
7891 msgstr "" | |
7892 | |
7893 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
7894 #: ../en/ch07-filenames.xml:241 | |
7895 msgid "" | |
7896 "<option role=\"hg-opt-global\">-I</option>, or <option role=\"hg-opt-global" | |
7897 "\">--include</option>, lets you specify a pattern that file names must match " | |
7898 "in order to be processed." | |
7899 msgstr "" | |
7900 | |
7901 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
7902 #: ../en/ch07-filenames.xml:246 | |
7903 msgid "" | |
7904 "<option role=\"hg-opt-global\">-X</option>, or <option role=\"hg-opt-global" | |
7905 "\">--exclude</option>, gives you a way to <emphasis>avoid</emphasis> " | |
7906 "processing files, if they match this pattern." | |
7907 msgstr "" | |
7908 | |
7909 #. type: Content of: <book><chapter><sect1><para> | |
7910 #: ../en/ch07-filenames.xml:251 | |
7911 msgid "" | |
7912 "You can provide multiple <option role=\"hg-opt-global\">-I</option> and " | |
7913 "<option role=\"hg-opt-global\">-X</option> options on the command line, and " | |
7914 "intermix them as you please. Mercurial interprets the patterns you provide " | |
7915 "using glob syntax by default (but you can use regexps if you need to)." | |
7916 msgstr "" | |
7917 | |
7918 #. type: Content of: <book><chapter><sect1><para> | |
7919 #: ../en/ch07-filenames.xml:258 | |
7920 msgid "" | |
7921 "You can read a <option role=\"hg-opt-global\">-I</option> filter as " | |
7922 "<quote>process only the files that match this filter</quote>." | |
7923 msgstr "" | |
7924 | |
7925 #. type: Content of: <book><chapter><sect1><para> | |
7926 #: ../en/ch07-filenames.xml:264 | |
7927 msgid "" | |
7928 "The <option role=\"hg-opt-global\">-X</option> filter is best read as " | |
7929 "<quote>process only the files that don't match this pattern</quote>." | |
7930 msgstr "" | |
7931 | |
7932 #. type: Content of: <book><chapter><sect1><title> | |
7933 #: ../en/ch07-filenames.xml:272 | |
7934 msgid "Ignoring unwanted files and directories" | |
7935 msgstr "" | |
7936 | |
7937 #. type: Content of: <book><chapter><sect1><para> | |
7938 #: ../en/ch07-filenames.xml:274 | |
7939 msgid "XXX." | |
7940 msgstr "" | |
7941 | |
7942 #. type: Content of: <book><chapter><sect1><title> | |
7943 #: ../en/ch07-filenames.xml:278 | |
7944 msgid "Case sensitivity" | |
7945 msgstr "" | |
7946 | |
7947 #. type: Content of: <book><chapter><sect1><para> | |
7948 #: ../en/ch07-filenames.xml:280 | |
7949 msgid "" | |
7950 "If you're working in a mixed development environment that contains both Linux " | |
7951 "(or other Unix) systems and Macs or Windows systems, you should keep in the " | |
7952 "back of your mind the knowledge that they treat the case (<quote>N</quote> " | |
7953 "versus <quote>n</quote>) of file names in incompatible ways. This is not " | |
7954 "very likely to affect you, and it's easy to deal with if it does, but it " | |
7955 "could surprise you if you don't know about it." | |
7956 msgstr "" | |
7957 | |
7958 #. type: Content of: <book><chapter><sect1><para> | |
7959 #: ../en/ch07-filenames.xml:289 | |
7960 msgid "" | |
7961 "Operating systems and filesystems differ in the way they handle the " | |
7962 "<emphasis>case</emphasis> of characters in file and directory names. There " | |
7963 "are three common ways to handle case in names." | |
7964 msgstr "" | |
7965 | |
7966 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
7967 #: ../en/ch07-filenames.xml:294 | |
7968 msgid "" | |
7969 "Completely case insensitive. Uppercase and lowercase versions of a letter " | |
7970 "are treated as identical, both when creating a file and during subsequent " | |
7971 "accesses. This is common on older DOS-based systems." | |
7972 msgstr "" | |
7973 | |
7974 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
7975 #: ../en/ch07-filenames.xml:299 | |
7976 msgid "" | |
7977 "Case preserving, but insensitive. When a file or directory is created, the " | |
7978 "case of its name is stored, and can be retrieved and displayed by the " | |
7979 "operating system. When an existing file is being looked up, its case is " | |
7980 "ignored. This is the standard arrangement on Windows and MacOS. The names " | |
7981 "<filename>foo</filename> and <filename>FoO</filename> identify the same " | |
7982 "file. This treatment of uppercase and lowercase letters as interchangeable " | |
7983 "is also referred to as <emphasis>case folding</emphasis>." | |
7984 msgstr "" | |
7985 | |
7986 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
7987 #: ../en/ch07-filenames.xml:310 | |
7988 msgid "" | |
7989 "Case sensitive. The case of a name is significant at all times. The names " | |
7990 "<filename>foo</filename> and {FoO} identify different files. This is the way " | |
7991 "Linux and Unix systems normally work." | |
7992 msgstr "" | |
7993 | |
7994 #. type: Content of: <book><chapter><sect1><para> | |
7995 #: ../en/ch07-filenames.xml:316 | |
7996 msgid "" | |
7997 "On Unix-like systems, it is possible to have any or all of the above ways of " | |
7998 "handling case in action at once. For example, if you use a USB thumb drive " | |
7999 "formatted with a FAT32 filesystem on a Linux system, Linux will handle names " | |
8000 "on that filesystem in a case preserving, but insensitive, way." | |
8001 msgstr "" | |
8002 | |
8003 #. type: Content of: <book><chapter><sect1><sect2><title> | |
8004 #: ../en/ch07-filenames.xml:323 | |
8005 msgid "Safe, portable repository storage" | |
8006 msgstr "" | |
8007 | |
8008 #. type: Content of: <book><chapter><sect1><sect2><para> | |
8009 #: ../en/ch07-filenames.xml:325 | |
8010 msgid "" | |
8011 "Mercurial's repository storage mechanism is <emphasis>case safe</emphasis>. " | |
8012 "It translates file names so that they can be safely stored on both case " | |
8013 "sensitive and case insensitive filesystems. This means that you can use " | |
8014 "normal file copying tools to transfer a Mercurial repository onto, for " | |
8015 "example, a USB thumb drive, and safely move that drive and repository back " | |
8016 "and forth between a Mac, a PC running Windows, and a Linux box." | |
8017 msgstr "" | |
8018 | |
8019 #. type: Content of: <book><chapter><sect1><sect2><title> | |
8020 #: ../en/ch07-filenames.xml:336 | |
8021 msgid "Detecting case conflicts" | |
8022 msgstr "" | |
8023 | |
8024 #. type: Content of: <book><chapter><sect1><sect2><para> | |
8025 #: ../en/ch07-filenames.xml:338 | |
8026 msgid "" | |
8027 "When operating in the working directory, Mercurial honours the naming policy " | |
8028 "of the filesystem where the working directory is located. If the filesystem " | |
8029 "is case preserving, but insensitive, Mercurial will treat names that differ " | |
8030 "only in case as the same." | |
8031 msgstr "" | |
8032 | |
8033 #. type: Content of: <book><chapter><sect1><sect2><para> | |
8034 #: ../en/ch07-filenames.xml:344 | |
8035 msgid "" | |
8036 "An important aspect of this approach is that it is possible to commit a " | |
8037 "changeset on a case sensitive (typically Linux or Unix) filesystem that will " | |
8038 "cause trouble for users on case insensitive (usually Windows and MacOS) " | |
8039 "users. If a Linux user commits changes to two files, one named " | |
8040 "<filename>myfile.c</filename> and the other named <filename>MyFile.C</" | |
8041 "filename>, they will be stored correctly in the repository. And in the " | |
8042 "working directories of other Linux users, they will be correctly represented " | |
8043 "as separate files." | |
8044 msgstr "" | |
8045 | |
8046 #. type: Content of: <book><chapter><sect1><sect2><para> | |
8047 #: ../en/ch07-filenames.xml:355 | |
8048 msgid "" | |
8049 "If a Windows or Mac user pulls this change, they will not initially have a " | |
8050 "problem, because Mercurial's repository storage mechanism is case safe. " | |
8051 "However, once they try to <command role=\"hg-cmd\">hg update</command> the " | |
8052 "working directory to that changeset, or <command role=\"hg-cmd\">hg merge</" | |
8053 "command> with that changeset, Mercurial will spot the conflict between the " | |
8054 "two file names that the filesystem would treat as the same, and forbid the " | |
8055 "update or merge from occurring." | |
8056 msgstr "" | |
8057 | |
8058 #. type: Content of: <book><chapter><sect1><sect2><title> | |
8059 #: ../en/ch07-filenames.xml:367 | |
8060 msgid "Fixing a case conflict" | |
8061 msgstr "" | |
8062 | |
8063 #. type: Content of: <book><chapter><sect1><sect2><para> | |
8064 #: ../en/ch07-filenames.xml:369 | |
8065 msgid "" | |
8066 "If you are using Windows or a Mac in a mixed environment where some of your " | |
8067 "collaborators are using Linux or Unix, and Mercurial reports a case folding " | |
8068 "conflict when you try to <command role=\"hg-cmd\">hg update</command> or " | |
8069 "<command role=\"hg-cmd\">hg merge</command>, the procedure to fix the problem " | |
8070 "is simple." | |
8071 msgstr "" | |
8072 | |
8073 #. type: Content of: <book><chapter><sect1><sect2><para> | |
8074 #: ../en/ch07-filenames.xml:376 | |
8075 msgid "" | |
8076 "Just find a nearby Linux or Unix box, clone the problem repository onto it, " | |
8077 "and use Mercurial's <command role=\"hg-cmd\">hg rename</command> command to " | |
8078 "change the names of any offending files or directories so that they will no " | |
8079 "longer cause case folding conflicts. Commit this change, <command role=\"hg-" | |
8080 "cmd\">hg pull</command> or <command role=\"hg-cmd\">hg push</command> it " | |
8081 "across to your Windows or MacOS system, and <command role=\"hg-cmd\">hg " | |
8082 "update</command> to the revision with the non-conflicting names." | |
8083 msgstr "" | |
8084 | |
8085 #. type: Content of: <book><chapter><sect1><sect2><para> | |
8086 #: ../en/ch07-filenames.xml:386 | |
8087 msgid "" | |
8088 "The changeset with case-conflicting names will remain in your project's " | |
8089 "history, and you still won't be able to <command role=\"hg-cmd\">hg update</" | |
8090 "command> your working directory to that changeset on a Windows or MacOS " | |
8091 "system, but you can continue development unimpeded." | |
8092 msgstr "" | |
8093 | |
8094 #. type: Content of: <book><chapter><sect1><sect2><note><para> | |
8095 #: ../en/ch07-filenames.xml:393 | |
8096 msgid "" | |
8097 "Prior to version 0.9.3, Mercurial did not use a case safe repository storage " | |
8098 "mechanism, and did not detect case folding conflicts. If you are using an " | |
8099 "older version of Mercurial on Windows or MacOS, I strongly recommend that you " | |
8100 "upgrade." | |
8101 msgstr "" | |
8102 | |
8103 #. type: Content of: <book><chapter><title> | |
8104 #: ../en/ch08-branch.xml:5 | |
8105 msgid "Managing releases and branchy development" | |
8106 msgstr "发布管理与分支开发" | |
8107 | |
8108 #. type: Content of: <book><chapter><para> | |
8109 #: ../en/ch08-branch.xml:7 | |
8110 msgid "" | |
8111 "Mercurial provides several mechanisms for you to manage a project that is " | |
8112 "making progress on multiple fronts at once. To understand these mechanisms, " | |
8113 "let's first take a brief look at a fairly normal software project structure." | |
8114 msgstr "" | |
8115 | |
8116 #. type: Content of: <book><chapter><para> | |
8117 #: ../en/ch08-branch.xml:12 | |
8118 msgid "" | |
8119 "Many software projects issue periodic <quote>major</quote> releases that " | |
8120 "contain substantial new features. In parallel, they may issue <quote>minor</" | |
8121 "quote> releases. These are usually identical to the major releases off which " | |
8122 "they're based, but with a few bugs fixed." | |
8123 msgstr "" | |
8124 | |
8125 #. type: Content of: <book><chapter><para> | |
8126 #: ../en/ch08-branch.xml:18 | |
8127 msgid "" | |
8128 "In this chapter, we'll start by talking about how to keep records of project " | |
8129 "milestones such as releases. We'll then continue on to talk about the flow " | |
8130 "of work between different phases of a project, and how Mercurial can help you " | |
8131 "to isolate and manage this work." | |
8132 msgstr "" | |
8133 | |
8134 #. type: Content of: <book><chapter><sect1><title> | |
8135 #: ../en/ch08-branch.xml:25 | |
8136 msgid "Giving a persistent name to a revision" | |
8137 msgstr "" | |
8138 | |
8139 #. type: Content of: <book><chapter><sect1><para> | |
8140 #: ../en/ch08-branch.xml:27 | |
8141 msgid "" | |
8142 "Once you decide that you'd like to call a particular revision a " | |
8143 "<quote>release</quote>, it's a good idea to record the identity of that " | |
8144 "revision. This will let you reproduce that release at a later date, for " | |
8145 "whatever purpose you might need at the time (reproducing a bug, porting to a " | |
8146 "new platform, etc). &interaction.tag.init;" | |
8147 msgstr "" | |
8148 | |
8149 # | |
8150 #. type: Content of: <book><chapter><sect1><para> | |
8151 #: ../en/ch08-branch.xml:34 | |
8152 msgid "" | |
8153 "Mercurial lets you give a permanent name to any revision using the <command " | |
8154 "role=\"hg-cmd\">hg tag</command> command. Not surprisingly, these names are " | |
8155 "called <quote>tags</quote>." | |
8156 msgstr "" | |
8157 | |
8158 #. type: Content of: <book><chapter><sect1><para> | |
8159 #: ../en/ch08-branch.xml:40 | |
8160 msgid "" | |
8161 "A tag is nothing more than a <quote>symbolic name</quote> for a revision. " | |
8162 "Tags exist purely for your convenience, so that you have a handy permanent " | |
8163 "way to refer to a revision; Mercurial doesn't interpret the tag names you use " | |
8164 "in any way. Neither does Mercurial place any restrictions on the name of a " | |
8165 "tag, beyond a few that are necessary to ensure that a tag can be parsed " | |
8166 "unambiguously. A tag name cannot contain any of the following characters:" | |
8167 msgstr "" | |
8168 | |
8169 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
8170 #: ../en/ch08-branch.xml:49 | |
8171 msgid "Colon (ASCII 58, <quote><literal>:</literal></quote>)" | |
8172 msgstr "" | |
8173 | |
8174 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
8175 #: ../en/ch08-branch.xml:52 | |
8176 msgid "Carriage return (ASCII 13, <quote><literal>\\r</literal></quote>)" | |
8177 msgstr "" | |
8178 | |
8179 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
8180 #: ../en/ch08-branch.xml:55 | |
8181 msgid "Newline (ASCII 10, <quote><literal>\\n</literal></quote>)" | |
8182 msgstr "" | |
8183 | |
8184 #. type: Content of: <book><chapter><sect1><para> | |
8185 #: ../en/ch08-branch.xml:59 | |
8186 msgid "" | |
8187 "You can use the <command role=\"hg-cmd\">hg tags</command> command to display " | |
8188 "the tags present in your repository. In the output, each tagged revision is " | |
8189 "identified first by its name, then by revision number, and finally by the " | |
8190 "unique hash of the revision." | |
8191 msgstr "" | |
8192 | |
8193 #. type: Content of: <book><chapter><sect1><para> | |
8194 #: ../en/ch08-branch.xml:67 | |
8195 msgid "" | |
8196 "Notice that <literal>tip</literal> is listed in the output of <command role=" | |
8197 "\"hg-cmd\">hg tags</command>. The <literal>tip</literal> tag is a special " | |
8198 "<quote>floating</quote> tag, which always identifies the newest revision in " | |
8199 "the repository." | |
8200 msgstr "" | |
8201 | |
8202 #. type: Content of: <book><chapter><sect1><para> | |
8203 #: ../en/ch08-branch.xml:73 | |
8204 msgid "" | |
8205 "In the output of the <command role=\"hg-cmd\">hg tags</command> command, tags " | |
8206 "are listed in reverse order, by revision number. This usually means that " | |
8207 "recent tags are listed before older tags. It also means that <literal>tip</" | |
8208 "literal> is always going to be the first tag listed in the output of <command " | |
8209 "role=\"hg-cmd\">hg tags</command>." | |
8210 msgstr "" | |
8211 | |
8212 #. type: Content of: <book><chapter><sect1><para> | |
8213 #: ../en/ch08-branch.xml:80 | |
8214 msgid "" | |
8215 "When you run <command role=\"hg-cmd\">hg log</command>, if it displays a " | |
8216 "revision that has tags associated with it, it will print those tags." | |
8217 msgstr "" | |
8218 | |
8219 # | |
8220 #. type: Content of: <book><chapter><sect1><para> | |
8221 #: ../en/ch08-branch.xml:86 | |
8222 msgid "" | |
8223 "Any time you need to provide a revision ID to a Mercurial command, the " | |
8224 "command will accept a tag name in its place. Internally, Mercurial will " | |
8225 "translate your tag name into the corresponding revision ID, then use that." | |
8226 msgstr "" | |
8227 | |
8228 #. type: Content of: <book><chapter><sect1><para> | |
8229 #: ../en/ch08-branch.xml:93 | |
8230 msgid "" | |
8231 "There's no limit on the number of tags you can have in a repository, or on " | |
8232 "the number of tags that a single revision can have. As a practical matter, " | |
8233 "it's not a great idea to have <quote>too many</quote> (a number which will " | |
8234 "vary from project to project), simply because tags are supposed to help you " | |
8235 "to find revisions. If you have lots of tags, the ease of using them to " | |
8236 "identify revisions diminishes rapidly." | |
8237 msgstr "" | |
8238 | |
8239 #. type: Content of: <book><chapter><sect1><para> | |
8240 #: ../en/ch08-branch.xml:101 | |
8241 msgid "" | |
8242 "For example, if your project has milestones as frequent as every few days, " | |
8243 "it's perfectly reasonable to tag each one of those. But if you have a " | |
8244 "continuous build system that makes sure every revision can be built cleanly, " | |
8245 "you'd be introducing a lot of noise if you were to tag every clean build. " | |
8246 "Instead, you could tag failed builds (on the assumption that they're rare!), " | |
8247 "or simply not use tags to track buildability." | |
8248 msgstr "" | |
8249 | |
8250 #. type: Content of: <book><chapter><sect1><para> | |
8251 #: ../en/ch08-branch.xml:109 | |
8252 msgid "" | |
8253 "If you want to remove a tag that you no longer want, use <command role=\"hg-" | |
8254 "cmd\">hg tag --remove</command>." | |
8255 msgstr "" | |
8256 | |
8257 #. type: Content of: <book><chapter><sect1><para> | |
8258 #: ../en/ch08-branch.xml:114 | |
8259 msgid "" | |
8260 "You can also modify a tag at any time, so that it identifies a different " | |
8261 "revision, by simply issuing a new <command role=\"hg-cmd\">hg tag</command> " | |
8262 "command. You'll have to use the <option role=\"hg-opt-tag\">-f</option> " | |
8263 "option to tell Mercurial that you <emphasis>really</emphasis> want to update " | |
8264 "the tag." | |
8265 msgstr "" | |
8266 | |
8267 #. type: Content of: <book><chapter><sect1><para> | |
8268 #: ../en/ch08-branch.xml:123 | |
8269 msgid "" | |
8270 "There will still be a permanent record of the previous identity of the tag, " | |
8271 "but Mercurial will no longer use it. There's thus no penalty to tagging the " | |
8272 "wrong revision; all you have to do is turn around and tag the correct " | |
8273 "revision once you discover your error." | |
8274 msgstr "" | |
8275 | |
8276 # | |
8277 #. type: Content of: <book><chapter><sect1><para> | |
8278 #: ../en/ch08-branch.xml:129 | |
8279 msgid "" | |
8280 "Mercurial stores tags in a normal revision-controlled file in your " | |
8281 "repository. If you've created any tags, you'll find them in a file named " | |
8282 "<filename role=\"special\">.hgtags</filename>. When you run the <command " | |
8283 "role=\"hg-cmd\">hg tag</command> command, Mercurial modifies this file, then " | |
8284 "automatically commits the change to it. This means that every time you run " | |
8285 "<command role=\"hg-cmd\">hg tag</command>, you'll see a corresponding " | |
8286 "changeset in the output of <command role=\"hg-cmd\">hg log</command>." | |
8287 msgstr "" | |
8288 | |
8289 #. type: Content of: <book><chapter><sect1><sect2><title> | |
8290 #: ../en/ch08-branch.xml:142 | |
8291 msgid "Handling tag conflicts during a merge" | |
8292 msgstr "" | |
8293 | |
8294 #. type: Content of: <book><chapter><sect1><sect2><para> | |
8295 #: ../en/ch08-branch.xml:144 | |
8296 msgid "" | |
8297 "You won't often need to care about the <filename role=\"special\">.hgtags</" | |
8298 "filename> file, but it sometimes makes its presence known during a merge. " | |
8299 "The format of the file is simple: it consists of a series of lines. Each " | |
8300 "line starts with a changeset hash, followed by a space, followed by the name " | |
8301 "of a tag." | |
8302 msgstr "" | |
8303 | |
8304 #. type: Content of: <book><chapter><sect1><sect2><para> | |
8305 #: ../en/ch08-branch.xml:151 | |
8306 msgid "" | |
8307 "If you're resolving a conflict in the <filename role=\"special\">.hgtags</" | |
8308 "filename> file during a merge, there's one twist to modifying the <filename " | |
8309 "role=\"special\">.hgtags</filename> file: when Mercurial is parsing the tags " | |
8310 "in a repository, it <emphasis>never</emphasis> reads the working copy of the " | |
8311 "<filename role=\"special\">.hgtags</filename> file. Instead, it reads the " | |
8312 "<emphasis>most recently committed</emphasis> revision of the file." | |
8313 msgstr "" | |
8314 | |
8315 #. type: Content of: <book><chapter><sect1><sect2><para> | |
8316 #: ../en/ch08-branch.xml:161 | |
8317 msgid "" | |
8318 "An unfortunate consequence of this design is that you can't actually verify " | |
8319 "that your merged <filename role=\"special\">.hgtags</filename> file is " | |
8320 "correct until <emphasis>after</emphasis> you've committed a change. So if " | |
8321 "you find yourself resolving a conflict on <filename role=\"special\">.hgtags</" | |
8322 "filename> during a merge, be sure to run <command role=\"hg-cmd\">hg tags</" | |
8323 "command> after you commit. If it finds an error in the <filename role=" | |
8324 "\"special\">.hgtags</filename> file, it will report the location of the " | |
8325 "error, which you can then fix and commit. You should then run <command role=" | |
8326 "\"hg-cmd\">hg tags</command> again, just to be sure that your fix is correct." | |
8327 msgstr "" | |
8328 | |
8329 #. type: Content of: <book><chapter><sect1><sect2><title> | |
8330 #: ../en/ch08-branch.xml:176 | |
8331 msgid "Tags and cloning" | |
8332 msgstr "" | |
8333 | |
8334 #. type: Content of: <book><chapter><sect1><sect2><para> | |
8335 #: ../en/ch08-branch.xml:178 | |
8336 msgid "" | |
8337 "You may have noticed that the <command role=\"hg-cmd\">hg clone</command> " | |
8338 "command has a <option role=\"hg-opt-clone\">-r</option> option that lets you " | |
8339 "clone an exact copy of the repository as of a particular changeset. The new " | |
8340 "clone will not contain any project history that comes after the revision you " | |
8341 "specified. This has an interaction with tags that can surprise the unwary." | |
8342 msgstr "" | |
8343 | |
8344 #. type: Content of: <book><chapter><sect1><sect2><para> | |
8345 #: ../en/ch08-branch.xml:186 | |
8346 msgid "" | |
8347 "Recall that a tag is stored as a revision to the <filename role=\"special\">." | |
8348 "hgtags</filename> file, so that when you create a tag, the changeset in which " | |
8349 "it's recorded necessarily refers to an older changeset. When you run " | |
8350 "<command role=\"hg-cmd\">hg clone -r foo</command> to clone a repository as " | |
8351 "of tag <literal>foo</literal>, the new clone <emphasis>will not contain the " | |
8352 "history that created the tag</emphasis> that you used to clone the " | |
8353 "repository. The result is that you'll get exactly the right subset of the " | |
8354 "project's history in the new repository, but <emphasis>not</emphasis> the tag " | |
8355 "you might have expected." | |
8356 msgstr "" | |
8357 | |
8358 #. type: Content of: <book><chapter><sect1><sect2><title> | |
8359 #: ../en/ch08-branch.xml:201 | |
8360 msgid "When permanent tags are too much" | |
8361 msgstr "" | |
8362 | |
8363 #. type: Content of: <book><chapter><sect1><sect2><para> | |
8364 #: ../en/ch08-branch.xml:203 | |
8365 msgid "" | |
8366 "Since Mercurial's tags are revision controlled and carried around with a " | |
8367 "project's history, everyone you work with will see the tags you create. But " | |
8368 "giving names to revisions has uses beyond simply noting that revision " | |
8369 "<literal>4237e45506ee</literal> is really <literal>v2.0.2</literal>. If " | |
8370 "you're trying to track down a subtle bug, you might want a tag to remind you " | |
8371 "of something like <quote>Anne saw the symptoms with this revision</quote>." | |
8372 msgstr "" | |
8373 | |
8374 #. type: Content of: <book><chapter><sect1><sect2><para> | |
8375 #: ../en/ch08-branch.xml:213 | |
8376 msgid "" | |
8377 "For cases like this, what you might want to use are <emphasis>local</" | |
8378 "emphasis> tags. You can create a local tag with the <option role=\"hg-opt-tag" | |
8379 "\">-l</option> option to the <command role=\"hg-cmd\">hg tag</command> " | |
8380 "command. This will store the tag in a file called <filename role=\"special" | |
8381 "\">.hg/localtags</filename>. Unlike <filename role=\"special\">.hgtags</" | |
8382 "filename>, <filename role=\"special\">.hg/localtags</filename> is not " | |
8383 "revision controlled. Any tags you create using <option role=\"hg-opt-tag\">-" | |
8384 "l</option> remain strictly local to the repository you're currently working " | |
8385 "in." | |
8386 msgstr "" | |
8387 | |
8388 #. type: Content of: <book><chapter><sect1><title> | |
8389 #: ../en/ch08-branch.xml:228 | |
8390 msgid "The flow of changes&emdash;big picture vs. little" | |
8391 msgstr "" | |
8392 | |
8393 #. type: Content of: <book><chapter><sect1><para> | |
8394 #: ../en/ch08-branch.xml:230 | |
8395 msgid "" | |
8396 "To return to the outline I sketched at the beginning of a chapter, let's " | |
8397 "think about a project that has multiple concurrent pieces of work under " | |
8398 "development at once." | |
8399 msgstr "" | |
8400 | |
8401 #. type: Content of: <book><chapter><sect1><para> | |
8402 #: ../en/ch08-branch.xml:234 | |
8403 msgid "" | |
8404 "There might be a push for a new <quote>main</quote> release; a new minor " | |
8405 "bugfix release to the last main release; and an unexpected <quote>hot fix</" | |
8406 "quote> to an old release that is now in maintenance mode." | |
8407 msgstr "" | |
8408 | |
8409 #. type: Content of: <book><chapter><sect1><para> | |
8410 #: ../en/ch08-branch.xml:239 | |
8411 msgid "" | |
8412 "The usual way people refer to these different concurrent directions of " | |
8413 "development is as <quote>branches</quote>. However, we've already seen " | |
8414 "numerous times that Mercurial treats <emphasis>all of history</emphasis> as a " | |
8415 "series of branches and merges. Really, what we have here is two ideas that " | |
8416 "are peripherally related, but which happen to share a name." | |
8417 msgstr "" | |
8418 | |
8419 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
8420 #: ../en/ch08-branch.xml:246 | |
8421 msgid "" | |
8422 "<quote>Big picture</quote> branches represent the sweep of a project's " | |
8423 "evolution; people give them names, and talk about them in conversation." | |
8424 msgstr "" | |
8425 | |
8426 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
8427 #: ../en/ch08-branch.xml:250 | |
8428 msgid "" | |
8429 "<quote>Little picture</quote> branches are artefacts of the day-to-day " | |
8430 "activity of developing and merging changes. They expose the narrative of how " | |
8431 "the code was developed." | |
8432 msgstr "" | |
8433 | |
8434 #. type: Content of: <book><chapter><sect1><title> | |
8435 #: ../en/ch08-branch.xml:258 | |
8436 msgid "Managing big-picture branches in repositories" | |
8437 msgstr "" | |
8438 | |
8439 #. type: Content of: <book><chapter><sect1><para> | |
8440 #: ../en/ch08-branch.xml:260 | |
8441 msgid "" | |
8442 "The easiest way to isolate a <quote>big picture</quote> branch in Mercurial " | |
8443 "is in a dedicated repository. If you have an existing shared " | |
8444 "repository&emdash;let's call it <literal>myproject</literal>&emdash;that " | |
8445 "reaches a <quote>1.0</quote> milestone, you can start to prepare for future " | |
8446 "maintenance releases on top of version 1.0 by tagging the revision from which " | |
8447 "you prepared the 1.0 release." | |
8448 msgstr "" | |
8449 | |
8450 #. type: Content of: <book><chapter><sect1><para> | |
8451 #: ../en/ch08-branch.xml:270 | |
8452 msgid "" | |
8453 "You can then clone a new shared <literal>myproject-1.0.1</literal> repository " | |
8454 "as of that tag." | |
8455 msgstr "" | |
8456 | |
8457 #. type: Content of: <book><chapter><sect1><para> | |
8458 #: ../en/ch08-branch.xml:276 | |
8459 msgid "" | |
8460 "Afterwards, if someone needs to work on a bug fix that ought to go into an " | |
8461 "upcoming 1.0.1 minor release, they clone the <literal>myproject-1.0.1</" | |
8462 "literal> repository, make their changes, and push them back." | |
8463 msgstr "" | |
8464 | |
8465 #. type: Content of: <book><chapter><sect1><para> | |
8466 #: ../en/ch08-branch.xml:283 | |
8467 msgid "" | |
8468 "Meanwhile, development for the next major release can continue, isolated and " | |
8469 "unabated, in the <literal>myproject</literal> repository." | |
8470 msgstr "" | |
8471 | |
8472 #. type: Content of: <book><chapter><sect1><title> | |
8473 #: ../en/ch08-branch.xml:291 | |
8474 msgid "Don't repeat yourself: merging across branches" | |
8475 msgstr "" | |
8476 | |
8477 #. type: Content of: <book><chapter><sect1><para> | |
8478 #: ../en/ch08-branch.xml:293 | |
8479 msgid "" | |
8480 "In many cases, if you have a bug to fix on a maintenance branch, the chances " | |
8481 "are good that the bug exists on your project's main branch (and possibly " | |
8482 "other maintenance branches, too). It's a rare developer who wants to fix the " | |
8483 "same bug multiple times, so let's look at a few ways that Mercurial can help " | |
8484 "you to manage these bugfixes without duplicating your work." | |
8485 msgstr "" | |
8486 | |
8487 #. type: Content of: <book><chapter><sect1><para> | |
8488 #: ../en/ch08-branch.xml:301 | |
8489 msgid "" | |
8490 "In the simplest instance, all you need to do is pull changes from your " | |
8491 "maintenance branch into your local clone of the target branch." | |
8492 msgstr "" | |
8493 | |
8494 #. type: Content of: <book><chapter><sect1><para> | |
8495 #: ../en/ch08-branch.xml:307 | |
8496 msgid "" | |
8497 "You'll then need to merge the heads of the two branches, and push back to the " | |
8498 "main branch." | |
8499 msgstr "" | |
8500 | |
8501 #. type: Content of: <book><chapter><sect1><title> | |
8502 #: ../en/ch08-branch.xml:314 | |
8503 msgid "Naming branches within one repository" | |
8504 msgstr "" | |
8505 | |
8506 #. type: Content of: <book><chapter><sect1><para> | |
8507 #: ../en/ch08-branch.xml:316 | |
8508 msgid "" | |
8509 "In most instances, isolating branches in repositories is the right approach. " | |
8510 "Its simplicity makes it easy to understand; and so it's hard to make " | |
8511 "mistakes. There's a one-to-one relationship between branches you're working " | |
8512 "in and directories on your system. This lets you use normal (non-Mercurial-" | |
8513 "aware) tools to work on files within a branch/repository." | |
8514 msgstr "" | |
8515 | |
8516 #. type: Content of: <book><chapter><sect1><para> | |
8517 #: ../en/ch08-branch.xml:323 | |
8518 msgid "" | |
8519 "If you're more in the <quote>power user</quote> category (<emphasis>and</" | |
8520 "emphasis> your collaborators are too), there is an alternative way of " | |
8521 "handling branches that you can consider. I've already mentioned the human-" | |
8522 "level distinction between <quote>small picture</quote> and <quote>big " | |
8523 "picture</quote> branches. While Mercurial works with multiple <quote>small " | |
8524 "picture</quote> branches in a repository all the time (for example after you " | |
8525 "pull changes in, but before you merge them), it can <emphasis>also</emphasis> " | |
8526 "work with multiple <quote>big picture</quote> branches." | |
8527 msgstr "" | |
8528 | |
8529 #. type: Content of: <book><chapter><sect1><para> | |
8530 #: ../en/ch08-branch.xml:334 | |
8531 msgid "" | |
8532 "The key to working this way is that Mercurial lets you assign a persistent " | |
8533 "<emphasis>name</emphasis> to a branch. There always exists a branch named " | |
8534 "<literal>default</literal>. Even before you start naming branches yourself, " | |
8535 "you can find traces of the <literal>default</literal> branch if you look for " | |
8536 "them." | |
8537 msgstr "" | |
8538 | |
8539 #. type: Content of: <book><chapter><sect1><para> | |
8540 #: ../en/ch08-branch.xml:341 | |
8541 msgid "" | |
8542 "As an example, when you run the <command role=\"hg-cmd\">hg commit</command> " | |
8543 "command, and it pops up your editor so that you can enter a commit message, " | |
8544 "look for a line that contains the text <quote><literal>HG: branch default</" | |
8545 "literal></quote> at the bottom. This is telling you that your commit will " | |
8546 "occur on the branch named <literal>default</literal>." | |
8547 msgstr "" | |
8548 | |
8549 #. type: Content of: <book><chapter><sect1><para> | |
8550 #: ../en/ch08-branch.xml:348 | |
8551 msgid "" | |
8552 "To start working with named branches, use the <command role=\"hg-cmd\">hg " | |
8553 "branches</command> command. This command lists the named branches already " | |
8554 "present in your repository, telling you which changeset is the tip of each." | |
8555 msgstr "" | |
8556 | |
8557 #. type: Content of: <book><chapter><sect1><para> | |
8558 #: ../en/ch08-branch.xml:355 | |
8559 msgid "" | |
8560 "Since you haven't created any named branches yet, the only one that exists is " | |
8561 "<literal>default</literal>." | |
8562 msgstr "" | |
8563 | |
8564 #. type: Content of: <book><chapter><sect1><para> | |
8565 #: ../en/ch08-branch.xml:358 | |
8566 msgid "" | |
8567 "To find out what the <quote>current</quote> branch is, run the <command role=" | |
8568 "\"hg-cmd\">hg branch</command> command, giving it no arguments. This tells " | |
8569 "you what branch the parent of the current changeset is on." | |
8570 msgstr "" | |
8571 | |
8572 # | |
8573 #. type: Content of: <book><chapter><sect1><para> | |
8574 #: ../en/ch08-branch.xml:365 | |
8575 msgid "" | |
8576 "To create a new branch, run the <command role=\"hg-cmd\">hg branch</command> " | |
8577 "command again. This time, give it one argument: the name of the branch you " | |
8578 "want to create." | |
8579 msgstr "" | |
8580 | |
8581 #. type: Content of: <book><chapter><sect1><para> | |
8582 #: ../en/ch08-branch.xml:371 | |
8583 msgid "" | |
8584 "After you've created a branch, you might wonder what effect the <command role=" | |
8585 "\"hg-cmd\">hg branch</command> command has had. What do the <command role=" | |
8586 "\"hg-cmd\">hg status</command> and <command role=\"hg-cmd\">hg tip</command> " | |
8587 "commands report?" | |
8588 msgstr "" | |
8589 | |
8590 #. type: Content of: <book><chapter><sect1><para> | |
8591 #: ../en/ch08-branch.xml:378 | |
8592 msgid "" | |
8593 "Nothing has changed in the working directory, and there's been no new history " | |
8594 "created. As this suggests, running the <command role=\"hg-cmd\">hg branch</" | |
8595 "command> command has no permanent effect; it only tells Mercurial what branch " | |
8596 "name to use the <emphasis>next</emphasis> time you commit a changeset." | |
8597 msgstr "" | |
8598 | |
8599 #. type: Content of: <book><chapter><sect1><para> | |
8600 #: ../en/ch08-branch.xml:385 | |
8601 msgid "" | |
8602 "When you commit a change, Mercurial records the name of the branch on which " | |
8603 "you committed. Once you've switched from the <literal>default</literal> " | |
8604 "branch to another and committed, you'll see the name of the new branch show " | |
8605 "up in the output of <command role=\"hg-cmd\">hg log</command>, <command role=" | |
8606 "\"hg-cmd\">hg tip</command>, and other commands that display the same kind of " | |
8607 "output." | |
8608 msgstr "" | |
8609 | |
8610 #. type: Content of: <book><chapter><sect1><para> | |
8611 #: ../en/ch08-branch.xml:395 | |
8612 msgid "" | |
8613 "The <command role=\"hg-cmd\">hg log</command>-like commands will print the " | |
8614 "branch name of every changeset that's not on the <literal>default</literal> " | |
8615 "branch. As a result, if you never use named branches, you'll never see this " | |
8616 "information." | |
8617 msgstr "" | |
8618 | |
8619 #. type: Content of: <book><chapter><sect1><para> | |
8620 #: ../en/ch08-branch.xml:400 | |
8621 msgid "" | |
8622 "Once you've named a branch and committed a change with that name, every " | |
8623 "subsequent commit that descends from that change will inherit the same branch " | |
8624 "name. You can change the name of a branch at any time, using the <command " | |
8625 "role=\"hg-cmd\">hg branch</command> command." | |
8626 msgstr "" | |
8627 | |
8628 #. type: Content of: <book><chapter><sect1><para> | |
8629 #: ../en/ch08-branch.xml:408 | |
8630 msgid "" | |
8631 "In practice, this is something you won't do very often, as branch names tend " | |
8632 "to have fairly long lifetimes. (This isn't a rule, just an observation.)" | |
8633 msgstr "" | |
8634 | |
8635 #. type: Content of: <book><chapter><sect1><title> | |
8636 #: ../en/ch08-branch.xml:414 | |
8637 msgid "Dealing with multiple named branches in a repository" | |
8638 msgstr "" | |
8639 | |
8640 #. type: Content of: <book><chapter><sect1><para> | |
8641 #: ../en/ch08-branch.xml:417 | |
8642 msgid "" | |
8643 "If you have more than one named branch in a repository, Mercurial will " | |
8644 "remember the branch that your working directory on when you start a command " | |
8645 "like <command role=\"hg-cmd\">hg update</command> or <command role=\"hg-cmd" | |
8646 "\">hg pull -u</command>. It will update the working directory to the tip of " | |
8647 "this branch, no matter what the <quote>repo-wide</quote> tip is. To update " | |
8648 "to a revision that's on a different named branch, you may need to use the " | |
8649 "<option role=\"hg-opt-update\">-C</option> option to <command role=\"hg-cmd" | |
8650 "\">hg update</command>." | |
8651 msgstr "" | |
8652 | |
8653 #. type: Content of: <book><chapter><sect1><para> | |
8654 #: ../en/ch08-branch.xml:427 | |
8655 msgid "" | |
8656 "This behaviour is a little subtle, so let's see it in action. First, let's " | |
8657 "remind ourselves what branch we're currently on, and what branches are in our " | |
8658 "repository." | |
8659 msgstr "" | |
8660 | |
8661 #. type: Content of: <book><chapter><sect1><para> | |
8662 #: ../en/ch08-branch.xml:433 | |
8663 msgid "" | |
8664 "We're on the <literal>bar</literal> branch, but there also exists an older " | |
8665 "<command role=\"hg-cmd\">hg foo</command> branch." | |
8666 msgstr "" | |
8667 | |
8668 #. type: Content of: <book><chapter><sect1><para> | |
8669 #: ../en/ch08-branch.xml:437 | |
8670 msgid "" | |
8671 "We can <command role=\"hg-cmd\">hg update</command> back and forth between " | |
8672 "the tips of the <literal>foo</literal> and <literal>bar</literal> branches " | |
8673 "without needing to use the <option role=\"hg-opt-update\">-C</option> option, " | |
8674 "because this only involves going backwards and forwards linearly through our " | |
8675 "change history." | |
8676 msgstr "" | |
8677 | |
8678 # | |
8679 #. type: Content of: <book><chapter><sect1><para> | |
8680 #: ../en/ch08-branch.xml:446 | |
8681 msgid "" | |
8682 "If we go back to the <literal>foo</literal> branch and then run <command role=" | |
8683 "\"hg-cmd\">hg update</command>, it will keep us on <literal>foo</literal>, " | |
8684 "not move us to the tip of <literal>bar</literal>." | |
8685 msgstr "" | |
8686 | |
8687 # | |
8688 #. type: Content of: <book><chapter><sect1><para> | |
8689 #: ../en/ch08-branch.xml:453 | |
8690 msgid "" | |
8691 "Committing a new change on the <literal>foo</literal> branch introduces a new " | |
8692 "head." | |
8693 msgstr "" | |
8694 | |
8695 #. type: Content of: <book><chapter><sect1><title> | |
8696 #: ../en/ch08-branch.xml:460 | |
8697 msgid "Branch names and merging" | |
8698 msgstr "" | |
8699 | |
8700 #. type: Content of: <book><chapter><sect1><para> | |
8701 #: ../en/ch08-branch.xml:462 | |
8702 msgid "" | |
8703 "As you've probably noticed, merges in Mercurial are not symmetrical. Let's " | |
8704 "say our repository has two heads, 17 and 23. If I <command role=\"hg-cmd" | |
8705 "\">hg update</command> to 17 and then <command role=\"hg-cmd\">hg merge</" | |
8706 "command> with 23, Mercurial records 17 as the first parent of the merge, and " | |
8707 "23 as the second. Whereas if I <command role=\"hg-cmd\">hg update</command> " | |
8708 "to 23 and then <command role=\"hg-cmd\">hg merge</command> with 17, it " | |
8709 "records 23 as the first parent, and 17 as the second." | |
8710 msgstr "" | |
8711 | |
8712 #. type: Content of: <book><chapter><sect1><para> | |
8713 #: ../en/ch08-branch.xml:472 | |
8714 msgid "" | |
8715 "This affects Mercurial's choice of branch name when you merge. After a " | |
8716 "merge, Mercurial will retain the branch name of the first parent when you " | |
8717 "commit the result of the merge. If your first parent's branch name is " | |
8718 "<literal>foo</literal>, and you merge with <literal>bar</literal>, the branch " | |
8719 "name will still be <literal>foo</literal> after you merge." | |
8720 msgstr "" | |
8721 | |
8722 #. type: Content of: <book><chapter><sect1><para> | |
8723 #: ../en/ch08-branch.xml:479 | |
8724 msgid "" | |
8725 "It's not unusual for a repository to contain multiple heads, each with the " | |
8726 "same branch name. Let's say I'm working on the <literal>foo</literal> " | |
8727 "branch, and so are you. We commit different changes; I pull your changes; I " | |
8728 "now have two heads, each claiming to be on the <literal>foo</literal> " | |
8729 "branch. The result of a merge will be a single head on the <literal>foo</" | |
8730 "literal> branch, as you might hope." | |
8731 msgstr "" | |
8732 | |
8733 # | |
8734 #. type: Content of: <book><chapter><sect1><para> | |
8735 #: ../en/ch08-branch.xml:487 | |
8736 msgid "" | |
8737 "But if I'm working on the <literal>bar</literal> branch, and I merge work " | |
8738 "from the <literal>foo</literal> branch, the result will remain on the " | |
8739 "<literal>bar</literal> branch." | |
8740 msgstr "" | |
8741 | |
8742 #. type: Content of: <book><chapter><sect1><para> | |
8743 #: ../en/ch08-branch.xml:493 | |
8744 msgid "" | |
8745 "To give a more concrete example, if I'm working on the <literal>bleeding-" | |
8746 "edge</literal> branch, and I want to bring in the latest fixes from the " | |
8747 "<literal>stable</literal> branch, Mercurial will choose the <quote>right</" | |
8748 "quote> (<literal>bleeding-edge</literal>) branch name when I pull and merge " | |
8749 "from <literal>stable</literal>." | |
8750 msgstr "" | |
8751 | |
8752 #. type: Content of: <book><chapter><sect1><title> | |
8753 #: ../en/ch08-branch.xml:502 | |
8754 msgid "Branch naming is generally useful" | |
8755 msgstr "" | |
8756 | |
8757 #. type: Content of: <book><chapter><sect1><para> | |
8758 #: ../en/ch08-branch.xml:504 | |
8759 msgid "" | |
8760 "You shouldn't think of named branches as applicable only to situations where " | |
8761 "you have multiple long-lived branches cohabiting in a single repository. " | |
8762 "They're very useful even in the one-branch-per-repository case." | |
8763 msgstr "" | |
8764 | |
8765 #. type: Content of: <book><chapter><sect1><para> | |
8766 #: ../en/ch08-branch.xml:509 | |
8767 msgid "" | |
8768 "In the simplest case, giving a name to each branch gives you a permanent " | |
8769 "record of which branch a changeset originated on. This gives you more " | |
8770 "context when you're trying to follow the history of a long-lived branchy " | |
8771 "project." | |
8772 msgstr "" | |
8773 | |
8774 #. type: Content of: <book><chapter><sect1><para> | |
8775 #: ../en/ch08-branch.xml:514 | |
8776 msgid "" | |
8777 "If you're working with shared repositories, you can set up a <literal role=" | |
8778 "\"hook\">pretxnchangegroup</literal> hook on each that will block incoming " | |
8779 "changes that have the <quote>wrong</quote> branch name. This provides a " | |
8780 "simple, but effective, defence against people accidentally pushing changes " | |
8781 "from a <quote>bleeding edge</quote> branch to a <quote>stable</quote> " | |
8782 "branch. Such a hook might look like this inside the shared repo's <filename " | |
8783 "role=\"special\"> /.hgrc</filename>." | |
8784 msgstr "" | |
8785 | |
8786 #. type: Content of: <book><chapter><title> | |
8787 #: ../en/ch09-undo.xml:5 | |
8788 msgid "Finding and fixing mistakes" | |
8789 msgstr "查找和修改错误" | |
8790 | |
8791 #. type: Content of: <book><chapter><para> | |
8792 #: ../en/ch09-undo.xml:7 | |
8793 msgid "" | |
8794 "To err might be human, but to really handle the consequences well takes a top-" | |
8795 "notch revision control system. In this chapter, we'll discuss some of the " | |
8796 "techniques you can use when you find that a problem has crept into your " | |
8797 "project. Mercurial has some highly capable features that will help you to " | |
8798 "isolate the sources of problems, and to handle them appropriately." | |
8799 msgstr "" | |
8800 | |
8801 #. type: Content of: <book><chapter><sect1><title> | |
8802 #: ../en/ch09-undo.xml:15 | |
8803 msgid "Erasing local history" | |
8804 msgstr "" | |
8805 | |
8806 #. type: Content of: <book><chapter><sect1><sect2><title> | |
8807 #: ../en/ch09-undo.xml:18 | |
8808 msgid "The accidental commit" | |
8809 msgstr "" | |
8810 | |
8811 #. type: Content of: <book><chapter><sect1><sect2><para> | |
8812 #: ../en/ch09-undo.xml:20 | |
8813 msgid "" | |
8814 "I have the occasional but persistent problem of typing rather more quickly " | |
8815 "than I can think, which sometimes results in me committing a changeset that " | |
8816 "is either incomplete or plain wrong. In my case, the usual kind of " | |
8817 "incomplete changeset is one in which I've created a new source file, but " | |
8818 "forgotten to <command role=\"hg-cmd\">hg add</command> it. A <quote>plain " | |
8819 "wrong</quote> changeset is not as common, but no less annoying." | |
8820 msgstr "" | |
8821 | |
8822 #. type: Content of: <book><chapter><sect1><sect2><title> | |
8823 #: ../en/ch09-undo.xml:31 | |
8824 msgid "Rolling back a transaction" | |
8825 msgstr "" | |
8826 | |
8827 #. type: Content of: <book><chapter><sect1><sect2><para> | |
8828 #: ../en/ch09-undo.xml:33 | |
8829 msgid "" | |
8830 "In section <xref linkend=\"sec.concepts.txn\"/>, I mentioned that Mercurial " | |
8831 "treats each modification of a repository as a <emphasis>transaction</" | |
8832 "emphasis>. Every time you commit a changeset or pull changes from another " | |
8833 "repository, Mercurial remembers what you did. You can undo, or " | |
8834 "<emphasis>roll back</emphasis>, exactly one of these actions using the " | |
8835 "<command role=\"hg-cmd\">hg rollback</command> command. (See section <xref " | |
8836 "linkend=\"sec.undo.rollback-after-push\"/> for an important caveat about the " | |
8837 "use of this command.)" | |
8838 msgstr "" | |
8839 | |
8840 #. type: Content of: <book><chapter><sect1><sect2><para> | |
8841 #: ../en/ch09-undo.xml:43 | |
8842 msgid "" | |
8843 "Here's a mistake that I often find myself making: committing a change in " | |
8844 "which I've created a new file, but forgotten to <command role=\"hg-cmd\">hg " | |
8845 "add</command> it." | |
8846 msgstr "" | |
8847 | |
8848 #. type: Content of: <book><chapter><sect1><sect2><para> | |
8849 #: ../en/ch09-undo.xml:50 | |
8850 msgid "" | |
8851 "Looking at the output of <command role=\"hg-cmd\">hg status</command> after " | |
8852 "the commit immediately confirms the error." | |
8853 msgstr "" | |
8854 | |
8855 #. type: Content of: <book><chapter><sect1><sect2><para> | |
8856 #: ../en/ch09-undo.xml:56 | |
8857 msgid "" | |
8858 "The commit captured the changes to the file <filename>a</filename>, but not " | |
8859 "the new file <filename>b</filename>. If I were to push this changeset to a " | |
8860 "repository that I shared with a colleague, the chances are high that " | |
8861 "something in <filename>a</filename> would refer to <filename>b</filename>, " | |
8862 "which would not be present in their repository when they pulled my changes. " | |
8863 "I would thus become the object of some indignation." | |
8864 msgstr "" | |
8865 | |
8866 #. type: Content of: <book><chapter><sect1><sect2><para> | |
8867 #: ../en/ch09-undo.xml:65 | |
8868 msgid "" | |
8869 "However, luck is with me&emdash;I've caught my error before I pushed the " | |
8870 "changeset. I use the <command role=\"hg-cmd\">hg rollback</command> command, " | |
8871 "and Mercurial makes that last changeset vanish." | |
8872 msgstr "" | |
8873 | |
8874 #. type: Content of: <book><chapter><sect1><sect2><para> | |
8875 #: ../en/ch09-undo.xml:72 | |
8876 msgid "" | |
8877 "Notice that the changeset is no longer present in the repository's history, " | |
8878 "and the working directory once again thinks that the file <filename>a</" | |
8879 "filename> is modified. The commit and rollback have left the working " | |
8880 "directory exactly as it was prior to the commit; the changeset has been " | |
8881 "completely erased. I can now safely <command role=\"hg-cmd\">hg add</" | |
8882 "command> the file <filename>b</filename>, and rerun my commit." | |
8883 msgstr "" | |
8884 | |
8885 #. type: Content of: <book><chapter><sect1><sect2><title> | |
8886 #: ../en/ch09-undo.xml:85 | |
8887 msgid "The erroneous pull" | |
8888 msgstr "" | |
8889 | |
8890 #. type: Content of: <book><chapter><sect1><sect2><para> | |
8891 #: ../en/ch09-undo.xml:87 | |
8892 msgid "" | |
8893 "It's common practice with Mercurial to maintain separate development branches " | |
8894 "of a project in different repositories. Your development team might have one " | |
8895 "shared repository for your project's <quote>0.9</quote> release, and another, " | |
8896 "containing different changes, for the <quote>1.0</quote> release." | |
8897 msgstr "" | |
8898 | |
8899 #. type: Content of: <book><chapter><sect1><sect2><para> | |
8900 #: ../en/ch09-undo.xml:94 | |
8901 msgid "" | |
8902 "Given this, you can imagine that the consequences could be messy if you had a " | |
8903 "local <quote>0.9</quote> repository, and accidentally pulled changes from the " | |
8904 "shared <quote>1.0</quote> repository into it. At worst, you could be paying " | |
8905 "insufficient attention, and push those changes into the shared <quote>0.9</" | |
8906 "quote> tree, confusing your entire team (but don't worry, we'll return to " | |
8907 "this horror scenario later). However, it's more likely that you'll notice " | |
8908 "immediately, because Mercurial will display the URL it's pulling from, or you " | |
8909 "will see it pull a suspiciously large number of changes into the repository." | |
8910 msgstr "" | |
8911 | |
8912 #. type: Content of: <book><chapter><sect1><sect2><para> | |
8913 #: ../en/ch09-undo.xml:106 | |
8914 msgid "" | |
8915 "The <command role=\"hg-cmd\">hg rollback</command> command will work nicely " | |
8916 "to expunge all of the changesets that you just pulled. Mercurial groups all " | |
8917 "changes from one <command role=\"hg-cmd\">hg pull</command> into a single " | |
8918 "transaction, so one <command role=\"hg-cmd\">hg rollback</command> is all you " | |
8919 "need to undo this mistake." | |
8920 msgstr "" | |
8921 | |
8922 #. type: Content of: <book><chapter><sect1><sect2><title> | |
8923 #: ../en/ch09-undo.xml:115 | |
8924 msgid "Rolling back is useless once you've pushed" | |
8925 msgstr "" | |
8926 | |
8927 #. type: Content of: <book><chapter><sect1><sect2><para> | |
8928 #: ../en/ch09-undo.xml:117 | |
8929 msgid "" | |
8930 "The value of the <command role=\"hg-cmd\">hg rollback</command> command drops " | |
8931 "to zero once you've pushed your changes to another repository. Rolling back " | |
8932 "a change makes it disappear entirely, but <emphasis>only</emphasis> in the " | |
8933 "repository in which you perform the <command role=\"hg-cmd\">hg rollback</" | |
8934 "command>. Because a rollback eliminates history, there's no way for the " | |
8935 "disappearance of a change to propagate between repositories." | |
8936 msgstr "" | |
8937 | |
8938 #. type: Content of: <book><chapter><sect1><sect2><para> | |
8939 #: ../en/ch09-undo.xml:126 | |
8940 msgid "" | |
8941 "If you've pushed a change to another repository&emdash;particularly if it's a " | |
8942 "shared repository&emdash;it has essentially <quote>escaped into the wild,</" | |
8943 "quote> and you'll have to recover from your mistake in a different way. What " | |
8944 "will happen if you push a changeset somewhere, then roll it back, then pull " | |
8945 "from the repository you pushed to, is that the changeset will reappear in " | |
8946 "your repository." | |
8947 msgstr "" | |
8948 | |
8949 #. type: Content of: <book><chapter><sect1><sect2><para> | |
8950 #: ../en/ch09-undo.xml:135 | |
8951 msgid "" | |
8952 "(If you absolutely know for sure that the change you want to roll back is the " | |
8953 "most recent change in the repository that you pushed to, <emphasis>and</" | |
8954 "emphasis> you know that nobody else could have pulled it from that " | |
8955 "repository, you can roll back the changeset there, too, but you really should " | |
8956 "really not rely on this working reliably. If you do this, sooner or later a " | |
8957 "change really will make it into a repository that you don't directly control " | |
8958 "(or have forgotten about), and come back to bite you.)" | |
8959 msgstr "" | |
8960 | |
8961 #. type: Content of: <book><chapter><sect1><sect2><title> | |
8962 #: ../en/ch09-undo.xml:147 | |
8963 msgid "You can only roll back once" | |
8964 msgstr "" | |
8965 | |
8966 #. type: Content of: <book><chapter><sect1><sect2><para> | |
8967 #: ../en/ch09-undo.xml:149 | |
8968 msgid "" | |
8969 "Mercurial stores exactly one transaction in its transaction log; that " | |
8970 "transaction is the most recent one that occurred in the repository. This " | |
8971 "means that you can only roll back one transaction. If you expect to be able " | |
8972 "to roll back one transaction, then its predecessor, this is not the behaviour " | |
8973 "you will get." | |
8974 msgstr "" | |
8975 | |
8976 #. type: Content of: <book><chapter><sect1><sect2><para> | |
8977 #: ../en/ch09-undo.xml:158 | |
8978 msgid "" | |
8979 "Once you've rolled back one transaction in a repository, you can't roll back " | |
8980 "again in that repository until you perform another commit or pull." | |
8981 msgstr "" | |
8982 | |
8983 #. type: Content of: <book><chapter><sect1><title> | |
8984 #: ../en/ch09-undo.xml:165 | |
8985 msgid "Reverting the mistaken change" | |
8986 msgstr "" | |
8987 | |
8988 #. type: Content of: <book><chapter><sect1><para> | |
8989 #: ../en/ch09-undo.xml:167 | |
8990 msgid "" | |
8991 "If you make a modification to a file, and decide that you really didn't want " | |
8992 "to change the file at all, and you haven't yet committed your changes, the " | |
8993 "<command role=\"hg-cmd\">hg revert</command> command is the one you'll need. " | |
8994 "It looks at the changeset that's the parent of the working directory, and " | |
8995 "restores the contents of the file to their state as of that changeset. " | |
8996 "(That's a long-winded way of saying that, in the normal case, it undoes your " | |
8997 "modifications.)" | |
8998 msgstr "" | |
8999 | |
9000 #. type: Content of: <book><chapter><sect1><para> | |
9001 #: ../en/ch09-undo.xml:176 | |
9002 msgid "" | |
9003 "Let's illustrate how the <command role=\"hg-cmd\">hg revert</command> command " | |
9004 "works with yet another small example. We'll begin by modifying a file that " | |
9005 "Mercurial is already tracking." | |
9006 msgstr "" | |
9007 | |
9008 #. type: Content of: <book><chapter><sect1><para> | |
9009 #: ../en/ch09-undo.xml:183 | |
9010 msgid "" | |
9011 "If we don't want that change, we can simply <command role=\"hg-cmd\">hg " | |
9012 "revert</command> the file." | |
9013 msgstr "" | |
9014 | |
9015 #. type: Content of: <book><chapter><sect1><para> | |
9016 #: ../en/ch09-undo.xml:189 | |
9017 msgid "" | |
9018 "The <command role=\"hg-cmd\">hg revert</command> command provides us with an " | |
9019 "extra degree of safety by saving our modified file with a <filename>.orig</" | |
9020 "filename> extension." | |
9021 msgstr "" | |
9022 | |
9023 #. type: Content of: <book><chapter><sect1><para> | |
9024 #: ../en/ch09-undo.xml:196 | |
9025 msgid "" | |
9026 "Here is a summary of the cases that the <command role=\"hg-cmd\">hg revert</" | |
9027 "command> command can deal with. We will describe each of these in more " | |
9028 "detail in the section that follows." | |
9029 msgstr "" | |
9030 | |
9031 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
9032 #: ../en/ch09-undo.xml:201 | |
9033 msgid "If you modify a file, it will restore the file to its unmodified state." | |
9034 msgstr "" | |
9035 | |
9036 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
9037 #: ../en/ch09-undo.xml:204 | |
9038 msgid "" | |
9039 "If you <command role=\"hg-cmd\">hg add</command> a file, it will undo the " | |
9040 "<quote>added</quote> state of the file, but leave the file itself untouched." | |
9041 msgstr "" | |
9042 | |
9043 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
9044 #: ../en/ch09-undo.xml:208 | |
9045 msgid "" | |
9046 "If you delete a file without telling Mercurial, it will restore the file to " | |
9047 "its unmodified contents." | |
9048 msgstr "" | |
9049 | |
9050 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
9051 #: ../en/ch09-undo.xml:211 | |
9052 msgid "" | |
9053 "If you use the <command role=\"hg-cmd\">hg remove</command> command to remove " | |
9054 "a file, it will undo the <quote>removed</quote> state of the file, and " | |
9055 "restore the file to its unmodified contents." | |
9056 msgstr "" | |
9057 | |
9058 #. type: Content of: <book><chapter><sect1><sect2><title> | |
9059 #: ../en/ch09-undo.xml:218 | |
9060 msgid "File management errors" | |
9061 msgstr "" | |
9062 | |
9063 #. type: Content of: <book><chapter><sect1><sect2><para> | |
9064 #: ../en/ch09-undo.xml:220 | |
9065 msgid "" | |
9066 "The <command role=\"hg-cmd\">hg revert</command> command is useful for more " | |
9067 "than just modified files. It lets you reverse the results of all of " | |
9068 "Mercurial's file management commands&emdash;<command role=\"hg-cmd\">hg add</" | |
9069 "command>, <command role=\"hg-cmd\">hg remove</command>, and so on." | |
9070 msgstr "" | |
9071 | |
9072 # | |
9073 #. type: Content of: <book><chapter><sect1><sect2><para> | |
9074 #: ../en/ch09-undo.xml:226 | |
9075 msgid "" | |
9076 "If you <command role=\"hg-cmd\">hg add</command> a file, then decide that in " | |
9077 "fact you don't want Mercurial to track it, use <command role=\"hg-cmd\">hg " | |
9078 "revert</command> to undo the add. Don't worry; Mercurial will not modify the " | |
9079 "file in any way. It will just <quote>unmark</quote> the file." | |
9080 msgstr "" | |
9081 | |
9082 #. type: Content of: <book><chapter><sect1><sect2><para> | |
9083 #: ../en/ch09-undo.xml:234 | |
9084 msgid "" | |
9085 "Similarly, if you ask Mercurial to <command role=\"hg-cmd\">hg remove</" | |
9086 "command> a file, you can use <command role=\"hg-cmd\">hg revert</command> to " | |
9087 "restore it to the contents it had as of the parent of the working directory. " | |
9088 "&interaction.daily.revert.remove; This works just as well for a file that you " | |
9089 "deleted by hand, without telling Mercurial (recall that in Mercurial " | |
9090 "terminology, this kind of file is called <quote>missing</quote>)." | |
9091 msgstr "" | |
9092 | |
9093 # | |
9094 #. type: Content of: <book><chapter><sect1><sect2><para> | |
9095 #: ../en/ch09-undo.xml:245 | |
9096 msgid "" | |
9097 "If you revert a <command role=\"hg-cmd\">hg copy</command>, the copied-to " | |
9098 "file remains in your working directory afterwards, untracked. Since a copy " | |
9099 "doesn't affect the copied-from file in any way, Mercurial doesn't do anything " | |
9100 "with the copied-from file." | |
9101 msgstr "" | |
9102 | |
9103 #. type: Content of: <book><chapter><sect1><sect2><sect3><title> | |
9104 #: ../en/ch09-undo.xml:254 | |
9105 msgid "A slightly special case: reverting a rename" | |
9106 msgstr "" | |
9107 | |
9108 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
9109 #: ../en/ch09-undo.xml:256 | |
9110 msgid "" | |
9111 "If you <command role=\"hg-cmd\">hg rename</command> a file, there is one " | |
9112 "small detail that you should remember. When you <command role=\"hg-cmd\">hg " | |
9113 "revert</command> a rename, it's not enough to provide the name of the renamed-" | |
9114 "to file, as you can see here." | |
9115 msgstr "" | |
9116 | |
9117 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
9118 #: ../en/ch09-undo.xml:264 | |
9119 msgid "" | |
9120 "As you can see from the output of <command role=\"hg-cmd\">hg status</" | |
9121 "command>, the renamed-to file is no longer identified as added, but the " | |
9122 "renamed-<emphasis>from</emphasis> file is still removed! This is counter-" | |
9123 "intuitive (at least to me), but at least it's easy to deal with." | |
9124 msgstr "" | |
9125 | |
9126 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
9127 #: ../en/ch09-undo.xml:273 | |
9128 msgid "" | |
9129 "So remember, to revert a <command role=\"hg-cmd\">hg rename</command>, you " | |
9130 "must provide <emphasis>both</emphasis> the source and destination names." | |
9131 msgstr "" | |
9132 | |
9133 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
9134 #: ../en/ch09-undo.xml:278 | |
9135 msgid "% TODO: the output doesn't look like it will be removed!" | |
9136 msgstr "" | |
9137 | |
9138 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
9139 #: ../en/ch09-undo.xml:281 | |
9140 msgid "" | |
9141 "(By the way, if you rename a file, then modify the renamed-to file, then " | |
9142 "revert both components of the rename, when Mercurial restores the file that " | |
9143 "was removed as part of the rename, it will be unmodified. If you need the " | |
9144 "modifications in the renamed-to file to show up in the renamed-from file, " | |
9145 "don't forget to copy them over.)" | |
9146 msgstr "" | |
9147 | |
9148 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
9149 #: ../en/ch09-undo.xml:288 | |
9150 msgid "" | |
9151 "These fiddly aspects of reverting a rename arguably constitute a small bug in " | |
9152 "Mercurial." | |
9153 msgstr "" | |
9154 | |
9155 #. type: Content of: <book><chapter><sect1><title> | |
9156 #: ../en/ch09-undo.xml:295 | |
9157 msgid "Dealing with committed changes" | |
9158 msgstr "" | |
9159 | |
9160 #. type: Content of: <book><chapter><sect1><para> | |
9161 #: ../en/ch09-undo.xml:297 | |
9162 msgid "" | |
9163 "Consider a case where you have committed a change $a$, and another change $b$ " | |
9164 "on top of it; you then realise that change $a$ was incorrect. Mercurial lets " | |
9165 "you <quote>back out</quote> an entire changeset automatically, and building " | |
9166 "blocks that let you reverse part of a changeset by hand." | |
9167 msgstr "" | |
9168 | |
9169 #. type: Content of: <book><chapter><sect1><para> | |
9170 #: ../en/ch09-undo.xml:303 | |
9171 msgid "" | |
9172 "Before you read this section, here's something to keep in mind: the <command " | |
9173 "role=\"hg-cmd\">hg backout</command> command undoes changes by " | |
9174 "<emphasis>adding</emphasis> history, not by modifying or erasing it. It's " | |
9175 "the right tool to use if you're fixing bugs, but not if you're trying to undo " | |
9176 "some change that has catastrophic consequences. To deal with those, see " | |
9177 "section <xref linkend=\"sec.undo.aaaiiieee\"/>." | |
9178 msgstr "" | |
9179 | |
9180 #. type: Content of: <book><chapter><sect1><sect2><title> | |
9181 #: ../en/ch09-undo.xml:312 | |
9182 msgid "Backing out a changeset" | |
9183 msgstr "" | |
9184 | |
9185 #. type: Content of: <book><chapter><sect1><sect2><para> | |
9186 #: ../en/ch09-undo.xml:314 | |
9187 msgid "" | |
9188 "The <command role=\"hg-cmd\">hg backout</command> command lets you " | |
9189 "<quote>undo</quote> the effects of an entire changeset in an automated " | |
9190 "fashion. Because Mercurial's history is immutable, this command " | |
9191 "<emphasis>does not</emphasis> get rid of the changeset you want to undo. " | |
9192 "Instead, it creates a new changeset that <emphasis>reverses</emphasis> the " | |
9193 "effect of the to-be-undone changeset." | |
9194 msgstr "" | |
9195 | |
9196 # | |
9197 #. type: Content of: <book><chapter><sect1><sect2><para> | |
9198 #: ../en/ch09-undo.xml:323 | |
9199 msgid "" | |
9200 "The operation of the <command role=\"hg-cmd\">hg backout</command> command is " | |
9201 "a little intricate, so let's illustrate it with some examples. First, we'll " | |
9202 "create a repository with some simple changes." | |
9203 msgstr "" | |
9204 | |
9205 #. type: Content of: <book><chapter><sect1><sect2><para> | |
9206 #: ../en/ch09-undo.xml:330 | |
9207 msgid "" | |
9208 "The <command role=\"hg-cmd\">hg backout</command> command takes a single " | |
9209 "changeset ID as its argument; this is the changeset to back out. Normally, " | |
9210 "<command role=\"hg-cmd\">hg backout</command> will drop you into a text " | |
9211 "editor to write a commit message, so you can record why you're backing the " | |
9212 "change out. In this example, we provide a commit message on the command line " | |
9213 "using the <option role=\"hg-opt-backout\">-m</option> option." | |
9214 msgstr "" | |
9215 | |
9216 #. type: Content of: <book><chapter><sect1><sect2><title> | |
9217 #: ../en/ch09-undo.xml:341 | |
9218 msgid "Backing out the tip changeset" | |
9219 msgstr "" | |
9220 | |
9221 #. type: Content of: <book><chapter><sect1><sect2><para> | |
9222 #: ../en/ch09-undo.xml:343 | |
9223 msgid "We're going to start by backing out the last changeset we committed." | |
9224 msgstr "" | |
9225 | |
9226 #. type: Content of: <book><chapter><sect1><sect2><para> | |
9227 #: ../en/ch09-undo.xml:348 | |
9228 msgid "" | |
9229 "You can see that the second line from <filename>myfile</filename> is no " | |
9230 "longer present. Taking a look at the output of <command role=\"hg-cmd\">hg " | |
9231 "log</command> gives us an idea of what the <command role=\"hg-cmd\">hg " | |
9232 "backout</command> command has done. &interaction.backout.simple.log; Notice " | |
9233 "that the new changeset that <command role=\"hg-cmd\">hg backout</command> has " | |
9234 "created is a child of the changeset we backed out. It's easier to see this " | |
9235 "in figure <xref linkend=\"fig.undo.backout\"/>, which presents a graphical " | |
9236 "view of the change history. As you can see, the history is nice and linear." | |
9237 msgstr "" | |
9238 | |
9239 #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject> | |
9240 #: ../en/ch09-undo.xml:362 | |
9241 msgid "" | |
9242 "<imageobject><imagedata fileref=\"images/undo-simple.png\"/></imageobject>" | |
9243 msgstr "" | |
9244 | |
9245 #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject><caption><para> | |
9246 #: ../en/ch09-undo.xml:364 ../en/ch09-undo.xml:477 | |
9247 msgid "" | |
9248 "Backing out a change using the <command role=\"hg-cmd\">hg backout</command> " | |
9249 "command" | |
9250 msgstr "" | |
9251 | |
9252 #. type: Content of: <book><chapter><sect1><sect2><title> | |
9253 #: ../en/ch09-undo.xml:373 | |
9254 msgid "Backing out a non-tip change" | |
9255 msgstr "" | |
9256 | |
9257 #. type: Content of: <book><chapter><sect1><sect2><para> | |
9258 #: ../en/ch09-undo.xml:375 | |
9259 msgid "" | |
9260 "If you want to back out a change other than the last one you committed, pass " | |
9261 "the <option role=\"hg-opt-backout\">--merge</option> option to the <command " | |
9262 "role=\"hg-cmd\">hg backout</command> command." | |
9263 msgstr "" | |
9264 | |
9265 #. type: Content of: <book><chapter><sect1><sect2><para> | |
9266 #: ../en/ch09-undo.xml:382 | |
9267 msgid "" | |
9268 "This makes backing out any changeset a <quote>one-shot</quote> operation " | |
9269 "that's usually simple and fast." | |
9270 msgstr "" | |
9271 | |
9272 #. type: Content of: <book><chapter><sect1><sect2><para> | |
9273 #: ../en/ch09-undo.xml:388 | |
9274 msgid "" | |
9275 "If you take a look at the contents of <filename>myfile</filename> after the " | |
9276 "backout finishes, you'll see that the first and third changes are present, " | |
9277 "but not the second." | |
9278 msgstr "" | |
9279 | |
9280 #. type: Content of: <book><chapter><sect1><sect2><para> | |
9281 #: ../en/ch09-undo.xml:395 | |
9282 msgid "" | |
9283 "As the graphical history in figure <xref linkend=\"fig.undo.backout-non-tip\"/" | |
9284 "> illustrates, Mercurial actually commits <emphasis>two</emphasis> changes in " | |
9285 "this kind of situation (the box-shaped nodes are the ones that Mercurial " | |
9286 "commits automatically). Before Mercurial begins the backout process, it " | |
9287 "first remembers what the current parent of the working directory is. It then " | |
9288 "backs out the target changeset, and commits that as a changeset. Finally, it " | |
9289 "merges back to the previous parent of the working directory, and commits the " | |
9290 "result of the merge." | |
9291 msgstr "" | |
9292 | |
9293 #. type: Content of: <book><chapter><sect1><sect2><para> | |
9294 #: ../en/ch09-undo.xml:406 | |
9295 msgid "" | |
9296 "% TODO: to me it looks like mercurial doesn't commit the second merge " | |
9297 "automatically!" | |
9298 msgstr "" | |
9299 | |
9300 #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject> | |
9301 #: ../en/ch09-undo.xml:410 | |
9302 msgid "" | |
9303 "<imageobject><imagedata fileref=\"images/undo-non-tip.png\"/></imageobject>" | |
9304 msgstr "" | |
9305 | |
9306 #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject><caption><para> | |
9307 #: ../en/ch09-undo.xml:412 | |
9308 msgid "" | |
9309 "Automated backout of a non-tip change using the <command role=\"hg-cmd\">hg " | |
9310 "backout</command> command" | |
9311 msgstr "" | |
9312 | |
9313 #. type: Content of: <book><chapter><sect1><sect2><para> | |
9314 #: ../en/ch09-undo.xml:418 | |
9315 msgid "" | |
9316 "The result is that you end up <quote>back where you were</quote>, only with " | |
9317 "some extra history that undoes the effect of the changeset you wanted to back " | |
9318 "out." | |
9319 msgstr "" | |
9320 | |
9321 #. type: Content of: <book><chapter><sect1><sect2><sect3><title> | |
9322 #: ../en/ch09-undo.xml:423 | |
9323 msgid "Always use the <option role=\"hg-opt-backout\">--merge</option> option" | |
9324 msgstr "" | |
9325 | |
9326 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
9327 #: ../en/ch09-undo.xml:426 | |
9328 msgid "" | |
9329 "In fact, since the <option role=\"hg-opt-backout\">--merge</option> option " | |
9330 "will do the <quote>right thing</quote> whether or not the changeset you're " | |
9331 "backing out is the tip (i.e. it won't try to merge if it's backing out the " | |
9332 "tip, since there's no need), you should <emphasis>always</emphasis> use this " | |
9333 "option when you run the <command role=\"hg-cmd\">hg backout</command> command." | |
9334 msgstr "" | |
9335 | |
9336 #. type: Content of: <book><chapter><sect1><sect2><title> | |
9337 #: ../en/ch09-undo.xml:437 | |
9338 msgid "Gaining more control of the backout process" | |
9339 msgstr "" | |
9340 | |
9341 #. type: Content of: <book><chapter><sect1><sect2><para> | |
9342 #: ../en/ch09-undo.xml:439 | |
9343 msgid "" | |
9344 "While I've recommended that you always use the <option role=\"hg-opt-backout" | |
9345 "\">--merge</option> option when backing out a change, the <command role=\"hg-" | |
9346 "cmd\">hg backout</command> command lets you decide how to merge a backout " | |
9347 "changeset. Taking control of the backout process by hand is something you " | |
9348 "will rarely need to do, but it can be useful to understand what the <command " | |
9349 "role=\"hg-cmd\">hg backout</command> command is doing for you automatically. " | |
9350 "To illustrate this, let's clone our first repository, but omit the backout " | |
9351 "change that it contains." | |
9352 msgstr "" | |
9353 | |
9354 #. type: Content of: <book><chapter><sect1><sect2><para> | |
9355 #: ../en/ch09-undo.xml:452 | |
9356 msgid "" | |
9357 "As with our earlier example, We'll commit a third changeset, then back out " | |
9358 "its parent, and see what happens." | |
9359 msgstr "" | |
9360 | |
9361 #. type: Content of: <book><chapter><sect1><sect2><para> | |
9362 #: ../en/ch09-undo.xml:458 | |
9363 msgid "" | |
9364 "Our new changeset is again a descendant of the changeset we backout out; it's " | |
9365 "thus a new head, <emphasis>not</emphasis> a descendant of the changeset that " | |
9366 "was the tip. The <command role=\"hg-cmd\">hg backout</command> command was " | |
9367 "quite explicit in telling us this." | |
9368 msgstr "" | |
9369 | |
9370 #. type: Content of: <book><chapter><sect1><sect2><para> | |
9371 #: ../en/ch09-undo.xml:466 | |
9372 msgid "" | |
9373 "Again, it's easier to see what has happened by looking at a graph of the " | |
9374 "revision history, in figure <xref linkend=\"fig.undo.backout-manual\"/>. " | |
9375 "This makes it clear that when we use <command role=\"hg-cmd\">hg backout</" | |
9376 "command> to back out a change other than the tip, Mercurial adds a new head " | |
9377 "to the repository (the change it committed is box-shaped)." | |
9378 msgstr "" | |
9379 | |
9380 #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject> | |
9381 #: ../en/ch09-undo.xml:475 | |
9382 msgid "" | |
9383 "<imageobject><imagedata fileref=\"images/undo-manual.png\"/></imageobject>" | |
9384 msgstr "" | |
9385 | |
9386 #. type: Content of: <book><chapter><sect1><sect2><para> | |
9387 #: ../en/ch09-undo.xml:484 | |
9388 msgid "" | |
9389 "After the <command role=\"hg-cmd\">hg backout</command> command has " | |
9390 "completed, it leaves the new <quote>backout</quote> changeset as the parent " | |
9391 "of the working directory." | |
9392 msgstr "" | |
9393 | |
9394 #. type: Content of: <book><chapter><sect1><sect2><para> | |
9395 #: ../en/ch09-undo.xml:491 | |
9396 msgid "Now we have two isolated sets of changes." | |
9397 msgstr "" | |
9398 | |
9399 #. type: Content of: <book><chapter><sect1><sect2><para> | |
9400 #: ../en/ch09-undo.xml:495 | |
9401 msgid "" | |
9402 "Let's think about what we expect to see as the contents of <filename>myfile</" | |
9403 "filename> now. The first change should be present, because we've never " | |
9404 "backed it out. The second change should be missing, as that's the change we " | |
9405 "backed out. Since the history graph shows the third change as a separate " | |
9406 "head, we <emphasis>don't</emphasis> expect to see the third change present in " | |
9407 "<filename>myfile</filename>." | |
9408 msgstr "" | |
9409 | |
9410 #. type: Content of: <book><chapter><sect1><sect2><para> | |
9411 #: ../en/ch09-undo.xml:505 | |
9412 msgid "" | |
9413 "To get the third change back into the file, we just do a normal merge of our " | |
9414 "two heads." | |
9415 msgstr "" | |
9416 | |
9417 #. type: Content of: <book><chapter><sect1><sect2><para> | |
9418 #: ../en/ch09-undo.xml:510 | |
9419 msgid "" | |
9420 "Afterwards, the graphical history of our repository looks like figure <xref " | |
9421 "linkend=\"fig.undo.backout-manual-merge\"/>." | |
9422 msgstr "" | |
9423 | |
9424 #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject> | |
9425 #: ../en/ch09-undo.xml:515 | |
9426 msgid "" | |
9427 "<imageobject><imagedata fileref=\"images/undo-manual-merge.png\"/></" | |
9428 "imageobject>" | |
9429 msgstr "" | |
9430 | |
9431 #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject><caption><para> | |
9432 #: ../en/ch09-undo.xml:517 | |
9433 msgid "Manually merging a backout change" | |
9434 msgstr "" | |
9435 | |
9436 #. type: Content of: <book><chapter><sect1><sect2><title> | |
9437 #: ../en/ch09-undo.xml:524 | |
9438 msgid "Why <command role=\"hg-cmd\">hg backout</command> works as it does" | |
9439 msgstr "" | |
9440 | |
9441 #. type: Content of: <book><chapter><sect1><sect2><para> | |
9442 #: ../en/ch09-undo.xml:527 | |
9443 msgid "" | |
9444 "Here's a brief description of how the <command role=\"hg-cmd\">hg backout</" | |
9445 "command> command works." | |
9446 msgstr "" | |
9447 | |
9448 #. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para> | |
9449 #: ../en/ch09-undo.xml:530 | |
9450 msgid "" | |
9451 "It ensures that the working directory is <quote>clean</quote>, i.e. that the " | |
9452 "output of <command role=\"hg-cmd\">hg status</command> would be empty." | |
9453 msgstr "" | |
9454 | |
9455 #. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para> | |
9456 #: ../en/ch09-undo.xml:534 | |
9457 msgid "" | |
9458 "It remembers the current parent of the working directory. Let's call this " | |
9459 "changeset <literal>orig</literal>" | |
9460 msgstr "" | |
9461 | |
9462 #. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para> | |
9463 #: ../en/ch09-undo.xml:538 | |
9464 msgid "" | |
9465 "It does the equivalent of a <command role=\"hg-cmd\">hg update</command> to " | |
9466 "sync the working directory to the changeset you want to back out. Let's call " | |
9467 "this changeset <literal>backout</literal>" | |
9468 msgstr "" | |
9469 | |
9470 #. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para> | |
9471 #: ../en/ch09-undo.xml:543 | |
9472 msgid "" | |
9473 "It finds the parent of that changeset. Let's call that changeset " | |
9474 "<literal>parent</literal>." | |
9475 msgstr "" | |
9476 | |
9477 #. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para> | |
9478 #: ../en/ch09-undo.xml:546 | |
9479 msgid "" | |
9480 "For each file that the <literal>backout</literal> changeset affected, it does " | |
9481 "the equivalent of a <command role=\"hg-cmd\">hg revert -r parent</command> on " | |
9482 "that file, to restore it to the contents it had before that changeset was " | |
9483 "committed." | |
9484 msgstr "" | |
9485 | |
9486 #. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para> | |
9487 #: ../en/ch09-undo.xml:553 | |
9488 msgid "" | |
9489 "It commits the result as a new changeset. This changeset has " | |
9490 "<literal>backout</literal> as its parent." | |
9491 msgstr "" | |
9492 | |
9493 #. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para> | |
9494 #: ../en/ch09-undo.xml:557 | |
9495 msgid "" | |
9496 "If you specify <option role=\"hg-opt-backout\">--merge</option> on the " | |
9497 "command line, it merges with <literal>orig</literal>, and commits the result " | |
9498 "of the merge." | |
9499 msgstr "" | |
9500 | |
9501 #. type: Content of: <book><chapter><sect1><sect2><para> | |
9502 #: ../en/ch09-undo.xml:563 | |
9503 msgid "" | |
9504 "An alternative way to implement the <command role=\"hg-cmd\">hg backout</" | |
9505 "command> command would be to <command role=\"hg-cmd\">hg export</command> the " | |
9506 "to-be-backed-out changeset as a diff, then use the <option role=\"cmd-opt-" | |
9507 "patch\">--reverse</option> option to the <command>patch</command> command to " | |
9508 "reverse the effect of the change without fiddling with the working " | |
9509 "directory. This sounds much simpler, but it would not work nearly as well." | |
9510 msgstr "" | |
9511 | |
9512 #. type: Content of: <book><chapter><sect1><sect2><para> | |
9513 #: ../en/ch09-undo.xml:573 | |
9514 msgid "" | |
9515 "The reason that <command role=\"hg-cmd\">hg backout</command> does an update, " | |
9516 "a commit, a merge, and another commit is to give the merge machinery the best " | |
9517 "chance to do a good job when dealing with all the changes <emphasis>between</" | |
9518 "emphasis> the change you're backing out and the current tip." | |
9519 msgstr "" | |
9520 | |
9521 #. type: Content of: <book><chapter><sect1><sect2><para> | |
9522 #: ../en/ch09-undo.xml:580 | |
9523 msgid "" | |
9524 "If you're backing out a changeset that's 100 revisions back in your project's " | |
9525 "history, the chances that the <command>patch</command> command will be able " | |
9526 "to apply a reverse diff cleanly are not good, because intervening changes are " | |
9527 "likely to have <quote>broken the context</quote> that <command>patch</" | |
9528 "command> uses to determine whether it can apply a patch (if this sounds like " | |
9529 "gibberish, see <xref linkend=\"sec.mq.patch\"/> for a discussion of the " | |
9530 "<command>patch</command> command). Also, Mercurial's merge machinery will " | |
9531 "handle files and directories being renamed, permission changes, and " | |
9532 "modifications to binary files, none of which <command>patch</command> can " | |
9533 "deal with." | |
9534 msgstr "" | |
9535 | |
9536 #. type: Content of: <book><chapter><sect1><title> | |
9537 #: ../en/ch09-undo.xml:597 | |
9538 msgid "Changes that should never have been" | |
9539 msgstr "" | |
9540 | |
9541 #. type: Content of: <book><chapter><sect1><para> | |
9542 #: ../en/ch09-undo.xml:599 | |
9543 msgid "" | |
9544 "Most of the time, the <command role=\"hg-cmd\">hg backout</command> command " | |
9545 "is exactly what you need if you want to undo the effects of a change. It " | |
9546 "leaves a permanent record of exactly what you did, both when committing the " | |
9547 "original changeset and when you cleaned up after it." | |
9548 msgstr "" | |
9549 | |
9550 #. type: Content of: <book><chapter><sect1><para> | |
9551 #: ../en/ch09-undo.xml:605 | |
9552 msgid "" | |
9553 "On rare occasions, though, you may find that you've committed a change that " | |
9554 "really should not be present in the repository at all. For example, it would " | |
9555 "be very unusual, and usually considered a mistake, to commit a software " | |
9556 "project's object files as well as its source files. Object files have almost " | |
9557 "no intrinsic value, and they're <emphasis>big</emphasis>, so they increase " | |
9558 "the size of the repository and the amount of time it takes to clone or pull " | |
9559 "changes." | |
9560 msgstr "" | |
9561 | |
9562 #. type: Content of: <book><chapter><sect1><para> | |
9563 #: ../en/ch09-undo.xml:614 | |
9564 msgid "" | |
9565 "Before I discuss the options that you have if you commit a <quote>brown paper " | |
9566 "bag</quote> change (the kind that's so bad that you want to pull a brown " | |
9567 "paper bag over your head), let me first discuss some approaches that probably " | |
9568 "won't work." | |
9569 msgstr "" | |
9570 | |
9571 #. type: Content of: <book><chapter><sect1><para> | |
9572 #: ../en/ch09-undo.xml:619 | |
9573 msgid "" | |
9574 "Since Mercurial treats history as accumulative&emdash;every change builds on " | |
9575 "top of all changes that preceded it&emdash;you generally can't just make " | |
9576 "disastrous changes disappear. The one exception is when you've just " | |
9577 "committed a change, and it hasn't been pushed or pulled into another " | |
9578 "repository. That's when you can safely use the <command role=\"hg-cmd\">hg " | |
9579 "rollback</command> command, as I detailed in section <xref linkend=\"sec.undo." | |
9580 "rollback\"/>." | |
9581 msgstr "" | |
9582 | |
9583 #. type: Content of: <book><chapter><sect1><para> | |
9584 #: ../en/ch09-undo.xml:628 | |
9585 msgid "" | |
9586 "After you've pushed a bad change to another repository, you <emphasis>could</" | |
9587 "emphasis> still use <command role=\"hg-cmd\">hg rollback</command> to make " | |
9588 "your local copy of the change disappear, but it won't have the consequences " | |
9589 "you want. The change will still be present in the remote repository, so it " | |
9590 "will reappear in your local repository the next time you pull." | |
9591 msgstr "" | |
9592 | |
9593 #. type: Content of: <book><chapter><sect1><para> | |
9594 #: ../en/ch09-undo.xml:636 | |
9595 msgid "" | |
9596 "If a situation like this arises, and you know which repositories your bad " | |
9597 "change has propagated into, you can <emphasis>try</emphasis> to get rid of " | |
9598 "the changeefrom <emphasis>every</emphasis> one of those repositories. This " | |
9599 "is, of course, not a satisfactory solution: if you miss even a single " | |
9600 "repository while you're expunging, the change is still <quote>in the wild</" | |
9601 "quote>, and could propagate further." | |
9602 msgstr "" | |
9603 | |
9604 #. type: Content of: <book><chapter><sect1><para> | |
9605 #: ../en/ch09-undo.xml:644 | |
9606 msgid "" | |
9607 "If you've committed one or more changes <emphasis>after</emphasis> the change " | |
9608 "that you'd like to see disappear, your options are further reduced. Mercurial " | |
9609 "doesn't provide a way to <quote>punch a hole</quote> in history, leaving " | |
9610 "changesets intact." | |
9611 msgstr "" | |
9612 | |
9613 #. type: Content of: <book><chapter><sect1><para> | |
9614 #: ../en/ch09-undo.xml:650 | |
9615 msgid "" | |
9616 "XXX This needs filling out. The <literal>hg-replay</literal> script in the " | |
9617 "<literal>examples</literal> directory works, but doesn't handle merge " | |
9618 "changesets. Kind of an important omission." | |
9619 msgstr "" | |
9620 | |
9621 #. type: Content of: <book><chapter><sect1><sect2><title> | |
9622 #: ../en/ch09-undo.xml:656 | |
9623 msgid "Protect yourself from <quote>escaped</quote> changes" | |
9624 msgstr "" | |
9625 | |
9626 #. type: Content of: <book><chapter><sect1><sect2><para> | |
9627 #: ../en/ch09-undo.xml:659 | |
9628 msgid "" | |
9629 "If you've committed some changes to your local repository and they've been " | |
9630 "pushed or pulled somewhere else, this isn't necessarily a disaster. You can " | |
9631 "protect yourself ahead of time against some classes of bad changeset. This " | |
9632 "is particularly easy if your team usually pulls changes from a central " | |
9633 "repository." | |
9634 msgstr "" | |
9635 | |
9636 #. type: Content of: <book><chapter><sect1><sect2><para> | |
9637 #: ../en/ch09-undo.xml:666 | |
9638 msgid "" | |
9639 "By configuring some hooks on that repository to validate incoming changesets " | |
9640 "(see chapter <xref linkend=\"chap.hook\"/>), you can automatically prevent " | |
9641 "some kinds of bad changeset from being pushed to the central repository at " | |
9642 "all. With such a configuration in place, some kinds of bad changeset will " | |
9643 "naturally tend to <quote>die out</quote> because they can't propagate into " | |
9644 "the central repository. Better yet, this happens without any need for " | |
9645 "explicit intervention." | |
9646 msgstr "" | |
9647 | |
9648 #. type: Content of: <book><chapter><sect1><sect2><para> | |
9649 #: ../en/ch09-undo.xml:676 | |
9650 msgid "" | |
9651 "For instance, an incoming change hook that verifies that a changeset will " | |
9652 "actually compile can prevent people from inadvertantly <quote>breaking the " | |
9653 "build</quote>." | |
9654 msgstr "" | |
9655 | |
9656 #. type: Content of: <book><chapter><sect1><title> | |
9657 #: ../en/ch09-undo.xml:683 | |
9658 msgid "Finding the source of a bug" | |
9659 msgstr "" | |
9660 | |
9661 #. type: Content of: <book><chapter><sect1><para> | |
9662 #: ../en/ch09-undo.xml:685 | |
9663 msgid "" | |
9664 "While it's all very well to be able to back out a changeset that introduced a " | |
9665 "bug, this requires that you know which changeset to back out. Mercurial " | |
9666 "provides an invaluable command, called <command role=\"hg-cmd\">hg bisect</" | |
9667 "command>, that helps you to automate this process and accomplish it very " | |
9668 "efficiently." | |
9669 msgstr "" | |
9670 | |
9671 #. type: Content of: <book><chapter><sect1><para> | |
9672 #: ../en/ch09-undo.xml:692 | |
9673 msgid "" | |
9674 "The idea behind the <command role=\"hg-cmd\">hg bisect</command> command is " | |
9675 "that a changeset has introduced some change of behaviour that you can " | |
9676 "identify with a simple binary test. You don't know which piece of code " | |
9677 "introduced the change, but you know how to test for the presence of the bug. " | |
9678 "The <command role=\"hg-cmd\">hg bisect</command> command uses your test to " | |
9679 "direct its search for the changeset that introduced the code that caused the " | |
9680 "bug." | |
9681 msgstr "" | |
9682 | |
9683 #. type: Content of: <book><chapter><sect1><para> | |
9684 #: ../en/ch09-undo.xml:701 | |
9685 msgid "" | |
9686 "Here are a few scenarios to help you understand how you might apply this " | |
9687 "command." | |
9688 msgstr "" | |
9689 | |
9690 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
9691 #: ../en/ch09-undo.xml:704 | |
9692 msgid "" | |
9693 "The most recent version of your software has a bug that you remember wasn't " | |
9694 "present a few weeks ago, but you don't know when it was introduced. Here, " | |
9695 "your binary test checks for the presence of that bug." | |
9696 msgstr "" | |
9697 | |
9698 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
9699 #: ../en/ch09-undo.xml:709 | |
9700 msgid "" | |
9701 "You fixed a bug in a rush, and now it's time to close the entry in your " | |
9702 "team's bug database. The bug database requires a changeset ID when you close " | |
9703 "an entry, but you don't remember which changeset you fixed the bug in. Once " | |
9704 "again, your binary test checks for the presence of the bug." | |
9705 msgstr "" | |
9706 | |
9707 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
9708 #: ../en/ch09-undo.xml:716 | |
9709 msgid "" | |
9710 "Your software works correctly, but runs 15% slower than the last time you " | |
9711 "measured it. You want to know which changeset introduced the performance " | |
9712 "regression. In this case, your binary test measures the performance of your " | |
9713 "software, to see whether it's <quote>fast</quote> or <quote>slow</quote>." | |
9714 msgstr "" | |
9715 | |
9716 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
9717 #: ../en/ch09-undo.xml:723 | |
9718 msgid "" | |
9719 "The sizes of the components of your project that you ship exploded recently, " | |
9720 "and you suspect that something changed in the way you build your project." | |
9721 msgstr "" | |
9722 | |
9723 #. type: Content of: <book><chapter><sect1><para> | |
9724 #: ../en/ch09-undo.xml:728 | |
9725 msgid "" | |
9726 "From these examples, it should be clear that the <command role=\"hg-cmd\">hg " | |
9727 "bisect</command> command is not useful only for finding the sources of bugs. " | |
9728 "You can use it to find any <quote>emergent property</quote> of a repository " | |
9729 "(anything that you can't find from a simple text search of the files in the " | |
9730 "tree) for which you can write a binary test." | |
9731 msgstr "" | |
9732 | |
9733 #. type: Content of: <book><chapter><sect1><para> | |
9734 #: ../en/ch09-undo.xml:735 | |
9735 msgid "" | |
9736 "We'll introduce a little bit of terminology here, just to make it clear which " | |
9737 "parts of the search process are your responsibility, and which are " | |
9738 "Mercurial's. A <emphasis>test</emphasis> is something that <emphasis>you</" | |
9739 "emphasis> run when <command role=\"hg-cmd\">hg bisect</command> chooses a " | |
9740 "changeset. A <emphasis>probe</emphasis> is what <command role=\"hg-cmd\">hg " | |
9741 "bisect</command> runs to tell whether a revision is good. Finally, we'll use " | |
9742 "the word <quote>bisect</quote>, as both a noun and a verb, to stand in for " | |
9743 "the phrase <quote>search using the <command role=\"hg-cmd\">hg bisect</" | |
9744 "command> command</quote>." | |
9745 msgstr "" | |
9746 | |
9747 #. type: Content of: <book><chapter><sect1><para> | |
9748 #: ../en/ch09-undo.xml:748 | |
9749 msgid "" | |
9750 "One simple way to automate the searching process would be simply to probe " | |
9751 "every changeset. However, this scales poorly. If it took ten minutes to " | |
9752 "test a single changeset, and you had 10,000 changesets in your repository, " | |
9753 "the exhaustive approach would take on average 35 <emphasis>days</emphasis> to " | |
9754 "find the changeset that introduced a bug. Even if you knew that the bug was " | |
9755 "introduced by one of the last 500 changesets, and limited your search to " | |
9756 "those, you'd still be looking at over 40 hours to find the changeset that " | |
9757 "introduced your bug." | |
9758 msgstr "" | |
9759 | |
9760 #. type: Content of: <book><chapter><sect1><para> | |
9761 #: ../en/ch09-undo.xml:758 | |
9762 msgid "" | |
9763 "What the <command role=\"hg-cmd\">hg bisect</command> command does is use its " | |
9764 "knowledge of the <quote>shape</quote> of your project's revision history to " | |
9765 "perform a search in time proportional to the <emphasis>logarithm</emphasis> " | |
9766 "of the number of changesets to check (the kind of search it performs is " | |
9767 "called a dichotomic search). With this approach, searching through 10,000 " | |
9768 "changesets will take less than three hours, even at ten minutes per test (the " | |
9769 "search will require about 14 tests). Limit your search to the last hundred " | |
9770 "changesets, and it will take only about an hour (roughly seven tests)." | |
9771 msgstr "" | |
9772 | |
9773 #. type: Content of: <book><chapter><sect1><para> | |
9774 #: ../en/ch09-undo.xml:769 | |
9775 msgid "" | |
9776 "The <command role=\"hg-cmd\">hg bisect</command> command is aware of the " | |
9777 "<quote>branchy</quote> nature of a Mercurial project's revision history, so " | |
9778 "it has no problems dealing with branches, merges, or multiple heads in a " | |
9779 "repository. It can prune entire branches of history with a single probe, " | |
9780 "which is how it operates so efficiently." | |
9781 msgstr "" | |
9782 | |
9783 #. type: Content of: <book><chapter><sect1><sect2><title> | |
9784 #: ../en/ch09-undo.xml:777 | |
9785 msgid "Using the <command role=\"hg-cmd\">hg bisect</command> command" | |
9786 msgstr "" | |
9787 | |
9788 #. type: Content of: <book><chapter><sect1><sect2><para> | |
9789 #: ../en/ch09-undo.xml:780 | |
9790 msgid "" | |
9791 "Here's an example of <command role=\"hg-cmd\">hg bisect</command> in action." | |
9792 msgstr "" | |
9793 | |
9794 #. type: Content of: <book><chapter><sect1><sect2><note><para> | |
9795 #: ../en/ch09-undo.xml:784 | |
9796 msgid "" | |
9797 "In versions 0.9.5 and earlier of Mercurial, <command role=\"hg-cmd\">hg " | |
9798 "bisect</command> was not a core command: it was distributed with Mercurial as " | |
9799 "an extension. This section describes the built-in command, not the old " | |
9800 "extension." | |
9801 msgstr "" | |
9802 | |
9803 #. type: Content of: <book><chapter><sect1><sect2><para> | |
9804 #: ../en/ch09-undo.xml:791 | |
9805 msgid "" | |
9806 "Now let's create a repository, so that we can try out the <command role=\"hg-" | |
9807 "cmd\">hg bisect</command> command in isolation." | |
9808 msgstr "" | |
9809 | |
9810 #. type: Content of: <book><chapter><sect1><sect2><para> | |
9811 #: ../en/ch09-undo.xml:797 | |
9812 msgid "" | |
9813 "We'll simulate a project that has a bug in it in a simple-minded way: create " | |
9814 "trivial changes in a loop, and nominate one specific change that will have " | |
9815 "the <quote>bug</quote>. This loop creates 35 changesets, each adding a " | |
9816 "single file to the repository. We'll represent our <quote>bug</quote> with a " | |
9817 "file that contains the text <quote>i have a gub</quote>." | |
9818 msgstr "" | |
9819 | |
9820 #. type: Content of: <book><chapter><sect1><sect2><para> | |
9821 #: ../en/ch09-undo.xml:807 | |
9822 msgid "" | |
9823 "The next thing that we'd like to do is figure out how to use the <command " | |
9824 "role=\"hg-cmd\">hg bisect</command> command. We can use Mercurial's normal " | |
9825 "built-in help mechanism for this." | |
9826 msgstr "" | |
9827 | |
9828 #. type: Content of: <book><chapter><sect1><sect2><para> | |
9829 #: ../en/ch09-undo.xml:814 | |
9830 msgid "" | |
9831 "The <command role=\"hg-cmd\">hg bisect</command> command works in steps. " | |
9832 "Each step proceeds as follows." | |
9833 msgstr "" | |
9834 | |
9835 #. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para> | |
9836 #: ../en/ch09-undo.xml:817 | |
9837 msgid "You run your binary test." | |
9838 msgstr "" | |
9839 | |
9840 #. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><itemizedlist><listitem><para> | |
9841 #: ../en/ch09-undo.xml:819 | |
9842 msgid "" | |
9843 "If the test succeeded, you tell <command role=\"hg-cmd\">hg bisect</command> " | |
9844 "by running the <command role=\"hg-cmd\">hg bisect good</command> command." | |
9845 msgstr "" | |
9846 | |
9847 #. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><itemizedlist><listitem><para> | |
9848 #: ../en/ch09-undo.xml:824 | |
9849 msgid "" | |
9850 "If it failed, run the <command role=\"hg-cmd\">hg bisect bad</command> " | |
9851 "command." | |
9852 msgstr "" | |
9853 | |
9854 #. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para> | |
9855 #: ../en/ch09-undo.xml:828 | |
9856 msgid "" | |
9857 "The command uses your information to decide which changeset to test next." | |
9858 msgstr "" | |
9859 | |
9860 #. type: Content of: <book><chapter><sect1><sect2><orderedlist><listitem><para> | |
9861 #: ../en/ch09-undo.xml:831 | |
9862 msgid "" | |
9863 "It updates the working directory to that changeset, and the process begins " | |
9864 "again." | |
9865 msgstr "" | |
9866 | |
9867 #. type: Content of: <book><chapter><sect1><sect2><para> | |
9868 #: ../en/ch09-undo.xml:834 | |
9869 msgid "" | |
9870 "The process ends when <command role=\"hg-cmd\">hg bisect</command> identifies " | |
9871 "a unique changeset that marks the point where your test transitioned from " | |
9872 "<quote>succeeding</quote> to <quote>failing</quote>." | |
9873 msgstr "" | |
9874 | |
9875 # | |
9876 #. type: Content of: <book><chapter><sect1><sect2><para> | |
9877 #: ../en/ch09-undo.xml:839 | |
9878 msgid "" | |
9879 "To start the search, we must run the <command role=\"hg-cmd\">hg bisect --" | |
9880 "reset</command> command." | |
9881 msgstr "" | |
9882 | |
9883 #. type: Content of: <book><chapter><sect1><sect2><para> | |
9884 #: ../en/ch09-undo.xml:844 | |
9885 msgid "" | |
9886 "In our case, the binary test we use is simple: we check to see if any file in " | |
9887 "the repository contains the string <quote>i have a gub</quote>. If it does, " | |
9888 "this changeset contains the change that <quote>caused the bug</quote>. By " | |
9889 "convention, a changeset that has the property we're searching for is " | |
9890 "<quote>bad</quote>, while one that doesn't is <quote>good</quote>." | |
9891 msgstr "" | |
9892 | |
9893 #. type: Content of: <book><chapter><sect1><sect2><para> | |
9894 #: ../en/ch09-undo.xml:852 | |
9895 msgid "" | |
9896 "Most of the time, the revision to which the working directory is synced " | |
9897 "(usually the tip) already exhibits the problem introduced by the buggy " | |
9898 "change, so we'll mark it as <quote>bad</quote>." | |
9899 msgstr "" | |
9900 | |
9901 # | |
9902 #. type: Content of: <book><chapter><sect1><sect2><para> | |
9903 #: ../en/ch09-undo.xml:859 | |
9904 msgid "" | |
9905 "Our next task is to nominate a changeset that we know <emphasis>doesn't</" | |
9906 "emphasis> have the bug; the <command role=\"hg-cmd\">hg bisect</command> " | |
9907 "command will <quote>bracket</quote> its search between the first pair of good " | |
9908 "and bad changesets. In our case, we know that revision 10 didn't have the " | |
9909 "bug. (I'll have more words about choosing the first <quote>good</quote> " | |
9910 "changeset later.)" | |
9911 msgstr "" | |
9912 | |
9913 #. type: Content of: <book><chapter><sect1><sect2><para> | |
9914 #: ../en/ch09-undo.xml:869 | |
9915 msgid "Notice that this command printed some output." | |
9916 msgstr "" | |
9917 | |
9918 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
9919 #: ../en/ch09-undo.xml:871 | |
9920 msgid "" | |
9921 "It told us how many changesets it must consider before it can identify the " | |
9922 "one that introduced the bug, and how many tests that will require." | |
9923 msgstr "" | |
9924 | |
9925 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
9926 #: ../en/ch09-undo.xml:875 | |
9927 msgid "" | |
9928 "It updated the working directory to the next changeset to test, and told us " | |
9929 "which changeset it's testing." | |
9930 msgstr "" | |
9931 | |
9932 #. type: Content of: <book><chapter><sect1><sect2><para> | |
9933 #: ../en/ch09-undo.xml:880 | |
9934 msgid "" | |
9935 "We now run our test in the working directory. We use the <command>grep</" | |
9936 "command> command to see if our <quote>bad</quote> file is present in the " | |
9937 "working directory. If it is, this revision is bad; if not, this revision is " | |
9938 "good. &interaction.bisect.search.step1;" | |
9939 msgstr "" | |
9940 | |
9941 #. type: Content of: <book><chapter><sect1><sect2><para> | |
9942 #: ../en/ch09-undo.xml:886 | |
9943 msgid "" | |
9944 "This test looks like a perfect candidate for automation, so let's turn it " | |
9945 "into a shell function." | |
9946 msgstr "" | |
9947 | |
9948 #. type: Content of: <book><chapter><sect1><sect2><para> | |
9949 #: ../en/ch09-undo.xml:890 | |
9950 msgid "" | |
9951 "We can now run an entire test step with a single command, <literal>mytest</" | |
9952 "literal>." | |
9953 msgstr "" | |
9954 | |
9955 #. type: Content of: <book><chapter><sect1><sect2><para> | |
9956 #: ../en/ch09-undo.xml:895 | |
9957 msgid "A few more invocations of our canned test step command, and we're done." | |
9958 msgstr "" | |
9959 | |
9960 #. type: Content of: <book><chapter><sect1><sect2><para> | |
9961 #: ../en/ch09-undo.xml:900 | |
9962 msgid "" | |
9963 "Even though we had 40 changesets to search through, the <command role=\"hg-cmd" | |
9964 "\">hg bisect</command> command let us find the changeset that introduced our " | |
9965 "<quote>bug</quote> with only five tests. Because the number of tests that " | |
9966 "the <command role=\"hg-cmd\">hg bisect</command> command performs grows " | |
9967 "logarithmically with the number of changesets to search, the advantage that " | |
9968 "it has over the <quote>brute force</quote> search approach increases with " | |
9969 "every changeset you add." | |
9970 msgstr "" | |
9971 | |
9972 #. type: Content of: <book><chapter><sect1><sect2><title> | |
9973 #: ../en/ch09-undo.xml:911 | |
9974 msgid "Cleaning up after your search" | |
9975 msgstr "" | |
9976 | |
9977 # | |
9978 #. type: Content of: <book><chapter><sect1><sect2><para> | |
9979 #: ../en/ch09-undo.xml:913 | |
9980 msgid "" | |
9981 "When you're finished using the <command role=\"hg-cmd\">hg bisect</command> " | |
9982 "command in a repository, you can use the <command role=\"hg-cmd\">hg bisect " | |
9983 "reset</command> command to drop the information it was using to drive your " | |
9984 "search. The command doesn't use much space, so it doesn't matter if you " | |
9985 "forget to run this command. However, <command role=\"hg-cmd\">hg bisect</" | |
9986 "command> won't let you start a new search in that repository until you do a " | |
9987 "<command role=\"hg-cmd\">hg bisect reset</command>." | |
9988 msgstr "" | |
9989 | |
9990 #. type: Content of: <book><chapter><sect1><title> | |
9991 #: ../en/ch09-undo.xml:928 | |
9992 msgid "Tips for finding bugs effectively" | |
9993 msgstr "" | |
9994 | |
9995 #. type: Content of: <book><chapter><sect1><sect2><title> | |
9996 #: ../en/ch09-undo.xml:931 | |
9997 msgid "Give consistent input" | |
9998 msgstr "" | |
9999 | |
10000 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10001 #: ../en/ch09-undo.xml:933 | |
10002 msgid "" | |
10003 "The <command role=\"hg-cmd\">hg bisect</command> command requires that you " | |
10004 "correctly report the result of every test you perform. If you tell it that a " | |
10005 "test failed when it really succeeded, it <emphasis>might</emphasis> be able " | |
10006 "to detect the inconsistency. If it can identify an inconsistency in your " | |
10007 "reports, it will tell you that a particular changeset is both good and bad. " | |
10008 "However, it can't do this perfectly; it's about as likely to report the wrong " | |
10009 "changeset as the source of the bug." | |
10010 msgstr "" | |
10011 | |
10012 #. type: Content of: <book><chapter><sect1><sect2><title> | |
10013 #: ../en/ch09-undo.xml:945 | |
10014 msgid "Automate as much as possible" | |
10015 msgstr "" | |
10016 | |
10017 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10018 #: ../en/ch09-undo.xml:947 | |
10019 msgid "" | |
10020 "When I started using the <command role=\"hg-cmd\">hg bisect</command> " | |
10021 "command, I tried a few times to run my tests by hand, on the command line. " | |
10022 "This is an approach that I, at least, am not suited to. After a few tries, I " | |
10023 "found that I was making enough mistakes that I was having to restart my " | |
10024 "searches several times before finally getting correct results." | |
10025 msgstr "" | |
10026 | |
10027 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10028 #: ../en/ch09-undo.xml:955 | |
10029 msgid "" | |
10030 "My initial problems with driving the <command role=\"hg-cmd\">hg bisect</" | |
10031 "command> command by hand occurred even with simple searches on small " | |
10032 "repositories; if the problem you're looking for is more subtle, or the number " | |
10033 "of tests that <command role=\"hg-cmd\">hg bisect</command> must perform " | |
10034 "increases, the likelihood of operator error ruining the search is much " | |
10035 "higher. Once I started automating my tests, I had much better results." | |
10036 msgstr "" | |
10037 | |
10038 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10039 #: ../en/ch09-undo.xml:964 | |
10040 msgid "The key to automated testing is twofold:" | |
10041 msgstr "" | |
10042 | |
10043 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
10044 #: ../en/ch09-undo.xml:966 | |
10045 msgid "always test for the same symptom, and" | |
10046 msgstr "" | |
10047 | |
10048 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
10049 #: ../en/ch09-undo.xml:968 | |
10050 msgid "" | |
10051 "always feed consistent input to the <command role=\"hg-cmd\">hg bisect</" | |
10052 "command> command." | |
10053 msgstr "" | |
10054 | |
10055 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10056 #: ../en/ch09-undo.xml:971 | |
10057 msgid "" | |
10058 "In my tutorial example above, the <command>grep</command> command tests for " | |
10059 "the symptom, and the <literal>if</literal> statement takes the result of this " | |
10060 "check and ensures that we always feed the same input to the <command role=" | |
10061 "\"hg-cmd\">hg bisect</command> command. The <literal>mytest</literal> " | |
10062 "function marries these together in a reproducible way, so that every test is " | |
10063 "uniform and consistent." | |
10064 msgstr "" | |
10065 | |
10066 #. type: Content of: <book><chapter><sect1><sect2><title> | |
10067 #: ../en/ch09-undo.xml:981 | |
10068 msgid "Check your results" | |
10069 msgstr "" | |
10070 | |
10071 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10072 #: ../en/ch09-undo.xml:983 | |
10073 msgid "" | |
10074 "Because the output of a <command role=\"hg-cmd\">hg bisect</command> search " | |
10075 "is only as good as the input you give it, don't take the changeset it reports " | |
10076 "as the absolute truth. A simple way to cross-check its report is to manually " | |
10077 "run your test at each of the following changesets:" | |
10078 msgstr "" | |
10079 | |
10080 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
10081 #: ../en/ch09-undo.xml:989 | |
10082 msgid "" | |
10083 "The changeset that it reports as the first bad revision. Your test should " | |
10084 "still report this as bad." | |
10085 msgstr "" | |
10086 | |
10087 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
10088 #: ../en/ch09-undo.xml:993 | |
10089 msgid "" | |
10090 "The parent of that changeset (either parent, if it's a merge). Your test " | |
10091 "should report this changeset as good." | |
10092 msgstr "" | |
10093 | |
10094 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
10095 #: ../en/ch09-undo.xml:997 | |
10096 msgid "" | |
10097 "A child of that changeset. Your test should report this changeset as bad." | |
10098 msgstr "" | |
10099 | |
10100 #. type: Content of: <book><chapter><sect1><sect2><title> | |
10101 #: ../en/ch09-undo.xml:1003 | |
10102 msgid "Beware interference between bugs" | |
10103 msgstr "" | |
10104 | |
10105 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10106 #: ../en/ch09-undo.xml:1005 | |
10107 msgid "" | |
10108 "It's possible that your search for one bug could be disrupted by the presence " | |
10109 "of another. For example, let's say your software crashes at revision 100, " | |
10110 "and worked correctly at revision 50. Unknown to you, someone else introduced " | |
10111 "a different crashing bug at revision 60, and fixed it at revision 80. This " | |
10112 "could distort your results in one of several ways." | |
10113 msgstr "" | |
10114 | |
10115 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10116 #: ../en/ch09-undo.xml:1013 | |
10117 msgid "" | |
10118 "It is possible that this other bug completely <quote>masks</quote> yours, " | |
10119 "which is to say that it occurs before your bug has a chance to manifest " | |
10120 "itself. If you can't avoid that other bug (for example, it prevents your " | |
10121 "project from building), and so can't tell whether your bug is present in a " | |
10122 "particular changeset, the <command role=\"hg-cmd\">hg bisect</command> " | |
10123 "command cannot help you directly. Instead, you can mark a changeset as " | |
10124 "untested by running <command role=\"hg-cmd\">hg bisect --skip</command>." | |
10125 msgstr "" | |
10126 | |
10127 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10128 #: ../en/ch09-undo.xml:1023 | |
10129 msgid "" | |
10130 "A different problem could arise if your test for a bug's presence is not " | |
10131 "specific enough. If you check for <quote>my program crashes</quote>, then " | |
10132 "both your crashing bug and an unrelated crashing bug that masks it will look " | |
10133 "like the same thing, and mislead <command role=\"hg-cmd\">hg bisect</command>." | |
10134 msgstr "" | |
10135 | |
10136 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10137 #: ../en/ch09-undo.xml:1030 | |
10138 msgid "" | |
10139 "Another useful situation in which to use <command role=\"hg-cmd\">hg bisect --" | |
10140 "skip</command> is if you can't test a revision because your project was in a " | |
10141 "broken and hence untestable state at that revision, perhaps because someone " | |
10142 "checked in a change that prevented the project from building." | |
10143 msgstr "" | |
10144 | |
10145 #. type: Content of: <book><chapter><sect1><sect2><title> | |
10146 #: ../en/ch09-undo.xml:1039 | |
10147 msgid "Bracket your search lazily" | |
10148 msgstr "" | |
10149 | |
10150 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10151 #: ../en/ch09-undo.xml:1041 | |
10152 msgid "" | |
10153 "Choosing the first <quote>good</quote> and <quote>bad</quote> changesets that " | |
10154 "will mark the end points of your search is often easy, but it bears a little " | |
10155 "discussion nevertheless. From the perspective of <command role=\"hg-cmd\">hg " | |
10156 "bisect</command>, the <quote>newest</quote> changeset is conventionally " | |
10157 "<quote>bad</quote>, and the older changeset is <quote>good</quote>." | |
10158 msgstr "" | |
10159 | |
10160 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10161 #: ../en/ch09-undo.xml:1049 | |
10162 msgid "" | |
10163 "If you're having trouble remembering when a suitable <quote>good</quote> " | |
10164 "change was, so that you can tell <command role=\"hg-cmd\">hg bisect</" | |
10165 "command>, you could do worse than testing changesets at random. Just " | |
10166 "remember to eliminate contenders that can't possibly exhibit the bug (perhaps " | |
10167 "because the feature with the bug isn't present yet) and those where another " | |
10168 "problem masks the bug (as I discussed above)." | |
10169 msgstr "" | |
10170 | |
10171 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10172 #: ../en/ch09-undo.xml:1058 | |
10173 msgid "" | |
10174 "Even if you end up <quote>early</quote> by thousands of changesets or months " | |
10175 "of history, you will only add a handful of tests to the total number that " | |
10176 "<command role=\"hg-cmd\">hg bisect</command> must perform, thanks to its " | |
10177 "logarithmic behaviour." | |
10178 msgstr "" | |
10179 | |
10180 #. type: Content of: <book><chapter><title> | |
10181 #: ../en/ch10-hook.xml:5 | |
10182 msgid "Handling repository events with hooks" | |
10183 msgstr "使用钩子处理版本库事件" | |
10184 | |
10185 #. type: Content of: <book><chapter><para> | |
10186 #: ../en/ch10-hook.xml:7 | |
10187 msgid "" | |
10188 "Mercurial offers a powerful mechanism to let you perform automated actions in " | |
10189 "response to events that occur in a repository. In some cases, you can even " | |
10190 "control Mercurial's response to those events." | |
10191 msgstr "" | |
10192 | |
10193 #. type: Content of: <book><chapter><para> | |
10194 #: ../en/ch10-hook.xml:12 | |
10195 msgid "" | |
10196 "The name Mercurial uses for one of these actions is a <emphasis>hook</" | |
10197 "emphasis>. Hooks are called <quote>triggers</quote> in some revision control " | |
10198 "systems, but the two names refer to the same idea." | |
10199 msgstr "" | |
10200 | |
10201 #. type: Content of: <book><chapter><sect1><title> | |
10202 #: ../en/ch10-hook.xml:18 | |
10203 msgid "An overview of hooks in Mercurial" | |
10204 msgstr "" | |
10205 | |
10206 #. type: Content of: <book><chapter><sect1><para> | |
10207 #: ../en/ch10-hook.xml:20 | |
10208 msgid "" | |
10209 "Here is a brief list of the hooks that Mercurial supports. We will revisit " | |
10210 "each of these hooks in more detail later, in section <xref linkend=\"sec.hook." | |
10211 "ref\"/>." | |
10212 msgstr "" | |
10213 | |
10214 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
10215 #: ../en/ch10-hook.xml:25 | |
10216 msgid "" | |
10217 "<literal role=\"hook\">changegroup</literal>: This is run after a group of " | |
10218 "changesets has been brought into the repository from elsewhere." | |
10219 msgstr "" | |
10220 | |
10221 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
10222 #: ../en/ch10-hook.xml:29 | |
10223 msgid "" | |
10224 "<literal role=\"hook\">commit</literal>: This is run after a new changeset " | |
10225 "has been created in the local repository." | |
10226 msgstr "" | |
10227 | |
10228 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
10229 #: ../en/ch10-hook.xml:33 | |
10230 msgid "" | |
10231 "<literal role=\"hook\">incoming</literal>: This is run once for each new " | |
10232 "changeset that is brought into the repository from elsewhere. Notice the " | |
10233 "difference from <literal role=\"hook\">changegroup</literal>, which is run " | |
10234 "once per <emphasis>group</emphasis> of changesets brought in." | |
10235 msgstr "" | |
10236 | |
10237 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
10238 #: ../en/ch10-hook.xml:40 | |
10239 msgid "" | |
10240 "<literal role=\"hook\">outgoing</literal>: This is run after a group of " | |
10241 "changesets has been transmitted from this repository." | |
10242 msgstr "" | |
10243 | |
10244 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
10245 #: ../en/ch10-hook.xml:44 | |
10246 msgid "" | |
10247 "<literal role=\"hook\">prechangegroup</literal>: This is run before starting " | |
10248 "to bring a group of changesets into the repository." | |
10249 msgstr "" | |
10250 | |
10251 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
10252 #: ../en/ch10-hook.xml:49 | |
10253 msgid "" | |
10254 "<literal role=\"hook\">precommit</literal>: Controlling. This is run before " | |
10255 "starting a commit." | |
10256 msgstr "" | |
10257 | |
10258 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
10259 #: ../en/ch10-hook.xml:53 | |
10260 msgid "" | |
10261 "<literal role=\"hook\">preoutgoing</literal>: Controlling. This is run before " | |
10262 "starting to transmit a group of changesets from this repository." | |
10263 msgstr "" | |
10264 | |
10265 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
10266 #: ../en/ch10-hook.xml:58 | |
10267 msgid "" | |
10268 "<literal role=\"hook\">pretag</literal>: Controlling. This is run before " | |
10269 "creating a tag." | |
10270 msgstr "" | |
10271 | |
10272 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
10273 #: ../en/ch10-hook.xml:62 | |
10274 msgid "" | |
10275 "<literal role=\"hook\">pretxnchangegroup</literal>: Controlling. This is run " | |
10276 "after a group of changesets has been brought into the local repository from " | |
10277 "another, but before the transaction completes that will make the changes " | |
10278 "permanent in the repository." | |
10279 msgstr "" | |
10280 | |
10281 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
10282 #: ../en/ch10-hook.xml:70 | |
10283 msgid "" | |
10284 "<literal role=\"hook\">pretxncommit</literal>: Controlling. This is run after " | |
10285 "a new changeset has been created in the local repository, but before the " | |
10286 "transaction completes that will make it permanent." | |
10287 msgstr "" | |
10288 | |
10289 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
10290 #: ../en/ch10-hook.xml:76 | |
10291 msgid "" | |
10292 "<literal role=\"hook\">preupdate</literal>: Controlling. This is run before " | |
10293 "starting an update or merge of the working directory." | |
10294 msgstr "" | |
10295 | |
10296 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
10297 #: ../en/ch10-hook.xml:81 | |
10298 msgid "" | |
10299 "<literal role=\"hook\">tag</literal>: This is run after a tag is created." | |
10300 msgstr "" | |
10301 | |
10302 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
10303 #: ../en/ch10-hook.xml:85 | |
10304 msgid "" | |
10305 "<literal role=\"hook\">update</literal>: This is run after an update or merge " | |
10306 "of the working directory has finished." | |
10307 msgstr "" | |
10308 | |
10309 #. type: Content of: <book><chapter><sect1><para> | |
10310 #: ../en/ch10-hook.xml:90 | |
10311 msgid "" | |
10312 "Each of the hooks whose description begins with the word <quote>Controlling</" | |
10313 "quote> has the ability to determine whether an activity can proceed. If the " | |
10314 "hook succeeds, the activity may proceed; if it fails, the activity is either " | |
10315 "not permitted or undone, depending on the hook." | |
10316 msgstr "" | |
10317 | |
10318 #. type: Content of: <book><chapter><sect1><title> | |
10319 #: ../en/ch10-hook.xml:99 | |
10320 msgid "Hooks and security" | |
10321 msgstr "" | |
10322 | |
10323 #. type: Content of: <book><chapter><sect1><sect2><title> | |
10324 #: ../en/ch10-hook.xml:102 | |
10325 msgid "Hooks are run with your privileges" | |
10326 msgstr "" | |
10327 | |
10328 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10329 #: ../en/ch10-hook.xml:104 | |
10330 msgid "" | |
10331 "When you run a Mercurial command in a repository, and the command causes a " | |
10332 "hook to run, that hook runs on <emphasis>your</emphasis> system, under " | |
10333 "<emphasis>your</emphasis> user account, with <emphasis>your</emphasis> " | |
10334 "privilege level. Since hooks are arbitrary pieces of executable code, you " | |
10335 "should treat them with an appropriate level of suspicion. Do not install a " | |
10336 "hook unless you are confident that you know who created it and what it does." | |
10337 msgstr "" | |
10338 | |
10339 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10340 #: ../en/ch10-hook.xml:115 | |
10341 msgid "" | |
10342 "In some cases, you may be exposed to hooks that you did not install " | |
10343 "yourself. If you work with Mercurial on an unfamiliar system, Mercurial will " | |
10344 "run hooks defined in that system's global <filename role=\"special\"> /.hgrc</" | |
10345 "filename>\\ file." | |
10346 msgstr "" | |
10347 | |
10348 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10349 #: ../en/ch10-hook.xml:122 | |
10350 msgid "" | |
10351 "If you are working with a repository owned by another user, Mercurial can run " | |
10352 "hooks defined in that user's repository, but it will still run them as " | |
10353 "<quote>you</quote>. For example, if you <command role=\"hg-cmd\">hg pull</" | |
10354 "command> from that repository, and its <filename role=\"special\">.hg/hgrc</" | |
10355 "filename> defines a local <literal role=\"hook\">outgoing</literal> hook, " | |
10356 "that hook will run under your user account, even though you don't own that " | |
10357 "repository." | |
10358 msgstr "" | |
10359 | |
10360 #. type: Content of: <book><chapter><sect1><sect2><note><para> | |
10361 #: ../en/ch10-hook.xml:134 | |
10362 msgid "" | |
10363 "This only applies if you are pulling from a repository on a local or network " | |
10364 "filesystem. If you're pulling over http or ssh, any <literal role=\"hook" | |
10365 "\">outgoing</literal> hook will run under whatever account is executing the " | |
10366 "server process, on the server." | |
10367 msgstr "" | |
10368 | |
10369 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10370 #: ../en/ch10-hook.xml:142 | |
10371 msgid "" | |
10372 "XXX To see what hooks are defined in a repository, use the <command role=\"hg-" | |
10373 "cmd\">hg config hooks</command> command. If you are working in one " | |
10374 "repository, but talking to another that you do not own (e.g. using <command " | |
10375 "role=\"hg-cmd\">hg pull</command> or <command role=\"hg-cmd\">hg incoming</" | |
10376 "command>), remember that it is the other repository's hooks you should be " | |
10377 "checking, not your own." | |
10378 msgstr "" | |
10379 | |
10380 #. type: Content of: <book><chapter><sect1><sect2><title> | |
10381 #: ../en/ch10-hook.xml:153 | |
10382 msgid "Hooks do not propagate" | |
10383 msgstr "" | |
10384 | |
10385 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10386 #: ../en/ch10-hook.xml:155 | |
10387 msgid "" | |
10388 "In Mercurial, hooks are not revision controlled, and do not propagate when " | |
10389 "you clone, or pull from, a repository. The reason for this is simple: a hook " | |
10390 "is a completely arbitrary piece of executable code. It runs under your user " | |
10391 "identity, with your privilege level, on your machine." | |
10392 msgstr "" | |
10393 | |
10394 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10395 #: ../en/ch10-hook.xml:162 | |
10396 msgid "" | |
10397 "It would be extremely reckless for any distributed revision control system to " | |
10398 "implement revision-controlled hooks, as this would offer an easily " | |
10399 "exploitable way to subvert the accounts of users of the revision control " | |
10400 "system." | |
10401 msgstr "" | |
10402 | |
10403 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10404 #: ../en/ch10-hook.xml:168 | |
10405 msgid "" | |
10406 "Since Mercurial does not propagate hooks, if you are collaborating with other " | |
10407 "people on a common project, you should not assume that they are using the " | |
10408 "same Mercurial hooks as you are, or that theirs are correctly configured. " | |
10409 "You should document the hooks you expect people to use." | |
10410 msgstr "" | |
10411 | |
10412 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10413 #: ../en/ch10-hook.xml:175 | |
10414 msgid "" | |
10415 "In a corporate intranet, this is somewhat easier to control, as you can for " | |
10416 "example provide a <quote>standard</quote> installation of Mercurial on an NFS " | |
10417 "filesystem, and use a site-wide <filename role=\"special\"> /.hgrc</filename>" | |
10418 "\\ file to define hooks that all users will see. However, this too has its " | |
10419 "limits; see below." | |
10420 msgstr "" | |
10421 | |
10422 #. type: Content of: <book><chapter><sect1><sect2><title> | |
10423 #: ../en/ch10-hook.xml:185 | |
10424 msgid "Hooks can be overridden" | |
10425 msgstr "" | |
10426 | |
10427 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10428 #: ../en/ch10-hook.xml:187 | |
10429 msgid "" | |
10430 "Mercurial allows you to override a hook definition by redefining the hook. " | |
10431 "You can disable it by setting its value to the empty string, or change its " | |
10432 "behaviour as you wish." | |
10433 msgstr "" | |
10434 | |
10435 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10436 #: ../en/ch10-hook.xml:192 | |
10437 msgid "" | |
10438 "If you deploy a system- or site-wide <filename role=\"special\"> /.hgrc</" | |
10439 "filename>\\ file that defines some hooks, you should thus understand that " | |
10440 "your users can disable or override those hooks." | |
10441 msgstr "" | |
10442 | |
10443 #. type: Content of: <book><chapter><sect1><sect2><title> | |
10444 #: ../en/ch10-hook.xml:200 | |
10445 msgid "Ensuring that critical hooks are run" | |
10446 msgstr "" | |
10447 | |
10448 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10449 #: ../en/ch10-hook.xml:202 | |
10450 msgid "" | |
10451 "Sometimes you may want to enforce a policy that you do not want others to be " | |
10452 "able to work around. For example, you may have a requirement that every " | |
10453 "changeset must pass a rigorous set of tests. Defining this requirement via a " | |
10454 "hook in a site-wide <filename role=\"special\"> /.hgrc</filename>\\ won't " | |
10455 "work for remote users on laptops, and of course local users can subvert it at " | |
10456 "will by overriding the hook." | |
10457 msgstr "" | |
10458 | |
10459 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10460 #: ../en/ch10-hook.xml:211 | |
10461 msgid "" | |
10462 "Instead, you can set up your policies for use of Mercurial so that people are " | |
10463 "expected to propagate changes through a well-known <quote>canonical</quote> " | |
10464 "server that you have locked down and configured appropriately." | |
10465 msgstr "" | |
10466 | |
10467 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10468 #: ../en/ch10-hook.xml:217 | |
10469 msgid "" | |
10470 "One way to do this is via a combination of social engineering and " | |
10471 "technology. Set up a restricted-access account; users can push changes over " | |
10472 "the network to repositories managed by this account, but they cannot log into " | |
10473 "the account and run normal shell commands. In this scenario, a user can " | |
10474 "commit a changeset that contains any old garbage they want." | |
10475 msgstr "" | |
10476 | |
10477 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10478 #: ../en/ch10-hook.xml:226 | |
10479 msgid "" | |
10480 "When someone pushes a changeset to the server that everyone pulls from, the " | |
10481 "server will test the changeset before it accepts it as permanent, and reject " | |
10482 "it if it fails to pass the test suite. If people only pull changes from this " | |
10483 "filtering server, it will serve to ensure that all changes that people pull " | |
10484 "have been automatically vetted." | |
10485 msgstr "" | |
10486 | |
10487 #. type: Content of: <book><chapter><sect1><title> | |
10488 #: ../en/ch10-hook.xml:237 | |
10489 msgid "Care with <literal>pretxn</literal> hooks in a shared-access repository" | |
10490 msgstr "" | |
10491 | |
10492 #. type: Content of: <book><chapter><sect1><para> | |
10493 #: ../en/ch10-hook.xml:240 | |
10494 msgid "" | |
10495 "If you want to use hooks to do some automated work in a repository that a " | |
10496 "number of people have shared access to, you need to be careful in how you do " | |
10497 "this." | |
10498 msgstr "" | |
10499 | |
10500 #. type: Content of: <book><chapter><sect1><para> | |
10501 #: ../en/ch10-hook.xml:245 | |
10502 msgid "" | |
10503 "Mercurial only locks a repository when it is writing to the repository, and " | |
10504 "only the parts of Mercurial that write to the repository pay attention to " | |
10505 "locks. Write locks are necessary to prevent multiple simultaneous writers " | |
10506 "from scribbling on each other's work, corrupting the repository." | |
10507 msgstr "" | |
10508 | |
10509 #. type: Content of: <book><chapter><sect1><para> | |
10510 #: ../en/ch10-hook.xml:252 | |
10511 msgid "" | |
10512 "Because Mercurial is careful with the order in which it reads and writes " | |
10513 "data, it does not need to acquire a lock when it wants to read data from the " | |
10514 "repository. The parts of Mercurial that read from the repository never pay " | |
10515 "attention to locks. This lockless reading scheme greatly increases " | |
10516 "performance and concurrency." | |
10517 msgstr "" | |
10518 | |
10519 #. type: Content of: <book><chapter><sect1><para> | |
10520 #: ../en/ch10-hook.xml:260 | |
10521 msgid "" | |
10522 "With great performance comes a trade-off, though, one which has the potential " | |
10523 "to cause you trouble unless you're aware of it. To describe this requires a " | |
10524 "little detail about how Mercurial adds changesets to a repository and reads " | |
10525 "those changes." | |
10526 msgstr "" | |
10527 | |
10528 #. type: Content of: <book><chapter><sect1><para> | |
10529 #: ../en/ch10-hook.xml:267 | |
10530 msgid "" | |
10531 "When Mercurial <emphasis>writes</emphasis> metadata, it writes it straight " | |
10532 "into the destination file. It writes file data first, then manifest data " | |
10533 "(which contains pointers to the new file data), then changelog data (which " | |
10534 "contains pointers to the new manifest data). Before the first write to each " | |
10535 "file, it stores a record of where the end of the file was in its transaction " | |
10536 "log. If the transaction must be rolled back, Mercurial simply truncates each " | |
10537 "file back to the size it was before the transaction began." | |
10538 msgstr "" | |
10539 | |
10540 #. type: Content of: <book><chapter><sect1><para> | |
10541 #: ../en/ch10-hook.xml:278 | |
10542 msgid "" | |
10543 "When Mercurial <emphasis>reads</emphasis> metadata, it reads the changelog " | |
10544 "first, then everything else. Since a reader will only access parts of the " | |
10545 "manifest or file metadata that it can see in the changelog, it can never see " | |
10546 "partially written data." | |
10547 msgstr "" | |
10548 | |
10549 #. type: Content of: <book><chapter><sect1><para> | |
10550 #: ../en/ch10-hook.xml:284 | |
10551 msgid "" | |
10552 "Some controlling hooks (<literal role=\"hook\">pretxncommit</literal> and " | |
10553 "<literal role=\"hook\">pretxnchangegroup</literal>) run when a transaction is " | |
10554 "almost complete. All of the metadata has been written, but Mercurial can " | |
10555 "still roll the transaction back and cause the newly-written data to disappear." | |
10556 msgstr "" | |
10557 | |
10558 #. type: Content of: <book><chapter><sect1><para> | |
10559 #: ../en/ch10-hook.xml:292 | |
10560 msgid "" | |
10561 "If one of these hooks runs for long, it opens a window of time during which a " | |
10562 "reader can see the metadata for changesets that are not yet permanent, and " | |
10563 "should not be thought of as <quote>really there</quote>. The longer the hook " | |
10564 "runs, the longer that window is open." | |
10565 msgstr "" | |
10566 | |
10567 #. type: Content of: <book><chapter><sect1><sect2><title> | |
10568 #: ../en/ch10-hook.xml:300 | |
10569 msgid "The problem illustrated" | |
10570 msgstr "" | |
10571 | |
10572 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10573 #: ../en/ch10-hook.xml:302 | |
10574 msgid "" | |
10575 "In principle, a good use for the <literal role=\"hook\">pretxnchangegroup</" | |
10576 "literal> hook would be to automatically build and test incoming changes " | |
10577 "before they are accepted into a central repository. This could let you " | |
10578 "guarantee that nobody can push changes to this repository that <quote>break " | |
10579 "the build</quote>. But if a client can pull changes while they're being " | |
10580 "tested, the usefulness of the test is zero; an unsuspecting someone can pull " | |
10581 "untested changes, potentially breaking their build." | |
10582 msgstr "" | |
10583 | |
10584 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10585 #: ../en/ch10-hook.xml:313 | |
10586 msgid "" | |
10587 "The safest technological answer to this challenge is to set up such a " | |
10588 "<quote>gatekeeper</quote> repository as <emphasis>unidirectional</emphasis>. " | |
10589 "Let it take changes pushed in from the outside, but do not allow anyone to " | |
10590 "pull changes from it (use the <literal role=\"hook\">preoutgoing</literal> " | |
10591 "hook to lock it down). Configure a <literal role=\"hook\">changegroup</" | |
10592 "literal> hook so that if a build or test succeeds, the hook will push the new " | |
10593 "changes out to another repository that people <emphasis>can</emphasis> pull " | |
10594 "from." | |
10595 msgstr "" | |
10596 | |
10597 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10598 #: ../en/ch10-hook.xml:325 | |
10599 msgid "" | |
10600 "In practice, putting a centralised bottleneck like this in place is not often " | |
10601 "a good idea, and transaction visibility has nothing to do with the problem. " | |
10602 "As the size of a project&emdash;and the time it takes to build and " | |
10603 "test&emdash;grows, you rapidly run into a wall with this <quote>try before " | |
10604 "you buy</quote> approach, where you have more changesets to test than time in " | |
10605 "which to deal with them. The inevitable result is frustration on the part of " | |
10606 "all involved." | |
10607 msgstr "" | |
10608 | |
10609 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10610 #: ../en/ch10-hook.xml:336 | |
10611 msgid "" | |
10612 "An approach that scales better is to get people to build and test before they " | |
10613 "push, then run automated builds and tests centrally <emphasis>after</" | |
10614 "emphasis> a push, to be sure all is well. The advantage of this approach is " | |
10615 "that it does not impose a limit on the rate at which the repository can " | |
10616 "accept changes." | |
10617 msgstr "" | |
10618 | |
10619 #. type: Content of: <book><chapter><sect1><title> | |
10620 #: ../en/ch10-hook.xml:347 | |
10621 msgid "A short tutorial on using hooks" | |
10622 msgstr "" | |
10623 | |
10624 #. type: Content of: <book><chapter><sect1><para> | |
10625 #: ../en/ch10-hook.xml:349 | |
10626 msgid "" | |
10627 "It is easy to write a Mercurial hook. Let's start with a hook that runs when " | |
10628 "you finish a <command role=\"hg-cmd\">hg commit</command>, and simply prints " | |
10629 "the hash of the changeset you just created. The hook is called <literal role=" | |
10630 "\"hook\">commit</literal>." | |
10631 msgstr "" | |
10632 | |
10633 #. type: Content of: <book><chapter><sect1><para> | |
10634 #: ../en/ch10-hook.xml:356 | |
10635 msgid "All hooks follow the pattern in this example." | |
10636 msgstr "" | |
10637 | |
10638 #. type: Content of: <book><chapter><sect1><para> | |
10639 #: ../en/ch10-hook.xml:360 | |
10640 msgid "" | |
10641 "You add an entry to the <literal role=\"rc-hooks\">hooks</literal> section of " | |
10642 "your <filename role=\"special\"> /.hgrc</filename>. On the left is the name " | |
10643 "of the event to trigger on; on the right is the action to take. As you can " | |
10644 "see, you can run an arbitrary shell command in a hook. Mercurial passes " | |
10645 "extra information to the hook using environment variables (look for " | |
10646 "<envar>HG_NODE</envar> in the example)." | |
10647 msgstr "" | |
10648 | |
10649 #. type: Content of: <book><chapter><sect1><sect2><title> | |
10650 #: ../en/ch10-hook.xml:370 | |
10651 msgid "Performing multiple actions per event" | |
10652 msgstr "" | |
10653 | |
10654 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10655 #: ../en/ch10-hook.xml:372 | |
10656 msgid "" | |
10657 "Quite often, you will want to define more than one hook for a particular kind " | |
10658 "of event, as shown below." | |
10659 msgstr "" | |
10660 | |
10661 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10662 #: ../en/ch10-hook.xml:377 | |
10663 msgid "" | |
10664 "Mercurial lets you do this by adding an <emphasis>extension</emphasis> to the " | |
10665 "end of a hook's name. You extend a hook's name by giving the name of the " | |
10666 "hook, followed by a full stop (the <quote><literal>.</literal></quote> " | |
10667 "character), followed by some more text of your choosing. For example, " | |
10668 "Mercurial will run both <literal>commit.foo</literal> and <literal>commit." | |
10669 "bar</literal> when the <literal>commit</literal> event occurs." | |
10670 msgstr "" | |
10671 | |
10672 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10673 #: ../en/ch10-hook.xml:388 | |
10674 msgid "" | |
10675 "To give a well-defined order of execution when there are multiple hooks " | |
10676 "defined for an event, Mercurial sorts hooks by extension, and executes the " | |
10677 "hook commands in this sorted order. In the above example, it will execute " | |
10678 "<literal>commit.bar</literal> before <literal>commit.foo</literal>, and " | |
10679 "<literal>commit</literal> before both." | |
10680 msgstr "" | |
10681 | |
10682 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10683 #: ../en/ch10-hook.xml:397 | |
10684 msgid "" | |
10685 "It is a good idea to use a somewhat descriptive extension when you define a " | |
10686 "new hook. This will help you to remember what the hook was for. If the hook " | |
10687 "fails, you'll get an error message that contains the hook name and extension, " | |
10688 "so using a descriptive extension could give you an immediate hint as to why " | |
10689 "the hook failed (see section <xref linkend=\"sec.hook.perm\"/> for an " | |
10690 "example)." | |
10691 msgstr "" | |
10692 | |
10693 #. type: Content of: <book><chapter><sect1><sect2><title> | |
10694 #: ../en/ch10-hook.xml:408 | |
10695 msgid "Controlling whether an activity can proceed" | |
10696 msgstr "" | |
10697 | |
10698 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10699 #: ../en/ch10-hook.xml:410 | |
10700 msgid "" | |
10701 "In our earlier examples, we used the <literal role=\"hook\">commit</literal> " | |
10702 "hook, which is run after a commit has completed. This is one of several " | |
10703 "Mercurial hooks that run after an activity finishes. Such hooks have no way " | |
10704 "of influencing the activity itself." | |
10705 msgstr "" | |
10706 | |
10707 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10708 #: ../en/ch10-hook.xml:417 | |
10709 msgid "" | |
10710 "Mercurial defines a number of events that occur before an activity starts; or " | |
10711 "after it starts, but before it finishes. Hooks that trigger on these events " | |
10712 "have the added ability to choose whether the activity can continue, or will " | |
10713 "abort." | |
10714 msgstr "" | |
10715 | |
10716 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10717 #: ../en/ch10-hook.xml:423 | |
10718 msgid "" | |
10719 "The <literal role=\"hook\">pretxncommit</literal> hook runs after a commit " | |
10720 "has all but completed. In other words, the metadata representing the " | |
10721 "changeset has been written out to disk, but the transaction has not yet been " | |
10722 "allowed to complete. The <literal role=\"hook\">pretxncommit</literal> hook " | |
10723 "has the ability to decide whether the transaction can complete, or must be " | |
10724 "rolled back." | |
10725 msgstr "" | |
10726 | |
10727 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10728 #: ../en/ch10-hook.xml:432 | |
10729 msgid "" | |
10730 "If the <literal role=\"hook\">pretxncommit</literal> hook exits with a status " | |
10731 "code of zero, the transaction is allowed to complete; the commit finishes; " | |
10732 "and the <literal role=\"hook\">commit</literal> hook is run. If the <literal " | |
10733 "role=\"hook\">pretxncommit</literal> hook exits with a non-zero status code, " | |
10734 "the transaction is rolled back; the metadata representing the changeset is " | |
10735 "erased; and the <literal role=\"hook\">commit</literal> hook is not run." | |
10736 msgstr "" | |
10737 | |
10738 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10739 #: ../en/ch10-hook.xml:444 | |
10740 msgid "" | |
10741 "The hook in the example above checks that a commit comment contains a bug " | |
10742 "ID. If it does, the commit can complete. If not, the commit is rolled back." | |
10743 msgstr "" | |
10744 | |
10745 #. type: Content of: <book><chapter><sect1><title> | |
10746 #: ../en/ch10-hook.xml:452 | |
10747 msgid "Writing your own hooks" | |
10748 msgstr "" | |
10749 | |
10750 #. type: Content of: <book><chapter><sect1><para> | |
10751 #: ../en/ch10-hook.xml:454 | |
10752 msgid "" | |
10753 "When you are writing a hook, you might find it useful to run Mercurial either " | |
10754 "with the <option role=\"hg-opt-global\">-v</option> option, or the <envar " | |
10755 "role=\"rc-item-ui\">verbose</envar> config item set to <quote>true</quote>. " | |
10756 "When you do so, Mercurial will print a message before it calls each hook." | |
10757 msgstr "" | |
10758 | |
10759 #. type: Content of: <book><chapter><sect1><sect2><title> | |
10760 #: ../en/ch10-hook.xml:463 | |
10761 msgid "Choosing how your hook should run" | |
10762 msgstr "" | |
10763 | |
10764 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10765 #: ../en/ch10-hook.xml:465 | |
10766 msgid "" | |
10767 "You can write a hook either as a normal program&emdash;typically a shell " | |
10768 "script&emdash;or as a Python function that is executed within the Mercurial " | |
10769 "process." | |
10770 msgstr "" | |
10771 | |
10772 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10773 #: ../en/ch10-hook.xml:470 | |
10774 msgid "" | |
10775 "Writing a hook as an external program has the advantage that it requires no " | |
10776 "knowledge of Mercurial's internals. You can call normal Mercurial commands " | |
10777 "to get any added information you need. The trade-off is that external hooks " | |
10778 "are slower than in-process hooks." | |
10779 msgstr "" | |
10780 | |
10781 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10782 #: ../en/ch10-hook.xml:477 | |
10783 msgid "" | |
10784 "An in-process Python hook has complete access to the Mercurial API, and does " | |
10785 "not <quote>shell out</quote> to another process, so it is inherently faster " | |
10786 "than an external hook. It is also easier to obtain much of the information " | |
10787 "that a hook requires by using the Mercurial API than by running Mercurial " | |
10788 "commands." | |
10789 msgstr "" | |
10790 | |
10791 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10792 #: ../en/ch10-hook.xml:485 | |
10793 msgid "" | |
10794 "If you are comfortable with Python, or require high performance, writing your " | |
10795 "hooks in Python may be a good choice. However, when you have a " | |
10796 "straightforward hook to write and you don't need to care about performance " | |
10797 "(probably the majority of hooks), a shell script is perfectly fine." | |
10798 msgstr "" | |
10799 | |
10800 #. type: Content of: <book><chapter><sect1><sect2><title> | |
10801 #: ../en/ch10-hook.xml:494 | |
10802 msgid "Hook parameters" | |
10803 msgstr "" | |
10804 | |
10805 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10806 #: ../en/ch10-hook.xml:496 | |
10807 msgid "" | |
10808 "Mercurial calls each hook with a set of well-defined parameters. In Python, " | |
10809 "a parameter is passed as a keyword argument to your hook function. For an " | |
10810 "external program, a parameter is passed as an environment variable." | |
10811 msgstr "" | |
10812 | |
10813 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10814 #: ../en/ch10-hook.xml:502 | |
10815 msgid "" | |
10816 "Whether your hook is written in Python or as a shell script, the hook-" | |
10817 "specific parameter names and values will be the same. A boolean parameter " | |
10818 "will be represented as a boolean value in Python, but as the number 1 (for " | |
10819 "<quote>true</quote>) or 0 (for <quote>false</quote>) as an environment " | |
10820 "variable for an external hook. If a hook parameter is named <literal>foo</" | |
10821 "literal>, the keyword argument for a Python hook will also be named " | |
10822 "<literal>foo</literal>, while the environment variable for an external hook " | |
10823 "will be named <literal>HG_FOO</literal>." | |
10824 msgstr "" | |
10825 | |
10826 #. type: Content of: <book><chapter><sect1><sect2><title> | |
10827 #: ../en/ch10-hook.xml:516 | |
10828 msgid "Hook return values and activity control" | |
10829 msgstr "" | |
10830 | |
10831 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10832 #: ../en/ch10-hook.xml:518 | |
10833 msgid "" | |
10834 "A hook that executes successfully must exit with a status of zero if " | |
10835 "external, or return boolean <quote>false</quote> if in-process. Failure is " | |
10836 "indicated with a non-zero exit status from an external hook, or an in-process " | |
10837 "hook returning boolean <quote>true</quote>. If an in-process hook raises an " | |
10838 "exception, the hook is considered to have failed." | |
10839 msgstr "" | |
10840 | |
10841 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10842 #: ../en/ch10-hook.xml:526 | |
10843 msgid "" | |
10844 "For a hook that controls whether an activity can proceed, zero/false means " | |
10845 "<quote>allow</quote>, while non-zero/true/exception means <quote>deny</quote>." | |
10846 msgstr "" | |
10847 | |
10848 #. type: Content of: <book><chapter><sect1><sect2><title> | |
10849 #: ../en/ch10-hook.xml:533 | |
10850 msgid "Writing an external hook" | |
10851 msgstr "" | |
10852 | |
10853 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10854 #: ../en/ch10-hook.xml:535 | |
10855 msgid "" | |
10856 "When you define an external hook in your <filename role=\"special\"> /.hgrc</" | |
10857 "filename>\\ and the hook is run, its value is passed to your shell, which " | |
10858 "interprets it. This means that you can use normal shell constructs in the " | |
10859 "body of the hook." | |
10860 msgstr "" | |
10861 | |
10862 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10863 #: ../en/ch10-hook.xml:542 | |
10864 msgid "" | |
10865 "An executable hook is always run with its current directory set to a " | |
10866 "repository's root directory." | |
10867 msgstr "" | |
10868 | |
10869 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10870 #: ../en/ch10-hook.xml:546 | |
10871 msgid "" | |
10872 "Each hook parameter is passed in as an environment variable; the name is " | |
10873 "upper-cased, and prefixed with the string <quote><literal>HG_</literal></" | |
10874 "quote>." | |
10875 msgstr "" | |
10876 | |
10877 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10878 #: ../en/ch10-hook.xml:551 | |
10879 msgid "" | |
10880 "With the exception of hook parameters, Mercurial does not set or modify any " | |
10881 "environment variables when running a hook. This is useful to remember if you " | |
10882 "are writing a site-wide hook that may be run by a number of different users " | |
10883 "with differing environment variables set. In multi-user situations, you " | |
10884 "should not rely on environment variables being set to the values you have in " | |
10885 "your environment when testing the hook." | |
10886 msgstr "" | |
10887 | |
10888 #. type: Content of: <book><chapter><sect1><sect2><title> | |
10889 #: ../en/ch10-hook.xml:562 | |
10890 msgid "Telling Mercurial to use an in-process hook" | |
10891 msgstr "" | |
10892 | |
10893 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10894 #: ../en/ch10-hook.xml:564 | |
10895 msgid "" | |
10896 "The <filename role=\"special\"> /.hgrc</filename>\\ syntax for defining an in-" | |
10897 "process hook is slightly different than for an executable hook. The value of " | |
10898 "the hook must start with the text <quote><literal>python:</literal></quote>, " | |
10899 "and continue with the fully-qualified name of a callable object to use as the " | |
10900 "hook's value." | |
10901 msgstr "" | |
10902 | |
10903 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10904 #: ../en/ch10-hook.xml:572 | |
10905 msgid "" | |
10906 "The module in which a hook lives is automatically imported when a hook is " | |
10907 "run. So long as you have the module name and <envar>PYTHONPATH</envar> " | |
10908 "right, it should <quote>just work</quote>." | |
10909 msgstr "" | |
10910 | |
10911 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10912 #: ../en/ch10-hook.xml:578 | |
10913 msgid "" | |
10914 "The following <filename role=\"special\"> /.hgrc</filename>\\ example snippet " | |
10915 "illustrates the syntax and meaning of the notions we just described." | |
10916 msgstr "" | |
10917 | |
10918 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10919 #: ../en/ch10-hook.xml:584 | |
10920 msgid "" | |
10921 "When Mercurial runs the <literal>commit.example</literal> hook, it imports " | |
10922 "<literal>mymodule.submodule</literal>, looks for the callable object named " | |
10923 "<literal>myhook</literal>, and calls it." | |
10924 msgstr "" | |
10925 | |
10926 #. type: Content of: <book><chapter><sect1><sect2><title> | |
10927 #: ../en/ch10-hook.xml:592 | |
10928 msgid "Writing an in-process hook" | |
10929 msgstr "" | |
10930 | |
10931 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10932 #: ../en/ch10-hook.xml:594 | |
10933 msgid "" | |
10934 "The simplest in-process hook does nothing, but illustrates the basic shape of " | |
10935 "the hook API:" | |
10936 msgstr "" | |
10937 | |
10938 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10939 #: ../en/ch10-hook.xml:599 | |
10940 msgid "" | |
10941 "The first argument to a Python hook is always a <literal role=\"py-mod-" | |
10942 "mercurial.ui\">ui</literal> object. The second is a repository object; at " | |
10943 "the moment, it is always an instance of <literal role=\"py-mod-mercurial." | |
10944 "localrepo\">localrepository</literal>. Following these two arguments are " | |
10945 "other keyword arguments. Which ones are passed in depends on the hook being " | |
10946 "called, but a hook can ignore arguments it doesn't care about by dropping " | |
10947 "them into a keyword argument dict, as with <literal>**kwargs</literal> above." | |
10948 msgstr "" | |
10949 | |
10950 #. type: Content of: <book><chapter><sect1><title> | |
10951 #: ../en/ch10-hook.xml:614 | |
10952 msgid "Some hook examples" | |
10953 msgstr "" | |
10954 | |
10955 #. type: Content of: <book><chapter><sect1><sect2><title> | |
10956 #: ../en/ch10-hook.xml:617 | |
10957 msgid "Writing meaningful commit messages" | |
10958 msgstr "" | |
10959 | |
10960 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10961 #: ../en/ch10-hook.xml:619 | |
10962 msgid "" | |
10963 "It's hard to imagine a useful commit message being very short. The simple " | |
10964 "<literal role=\"hook\">pretxncommit</literal> hook of the example below will " | |
10965 "prevent you from committing a changeset with a message that is less than ten " | |
10966 "bytes long." | |
10967 msgstr "" | |
10968 | |
10969 #. type: Content of: <book><chapter><sect1><sect2><title> | |
10970 #: ../en/ch10-hook.xml:629 | |
10971 msgid "Checking for trailing whitespace" | |
10972 msgstr "" | |
10973 | |
10974 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10975 #: ../en/ch10-hook.xml:631 | |
10976 msgid "" | |
10977 "An interesting use of a commit-related hook is to help you to write cleaner " | |
10978 "code. A simple example of <quote>cleaner code</quote> is the dictum that a " | |
10979 "change should not add any new lines of text that contain <quote>trailing " | |
10980 "whitespace</quote>. Trailing whitespace is a series of space and tab " | |
10981 "characters at the end of a line of text. In most cases, trailing whitespace " | |
10982 "is unnecessary, invisible noise, but it is occasionally problematic, and " | |
10983 "people often prefer to get rid of it." | |
10984 msgstr "" | |
10985 | |
10986 #. type: Content of: <book><chapter><sect1><sect2><para> | |
10987 #: ../en/ch10-hook.xml:642 | |
10988 msgid "" | |
10989 "You can use either the <literal role=\"hook\">precommit</literal> or <literal " | |
10990 "role=\"hook\">pretxncommit</literal> hook to tell whether you have a trailing " | |
10991 "whitespace problem. If you use the <literal role=\"hook\">precommit</" | |
10992 "literal> hook, the hook will not know which files you are committing, so it " | |
10993 "will have to check every modified file in the repository for trailing white " | |
10994 "space. If you want to commit a change to just the file <filename>foo</" | |
10995 "filename>, but the file <filename>bar</filename> contains trailing " | |
10996 "whitespace, doing a check in the <literal role=\"hook\">precommit</literal> " | |
10997 "hook will prevent you from committing <filename>foo</filename> due to the " | |
10998 "problem with <filename>bar</filename>. This doesn't seem right." | |
10999 msgstr "" | |
11000 | |
11001 #. type: Content of: <book><chapter><sect1><sect2><para> | |
11002 #: ../en/ch10-hook.xml:658 | |
11003 msgid "" | |
11004 "Should you choose the <literal role=\"hook\">pretxncommit</literal> hook, the " | |
11005 "check won't occur until just before the transaction for the commit " | |
11006 "completes. This will allow you to check for problems only the exact files " | |
11007 "that are being committed. However, if you entered the commit message " | |
11008 "interactively and the hook fails, the transaction will roll back; you'll have " | |
11009 "to re-enter the commit message after you fix the trailing whitespace and run " | |
11010 "<command role=\"hg-cmd\">hg commit</command> again." | |
11011 msgstr "" | |
11012 | |
11013 #. type: Content of: <book><chapter><sect1><sect2><para> | |
11014 #: ../en/ch10-hook.xml:671 | |
11015 msgid "" | |
11016 "In this example, we introduce a simple <literal role=\"hook\">pretxncommit</" | |
11017 "literal> hook that checks for trailing whitespace. This hook is short, but " | |
11018 "not very helpful. It exits with an error status if a change adds a line with " | |
11019 "trailing whitespace to any file, but does not print any information that " | |
11020 "might help us to identify the offending file or line. It also has the nice " | |
11021 "property of not paying attention to unmodified lines; only lines that " | |
11022 "introduce new trailing whitespace cause problems." | |
11023 msgstr "" | |
11024 | |
11025 #. type: Content of: <book><chapter><sect1><sect2><para> | |
11026 #: ../en/ch10-hook.xml:682 | |
11027 msgid "" | |
11028 "The above version is much more complex, but also more useful. It parses a " | |
11029 "unified diff to see if any lines add trailing whitespace, and prints the name " | |
11030 "of the file and the line number of each such occurrence. Even better, if the " | |
11031 "change adds trailing whitespace, this hook saves the commit comment and " | |
11032 "prints the name of the save file before exiting and telling Mercurial to roll " | |
11033 "the transaction back, so you can use the <option role=\"hg-opt-commit\">-l " | |
11034 "filename</option> option to <command role=\"hg-cmd\">hg commit</command> to " | |
11035 "reuse the saved commit message once you've corrected the problem." | |
11036 msgstr "" | |
11037 | |
11038 #. type: Content of: <book><chapter><sect1><sect2><para> | |
11039 #: ../en/ch10-hook.xml:696 | |
11040 msgid "" | |
11041 "As a final aside, note in the example above the use of <command>perl</" | |
11042 "command>'s in-place editing feature to get rid of trailing whitespace from a " | |
11043 "file. This is concise and useful enough that I will reproduce it here." | |
11044 msgstr "" | |
11045 | |
11046 #. type: Content of: <book><chapter><sect1><title> | |
11047 #: ../en/ch10-hook.xml:706 | |
11048 msgid "Bundled hooks" | |
11049 msgstr "" | |
11050 | |
11051 #. type: Content of: <book><chapter><sect1><para> | |
11052 #: ../en/ch10-hook.xml:708 | |
11053 msgid "" | |
11054 "Mercurial ships with several bundled hooks. You can find them in the " | |
11055 "<filename class=\"directory\">hgext</filename> directory of a Mercurial " | |
11056 "source tree. If you are using a Mercurial binary package, the hooks will be " | |
11057 "located in the <filename class=\"directory\">hgext</filename> directory of " | |
11058 "wherever your package installer put Mercurial." | |
11059 msgstr "" | |
11060 | |
11061 #. type: Content of: <book><chapter><sect1><sect2><title> | |
11062 #: ../en/ch10-hook.xml:717 | |
11063 msgid "" | |
11064 "<literal role=\"hg-ext\">acl</literal>&emdash;access control for parts of a " | |
11065 "repository" | |
11066 msgstr "" | |
11067 | |
11068 #. type: Content of: <book><chapter><sect1><sect2><para> | |
11069 #: ../en/ch10-hook.xml:720 | |
11070 msgid "" | |
11071 "The <literal role=\"hg-ext\">acl</literal> extension lets you control which " | |
11072 "remote users are allowed to push changesets to a networked server. You can " | |
11073 "protect any portion of a repository (including the entire repo), so that a " | |
11074 "specific remote user can push changes that do not affect the protected " | |
11075 "portion." | |
11076 msgstr "" | |
11077 | |
11078 #. type: Content of: <book><chapter><sect1><sect2><para> | |
11079 #: ../en/ch10-hook.xml:728 | |
11080 msgid "" | |
11081 "This extension implements access control based on the identity of the user " | |
11082 "performing a push, <emphasis>not</emphasis> on who committed the changesets " | |
11083 "they're pushing. It makes sense to use this hook only if you have a locked-" | |
11084 "down server environment that authenticates remote users, and you want to be " | |
11085 "sure that only specific users are allowed to push changes to that server." | |
11086 msgstr "" | |
11087 | |
11088 #. type: Content of: <book><chapter><sect1><sect2><sect3><title> | |
11089 #: ../en/ch10-hook.xml:738 | |
11090 msgid "Configuring the <literal role=\"hook\">acl</literal> hook" | |
11091 msgstr "" | |
11092 | |
11093 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
11094 #: ../en/ch10-hook.xml:741 | |
11095 msgid "" | |
11096 "In order to manage incoming changesets, the <literal role=\"hg-ext\">acl</" | |
11097 "literal> hook must be used as a <literal role=\"hook\">pretxnchangegroup</" | |
11098 "literal> hook. This lets it see which files are modified by each incoming " | |
11099 "changeset, and roll back a group of changesets if they modify " | |
11100 "<quote>forbidden</quote> files. Example:" | |
11101 msgstr "" | |
11102 | |
11103 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
11104 #: ../en/ch10-hook.xml:751 | |
11105 msgid "" | |
11106 "The <literal role=\"hg-ext\">acl</literal> extension is configured using " | |
11107 "three sections." | |
11108 msgstr "" | |
11109 | |
11110 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
11111 #: ../en/ch10-hook.xml:755 | |
11112 msgid "" | |
11113 "The <literal role=\"rc-acl\">acl</literal> section has only one entry, <envar " | |
11114 "role=\"rc-item-acl\">sources</envar>, which lists the sources of incoming " | |
11115 "changesets that the hook should pay attention to. You don't normally need to " | |
11116 "configure this section." | |
11117 msgstr "" | |
11118 | |
11119 #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para> | |
11120 #: ../en/ch10-hook.xml:762 | |
11121 msgid "" | |
11122 "<envar role=\"rc-item-acl\">serve</envar>: Control incoming changesets that " | |
11123 "are arriving from a remote repository over http or ssh. This is the default " | |
11124 "value of <envar role=\"rc-item-acl\">sources</envar>, and usually the only " | |
11125 "setting you'll need for this configuration item." | |
11126 msgstr "" | |
11127 | |
11128 #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para> | |
11129 #: ../en/ch10-hook.xml:770 | |
11130 msgid "" | |
11131 "<envar role=\"rc-item-acl\">pull</envar>: Control incoming changesets that " | |
11132 "are arriving via a pull from a local repository." | |
11133 msgstr "" | |
11134 | |
11135 #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para> | |
11136 #: ../en/ch10-hook.xml:775 | |
11137 msgid "" | |
11138 "<envar role=\"rc-item-acl\">push</envar>: Control incoming changesets that " | |
11139 "are arriving via a push from a local repository." | |
11140 msgstr "" | |
11141 | |
11142 #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para> | |
11143 #: ../en/ch10-hook.xml:780 | |
11144 msgid "" | |
11145 "<envar role=\"rc-item-acl\">bundle</envar>: Control incoming changesets that " | |
11146 "are arriving from another repository via a bundle." | |
11147 msgstr "" | |
11148 | |
11149 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
11150 #: ../en/ch10-hook.xml:786 | |
11151 msgid "" | |
11152 "The <literal role=\"rc-acl.allow\">acl.allow</literal> section controls the " | |
11153 "users that are allowed to add changesets to the repository. If this section " | |
11154 "is not present, all users that are not explicitly denied are allowed. If " | |
11155 "this section is present, all users that are not explicitly allowed are denied " | |
11156 "(so an empty section means that all users are denied)." | |
11157 msgstr "" | |
11158 | |
11159 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
11160 #: ../en/ch10-hook.xml:795 | |
11161 msgid "" | |
11162 "The <literal role=\"rc-acl.deny\">acl.deny</literal> section determines which " | |
11163 "users are denied from adding changesets to the repository. If this section " | |
11164 "is not present or is empty, no users are denied." | |
11165 msgstr "" | |
11166 | |
11167 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
11168 #: ../en/ch10-hook.xml:801 | |
11169 msgid "" | |
11170 "The syntaxes for the <literal role=\"rc-acl.allow\">acl.allow</literal> and " | |
11171 "<literal role=\"rc-acl.deny\">acl.deny</literal> sections are identical. On " | |
11172 "the left of each entry is a glob pattern that matches files or directories, " | |
11173 "relative to the root of the repository; on the right, a user name." | |
11174 msgstr "" | |
11175 | |
11176 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
11177 #: ../en/ch10-hook.xml:809 | |
11178 msgid "" | |
11179 "In the following example, the user <literal>docwriter</literal> can only push " | |
11180 "changes to the <filename class=\"directory\">docs</filename> subtree of the " | |
11181 "repository, while <literal>intern</literal> can push changes to any file or " | |
11182 "directory except <filename class=\"directory\">source/sensitive</filename>." | |
11183 msgstr "" | |
11184 | |
11185 #. type: Content of: <book><chapter><sect1><sect2><sect3><title> | |
11186 #: ../en/ch10-hook.xml:821 ../en/ch10-hook.xml:1095 ../en/ch10-hook.xml:1308 | |
11187 msgid "Testing and troubleshooting" | |
11188 msgstr "" | |
11189 | |
11190 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
11191 #: ../en/ch10-hook.xml:823 | |
11192 msgid "" | |
11193 "If you want to test the <literal role=\"hg-ext\">acl</literal> hook, run it " | |
11194 "with Mercurial's debugging output enabled. Since you'll probably be running " | |
11195 "it on a server where it's not convenient (or sometimes possible) to pass in " | |
11196 "the <option role=\"hg-opt-global\">--debug</option> option, don't forget that " | |
11197 "you can enable debugging output in your <filename role=\"special\"> /.hgrc</" | |
11198 "filename>:" | |
11199 msgstr "" | |
11200 | |
11201 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
11202 #: ../en/ch10-hook.xml:833 | |
11203 msgid "" | |
11204 "With this enabled, the <literal role=\"hg-ext\">acl</literal> hook will print " | |
11205 "enough information to let you figure out why it is allowing or forbidding " | |
11206 "pushes from specific users." | |
11207 msgstr "" | |
11208 | |
11209 #. type: Content of: <book><chapter><sect1><sect2><title> | |
11210 #: ../en/ch10-hook.xml:842 | |
11211 msgid "" | |
11212 "<literal role=\"hg-ext\">bugzilla</literal>&emdash;integration with Bugzilla" | |
11213 msgstr "" | |
11214 | |
11215 #. type: Content of: <book><chapter><sect1><sect2><para> | |
11216 #: ../en/ch10-hook.xml:846 | |
11217 msgid "" | |
11218 "The <literal role=\"hg-ext\">bugzilla</literal> extension adds a comment to a " | |
11219 "Bugzilla bug whenever it finds a reference to that bug ID in a commit " | |
11220 "comment. You can install this hook on a shared server, so that any time a " | |
11221 "remote user pushes changes to this server, the hook gets run." | |
11222 msgstr "" | |
11223 | |
11224 #. type: Content of: <book><chapter><sect1><sect2><para> | |
11225 #: ../en/ch10-hook.xml:853 | |
11226 msgid "" | |
11227 "It adds a comment to the bug that looks like this (you can configure the " | |
11228 "contents of the comment&emdash;see below):" | |
11229 msgstr "" | |
11230 | |
11231 #. type: Content of: <book><chapter><sect1><sect2><para> | |
11232 #: ../en/ch10-hook.xml:862 | |
11233 msgid "" | |
11234 "The value of this hook is that it automates the process of updating a bug any " | |
11235 "time a changeset refers to it. If you configure the hook properly, it makes " | |
11236 "it easy for people to browse straight from a Bugzilla bug to a changeset that " | |
11237 "refers to that bug." | |
11238 msgstr "" | |
11239 | |
11240 #. type: Content of: <book><chapter><sect1><sect2><para> | |
11241 #: ../en/ch10-hook.xml:869 | |
11242 msgid "" | |
11243 "You can use the code in this hook as a starting point for some more exotic " | |
11244 "Bugzilla integration recipes. Here are a few possibilities:" | |
11245 msgstr "" | |
11246 | |
11247 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
11248 #: ../en/ch10-hook.xml:874 | |
11249 msgid "" | |
11250 "Require that every changeset pushed to the server have a valid bug ID in its " | |
11251 "commit comment. In this case, you'd want to configure the hook as a <literal " | |
11252 "role=\"hook\">pretxncommit</literal> hook. This would allow the hook to " | |
11253 "reject changes that didn't contain bug IDs." | |
11254 msgstr "" | |
11255 | |
11256 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
11257 #: ../en/ch10-hook.xml:882 | |
11258 msgid "" | |
11259 "Allow incoming changesets to automatically modify the <emphasis>state</" | |
11260 "emphasis> of a bug, as well as simply adding a comment. For example, the " | |
11261 "hook could recognise the string <quote>fixed bug 31337</quote> as indicating " | |
11262 "that it should update the state of bug 31337 to <quote>requires testing</" | |
11263 "quote>." | |
11264 msgstr "" | |
11265 | |
11266 #. type: Content of: <book><chapter><sect1><sect2><sect3><title> | |
11267 #: ../en/ch10-hook.xml:892 | |
11268 msgid "Configuring the <literal role=\"hook\">bugzilla</literal> hook" | |
11269 msgstr "" | |
11270 | |
11271 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
11272 #: ../en/ch10-hook.xml:895 | |
11273 msgid "" | |
11274 "You should configure this hook in your server's <filename role=\"special\"> /." | |
11275 "hgrc</filename>\\ as an <literal role=\"hook\">incoming</literal> hook, for " | |
11276 "example as follows:" | |
11277 msgstr "" | |
11278 | |
11279 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
11280 #: ../en/ch10-hook.xml:903 | |
11281 msgid "" | |
11282 "Because of the specialised nature of this hook, and because Bugzilla was not " | |
11283 "written with this kind of integration in mind, configuring this hook is a " | |
11284 "somewhat involved process." | |
11285 msgstr "" | |
11286 | |
11287 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
11288 #: ../en/ch10-hook.xml:909 | |
11289 msgid "" | |
11290 "Before you begin, you must install the MySQL bindings for Python on the host" | |
11291 "(s) where you'll be running the hook. If this is not available as a binary " | |
11292 "package for your system, you can download it from <citation>web:mysql-python</" | |
11293 "citation>." | |
11294 msgstr "" | |
11295 | |
11296 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
11297 #: ../en/ch10-hook.xml:916 | |
11298 msgid "" | |
11299 "Configuration information for this hook lives in the <literal role=\"rc-" | |
11300 "bugzilla\">bugzilla</literal> section of your <filename role=\"special\"> /." | |
11301 "hgrc</filename>." | |
11302 msgstr "" | |
11303 | |
11304 #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para> | |
11305 #: ../en/ch10-hook.xml:921 | |
11306 msgid "" | |
11307 "<envar role=\"rc-item-bugzilla\">version</envar>: The version of Bugzilla " | |
11308 "installed on the server. The database schema that Bugzilla uses changes " | |
11309 "occasionally, so this hook has to know exactly which schema to use. At the " | |
11310 "moment, the only version supported is <literal>2.16</literal>." | |
11311 msgstr "" | |
11312 | |
11313 #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para> | |
11314 #: ../en/ch10-hook.xml:930 | |
11315 msgid "" | |
11316 "<envar role=\"rc-item-bugzilla\">host</envar>: The hostname of the MySQL " | |
11317 "server that stores your Bugzilla data. The database must be configured to " | |
11318 "allow connections from whatever host you are running the <literal role=\"hook" | |
11319 "\">bugzilla</literal> hook on." | |
11320 msgstr "" | |
11321 | |
11322 #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para> | |
11323 #: ../en/ch10-hook.xml:937 | |
11324 msgid "" | |
11325 "<envar role=\"rc-item-bugzilla\">user</envar>: The username with which to " | |
11326 "connect to the MySQL server. The database must be configured to allow this " | |
11327 "user to connect from whatever host you are running the <literal role=\"hook" | |
11328 "\">bugzilla</literal> hook on. This user must be able to access and modify " | |
11329 "Bugzilla tables. The default value of this item is <literal>bugs</literal>, " | |
11330 "which is the standard name of the Bugzilla user in a MySQL database." | |
11331 msgstr "" | |
11332 | |
11333 #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para> | |
11334 #: ../en/ch10-hook.xml:948 | |
11335 msgid "" | |
11336 "<envar role=\"rc-item-bugzilla\">password</envar>: The MySQL password for the " | |
11337 "user you configured above. This is stored as plain text, so you should make " | |
11338 "sure that unauthorised users cannot read the <filename role=\"special\"> /." | |
11339 "hgrc</filename>\\ file where you store this information." | |
11340 msgstr "" | |
11341 | |
11342 #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para> | |
11343 #: ../en/ch10-hook.xml:957 | |
11344 msgid "" | |
11345 "<envar role=\"rc-item-bugzilla\">db</envar>: The name of the Bugzilla " | |
11346 "database on the MySQL server. The default value of this item is " | |
11347 "<literal>bugs</literal>, which is the standard name of the MySQL database " | |
11348 "where Bugzilla stores its data." | |
11349 msgstr "" | |
11350 | |
11351 #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para> | |
11352 #: ../en/ch10-hook.xml:964 | |
11353 msgid "" | |
11354 "<envar role=\"rc-item-bugzilla\">notify</envar>: If you want Bugzilla to send " | |
11355 "out a notification email to subscribers after this hook has added a comment " | |
11356 "to a bug, you will need this hook to run a command whenever it updates the " | |
11357 "database. The command to run depends on where you have installed Bugzilla, " | |
11358 "but it will typically look something like this, if you have Bugzilla " | |
11359 "installed in <filename class=\"directory\">/var/www/html/bugzilla</filename>:" | |
11360 msgstr "" | |
11361 | |
11362 #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para> | |
11363 #: ../en/ch10-hook.xml:977 | |
11364 msgid "" | |
11365 "The Bugzilla <literal>processmail</literal> program expects to be given a bug " | |
11366 "ID (the hook replaces <quote><literal>%s</literal></quote> with the bug ID) " | |
11367 "and an email address. It also expects to be able to write to some files in " | |
11368 "the directory that it runs in. If Bugzilla and this hook are not installed " | |
11369 "on the same machine, you will need to find a way to run <literal>processmail</" | |
11370 "literal> on the server where Bugzilla is installed." | |
11371 msgstr "" | |
11372 | |
11373 #. type: Content of: <book><chapter><sect1><sect2><sect3><title> | |
11374 #: ../en/ch10-hook.xml:992 | |
11375 msgid "Mapping committer names to Bugzilla user names" | |
11376 msgstr "" | |
11377 | |
11378 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
11379 #: ../en/ch10-hook.xml:994 | |
11380 msgid "" | |
11381 "By default, the <literal role=\"hg-ext\">bugzilla</literal> hook tries to use " | |
11382 "the email address of a changeset's committer as the Bugzilla user name with " | |
11383 "which to update a bug. If this does not suit your needs, you can map " | |
11384 "committer email addresses to Bugzilla user names using a <literal role=\"rc-" | |
11385 "usermap\">usermap</literal> section." | |
11386 msgstr "" | |
11387 | |
11388 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
11389 #: ../en/ch10-hook.xml:1003 | |
11390 msgid "" | |
11391 "Each item in the <literal role=\"rc-usermap\">usermap</literal> section " | |
11392 "contains an email address on the left, and a Bugzilla user name on the right." | |
11393 msgstr "" | |
11394 | |
11395 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
11396 #: ../en/ch10-hook.xml:1010 | |
11397 msgid "" | |
11398 "You can either keep the <literal role=\"rc-usermap\">usermap</literal> data " | |
11399 "in a normal <filename role=\"special\">~/.hgrc</filename>, or tell the " | |
11400 "<literal role=\"hg-ext\">bugzilla</literal> hook to read the information from " | |
11401 "an external <filename>usermap</filename> file. In the latter case, you can " | |
11402 "store <filename>usermap</filename> data by itself in (for example) a user-" | |
11403 "modifiable repository. This makes it possible to let your users maintain " | |
11404 "their own <envar role=\"rc-item-bugzilla\">usermap</envar> entries. The main " | |
11405 "<filename role=\"special\"> /.hgrc</filename>\\ file might look like this:" | |
11406 msgstr "" | |
11407 | |
11408 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
11409 #: ../en/ch10-hook.xml:1026 | |
11410 msgid "" | |
11411 "While the <filename>usermap</filename> file that it refers to might look like " | |
11412 "this:" | |
11413 msgstr "" | |
11414 | |
11415 #. type: Content of: <book><chapter><sect1><sect2><sect3><title> | |
11416 #: ../en/ch10-hook.xml:1035 | |
11417 msgid "Configuring the text that gets added to a bug" | |
11418 msgstr "" | |
11419 | |
11420 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
11421 #: ../en/ch10-hook.xml:1037 | |
11422 msgid "" | |
11423 "You can configure the text that this hook adds as a comment; you specify it " | |
11424 "in the form of a Mercurial template. Several <filename role=\"special\"> /." | |
11425 "hgrc</filename>\\ entries (still in the <literal role=\"rc-bugzilla" | |
11426 "\">bugzilla</literal> section) control this behaviour." | |
11427 msgstr "" | |
11428 | |
11429 #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para> | |
11430 #: ../en/ch10-hook.xml:1044 | |
11431 msgid "" | |
11432 "<literal>strip</literal>: The number of leading path elements to strip from a " | |
11433 "repository's path name to construct a partial path for a URL. For example, if " | |
11434 "the repositories on your server live under <filename class=\"directory\">/" | |
11435 "home/hg/repos</filename>, and you have a repository whose path is <filename " | |
11436 "class=\"directory\">/home/hg/repos/app/tests</filename>, then setting " | |
11437 "<literal>strip</literal> to <literal>4</literal> will give a partial path of " | |
11438 "<filename class=\"directory\">app/tests</filename>. The hook will make this " | |
11439 "partial path available when expanding a template, as <literal>webroot</" | |
11440 "literal>." | |
11441 msgstr "" | |
11442 | |
11443 #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para> | |
11444 #: ../en/ch10-hook.xml:1058 | |
11445 msgid "" | |
11446 "<literal>template</literal>: The text of the template to use. In addition to " | |
11447 "the usual changeset-related variables, this template can use <literal>hgweb</" | |
11448 "literal> (the value of the <literal>hgweb</literal> configuration item above) " | |
11449 "and <literal>webroot</literal> (the path constructed using <literal>strip</" | |
11450 "literal> above)." | |
11451 msgstr "" | |
11452 | |
11453 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
11454 #: ../en/ch10-hook.xml:1068 | |
11455 msgid "" | |
11456 "In addition, you can add a <envar role=\"rc-item-web\">baseurl</envar> item " | |
11457 "to the <literal role=\"rc-web\">web</literal> section of your <filename role=" | |
11458 "\"special\"> /.hgrc</filename>. The <literal role=\"hg-ext\">bugzilla</" | |
11459 "literal> hook will make this available when expanding a template, as the base " | |
11460 "string to use when constructing a URL that will let users browse from a " | |
11461 "Bugzilla comment to view a changeset. Example:" | |
11462 msgstr "" | |
11463 | |
11464 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
11465 #: ../en/ch10-hook.xml:1080 | |
11466 msgid "" | |
11467 "Here is an example set of <literal role=\"hg-ext\">bugzilla</literal> hook " | |
11468 "config information." | |
11469 msgstr "" | |
11470 | |
11471 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
11472 #: ../en/ch10-hook.xml:1097 | |
11473 msgid "" | |
11474 "The most common problems with configuring the <literal role=\"hg-ext" | |
11475 "\">bugzilla</literal> hook relate to running Bugzilla's " | |
11476 "<filename>processmail</filename> script and mapping committer names to user " | |
11477 "names." | |
11478 msgstr "" | |
11479 | |
11480 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
11481 #: ../en/ch10-hook.xml:1103 | |
11482 msgid "" | |
11483 "Recall from section <xref linkend=\"sec.hook.bugzilla.config\"/> above that " | |
11484 "the user that runs the Mercurial process on the server is also the one that " | |
11485 "will run the <filename>processmail</filename> script. The " | |
11486 "<filename>processmail</filename> script sometimes causes Bugzilla to write to " | |
11487 "files in its configuration directory, and Bugzilla's configuration files are " | |
11488 "usually owned by the user that your web server runs under." | |
11489 msgstr "" | |
11490 | |
11491 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
11492 #: ../en/ch10-hook.xml:1114 | |
11493 msgid "" | |
11494 "You can cause <filename>processmail</filename> to be run with the suitable " | |
11495 "user's identity using the <command>sudo</command> command. Here is an " | |
11496 "example entry for a <filename>sudoers</filename> file." | |
11497 msgstr "" | |
11498 | |
11499 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
11500 #: ../en/ch10-hook.xml:1122 | |
11501 msgid "" | |
11502 "This allows the <literal>hg_user</literal> user to run a " | |
11503 "<filename>processmail-wrapper</filename> program under the identity of " | |
11504 "<literal>httpd_user</literal>." | |
11505 msgstr "" | |
11506 | |
11507 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
11508 #: ../en/ch10-hook.xml:1127 | |
11509 msgid "" | |
11510 "This indirection through a wrapper script is necessary, because " | |
11511 "<filename>processmail</filename> expects to be run with its current directory " | |
11512 "set to wherever you installed Bugzilla; you can't specify that kind of " | |
11513 "constraint in a <filename>sudoers</filename> file. The contents of the " | |
11514 "wrapper script are simple:" | |
11515 msgstr "" | |
11516 | |
11517 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
11518 #: ../en/ch10-hook.xml:1136 | |
11519 msgid "" | |
11520 "It doesn't seem to matter what email address you pass to " | |
11521 "<filename>processmail</filename>." | |
11522 msgstr "" | |
11523 | |
11524 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
11525 #: ../en/ch10-hook.xml:1140 | |
11526 msgid "" | |
11527 "If your <literal role=\"rc-usermap\">usermap</literal> is not set up " | |
11528 "correctly, users will see an error message from the <literal role=\"hg-ext" | |
11529 "\">bugzilla</literal> hook when they push changes to the server. The error " | |
11530 "message will look like this:" | |
11531 msgstr "" | |
11532 | |
11533 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
11534 #: ../en/ch10-hook.xml:1148 | |
11535 msgid "" | |
11536 "What this means is that the committer's address, <literal>john.q." | |
11537 "public@example.com</literal>, is not a valid Bugzilla user name, nor does it " | |
11538 "have an entry in your <literal role=\"rc-usermap\">usermap</literal> that " | |
11539 "maps it to a valid Bugzilla user name." | |
11540 msgstr "" | |
11541 | |
11542 #. type: Content of: <book><chapter><sect1><sect2><title> | |
11543 #: ../en/ch10-hook.xml:1158 | |
11544 msgid "" | |
11545 "<literal role=\"hg-ext\">notify</literal>&emdash;send email notifications" | |
11546 msgstr "" | |
11547 | |
11548 #. type: Content of: <book><chapter><sect1><sect2><para> | |
11549 #: ../en/ch10-hook.xml:1161 | |
11550 msgid "" | |
11551 "Although Mercurial's built-in web server provides RSS feeds of changes in " | |
11552 "every repository, many people prefer to receive change notifications via " | |
11553 "email. The <literal role=\"hg-ext\">notify</literal> hook lets you send out " | |
11554 "notifications to a set of email addresses whenever changesets arrive that " | |
11555 "those subscribers are interested in." | |
11556 msgstr "" | |
11557 | |
11558 #. type: Content of: <book><chapter><sect1><sect2><para> | |
11559 #: ../en/ch10-hook.xml:1169 | |
11560 msgid "" | |
11561 "As with the <literal role=\"hg-ext\">bugzilla</literal> hook, the <literal " | |
11562 "role=\"hg-ext\">notify</literal> hook is template-driven, so you can " | |
11563 "customise the contents of the notification messages that it sends." | |
11564 msgstr "" | |
11565 | |
11566 #. type: Content of: <book><chapter><sect1><sect2><para> | |
11567 #: ../en/ch10-hook.xml:1175 | |
11568 msgid "" | |
11569 "By default, the <literal role=\"hg-ext\">notify</literal> hook includes a " | |
11570 "diff of every changeset that it sends out; you can limit the size of the " | |
11571 "diff, or turn this feature off entirely. It is useful for letting " | |
11572 "subscribers review changes immediately, rather than clicking to follow a URL." | |
11573 msgstr "" | |
11574 | |
11575 #. type: Content of: <book><chapter><sect1><sect2><sect3><title> | |
11576 #: ../en/ch10-hook.xml:1183 | |
11577 msgid "Configuring the <literal role=\"hg-ext\">notify</literal> hook" | |
11578 msgstr "" | |
11579 | |
11580 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
11581 #: ../en/ch10-hook.xml:1186 | |
11582 msgid "" | |
11583 "You can set up the <literal role=\"hg-ext\">notify</literal> hook to send one " | |
11584 "email message per incoming changeset, or one per incoming group of changesets " | |
11585 "(all those that arrived in a single pull or push)." | |
11586 msgstr "" | |
11587 | |
11588 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
11589 #: ../en/ch10-hook.xml:1197 | |
11590 msgid "" | |
11591 "Configuration information for this hook lives in the <literal role=\"rc-notify" | |
11592 "\">notify</literal> section of a <filename role=\"special\"> /.hgrc</filename>" | |
11593 "\\ file." | |
11594 msgstr "" | |
11595 | |
11596 #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para> | |
11597 #: ../en/ch10-hook.xml:1202 | |
11598 msgid "" | |
11599 "<envar role=\"rc-item-notify\">test</envar>: By default, this hook does not " | |
11600 "send out email at all; instead, it prints the message that it " | |
11601 "<emphasis>would</emphasis> send. Set this item to <literal>false</literal> " | |
11602 "to allow email to be sent. The reason that sending of email is turned off by " | |
11603 "default is that it takes several tries to configure this extension exactly as " | |
11604 "you would like, and it would be bad form to spam subscribers with a number of " | |
11605 "<quote>broken</quote> notifications while you debug your configuration." | |
11606 msgstr "" | |
11607 | |
11608 #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para> | |
11609 #: ../en/ch10-hook.xml:1214 | |
11610 msgid "" | |
11611 "<envar role=\"rc-item-notify\">config</envar>: The path to a configuration " | |
11612 "file that contains subscription information. This is kept separate from the " | |
11613 "main <filename role=\"special\"> /.hgrc</filename>\\ so that you can maintain " | |
11614 "it in a repository of its own. People can then clone that repository, update " | |
11615 "their subscriptions, and push the changes back to your server." | |
11616 msgstr "" | |
11617 | |
11618 #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para> | |
11619 #: ../en/ch10-hook.xml:1223 | |
11620 msgid "" | |
11621 "<envar role=\"rc-item-notify\">strip</envar>: The number of leading path " | |
11622 "separator characters to strip from a repository's path, when deciding whether " | |
11623 "a repository has subscribers. For example, if the repositories on your " | |
11624 "server live in <filename class=\"directory\">/home/hg/repos</filename>, and " | |
11625 "<literal role=\"hg-ext\">notify</literal> is considering a repository named " | |
11626 "<filename class=\"directory\">/home/hg/repos/shared/test</filename>, setting " | |
11627 "<envar role=\"rc-item-notify\">strip</envar> to <literal>4</literal> will " | |
11628 "cause <literal role=\"hg-ext\">notify</literal> to trim the path it considers " | |
11629 "down to <filename class=\"directory\">shared/test</filename>, and it will " | |
11630 "match subscribers against that." | |
11631 msgstr "" | |
11632 | |
11633 #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para> | |
11634 #: ../en/ch10-hook.xml:1240 | |
11635 msgid "" | |
11636 "<envar role=\"rc-item-notify\">template</envar>: The template text to use " | |
11637 "when sending messages. This specifies both the contents of the message " | |
11638 "header and its body." | |
11639 msgstr "" | |
11640 | |
11641 #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para> | |
11642 #: ../en/ch10-hook.xml:1246 | |
11643 msgid "" | |
11644 "<envar role=\"rc-item-notify\">maxdiff</envar>: The maximum number of lines " | |
11645 "of diff data to append to the end of a message. If a diff is longer than " | |
11646 "this, it is truncated. By default, this is set to 300. Set this to " | |
11647 "<literal>0</literal> to omit diffs from notification emails." | |
11648 msgstr "" | |
11649 | |
11650 #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para> | |
11651 #: ../en/ch10-hook.xml:1255 | |
11652 msgid "" | |
11653 "<envar role=\"rc-item-notify\">sources</envar>: A list of sources of " | |
11654 "changesets to consider. This lets you limit <literal role=\"hg-ext\">notify</" | |
11655 "literal> to only sending out email about changes that remote users pushed " | |
11656 "into this repository via a server, for example. See section <xref linkend=" | |
11657 "\"sec.hook.sources\"/> for the sources you can specify here." | |
11658 msgstr "" | |
11659 | |
11660 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
11661 #: ../en/ch10-hook.xml:1267 | |
11662 msgid "" | |
11663 "If you set the <envar role=\"rc-item-web\">baseurl</envar> item in the " | |
11664 "<literal role=\"rc-web\">web</literal> section, you can use it in a template; " | |
11665 "it will be available as <literal>webroot</literal>." | |
11666 msgstr "" | |
11667 | |
11668 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
11669 #: ../en/ch10-hook.xml:1273 | |
11670 msgid "" | |
11671 "Here is an example set of <literal role=\"hg-ext\">notify</literal> " | |
11672 "configuration information." | |
11673 msgstr "" | |
11674 | |
11675 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
11676 #: ../en/ch10-hook.xml:1289 | |
11677 msgid "This will produce a message that looks like the following:" | |
11678 msgstr "" | |
11679 | |
11680 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
11681 #: ../en/ch10-hook.xml:1310 | |
11682 msgid "" | |
11683 "Do not forget that by default, the <literal role=\"hg-ext\">notify</literal> " | |
11684 "extension <emphasis>will not send any mail</emphasis> until you explicitly " | |
11685 "configure it to do so, by setting <envar role=\"rc-item-notify\">test</envar> " | |
11686 "to <literal>false</literal>. Until you do that, it simply prints the message " | |
11687 "it <emphasis>would</emphasis> send." | |
11688 msgstr "" | |
11689 | |
11690 #. type: Content of: <book><chapter><sect1><title> | |
11691 #: ../en/ch10-hook.xml:1322 | |
11692 msgid "Information for writers of hooks" | |
11693 msgstr "" | |
11694 | |
11695 #. type: Content of: <book><chapter><sect1><sect2><title> | |
11696 #: ../en/ch10-hook.xml:1325 | |
11697 msgid "In-process hook execution" | |
11698 msgstr "" | |
11699 | |
11700 #. type: Content of: <book><chapter><sect1><sect2><para> | |
11701 #: ../en/ch10-hook.xml:1327 | |
11702 msgid "An in-process hook is called with arguments of the following form:" | |
11703 msgstr "" | |
11704 | |
11705 #. type: Content of: <book><chapter><sect1><sect2><para> | |
11706 #: ../en/ch10-hook.xml:1333 | |
11707 msgid "" | |
11708 "The <literal>ui</literal> parameter is a <literal role=\"py-mod-mercurial.ui" | |
11709 "\">ui</literal> object. The <literal>repo</literal> parameter is a <literal " | |
11710 "role=\"py-mod-mercurial.localrepo\">localrepository</literal> object. The " | |
11711 "names and values of the <literal>**kwargs</literal> parameters depend on the " | |
11712 "hook being invoked, with the following common features:" | |
11713 msgstr "" | |
11714 | |
11715 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
11716 #: ../en/ch10-hook.xml:1342 | |
11717 msgid "" | |
11718 "If a parameter is named <literal>node</literal> or <literal>parentN</" | |
11719 "literal>, it will contain a hexadecimal changeset ID. The empty string is " | |
11720 "used to represent <quote>null changeset ID</quote> instead of a string of " | |
11721 "zeroes." | |
11722 msgstr "" | |
11723 | |
11724 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
11725 #: ../en/ch10-hook.xml:1349 | |
11726 msgid "" | |
11727 "If a parameter is named <literal>url</literal>, it will contain the URL of a " | |
11728 "remote repository, if that can be determined." | |
11729 msgstr "" | |
11730 | |
11731 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
11732 #: ../en/ch10-hook.xml:1354 | |
11733 msgid "" | |
11734 "Boolean-valued parameters are represented as Python <literal>bool</literal> " | |
11735 "objects." | |
11736 msgstr "" | |
11737 | |
11738 #. type: Content of: <book><chapter><sect1><sect2><para> | |
11739 #: ../en/ch10-hook.xml:1359 | |
11740 msgid "" | |
11741 "An in-process hook is called without a change to the process's working " | |
11742 "directory (unlike external hooks, which are run in the root of the " | |
11743 "repository). It must not change the process's working directory, or it will " | |
11744 "cause any calls it makes into the Mercurial API to fail." | |
11745 msgstr "" | |
11746 | |
11747 #. type: Content of: <book><chapter><sect1><sect2><para> | |
11748 #: ../en/ch10-hook.xml:1366 | |
11749 msgid "" | |
11750 "If a hook returns a boolean <quote>false</quote> value, it is considered to " | |
11751 "have succeeded. If it returns a boolean <quote>true</quote> value or raises " | |
11752 "an exception, it is considered to have failed. A useful way to think of the " | |
11753 "calling convention is <quote>tell me if you fail</quote>." | |
11754 msgstr "" | |
11755 | |
11756 #. type: Content of: <book><chapter><sect1><sect2><para> | |
11757 #: ../en/ch10-hook.xml:1373 | |
11758 msgid "" | |
11759 "Note that changeset IDs are passed into Python hooks as hexadecimal strings, " | |
11760 "not the binary hashes that Mercurial's APIs normally use. To convert a hash " | |
11761 "from hex to binary, use the \\pymodfunc{mercurial.node}{bin} function." | |
11762 msgstr "" | |
11763 | |
11764 #. type: Content of: <book><chapter><sect1><sect2><title> | |
11765 #: ../en/ch10-hook.xml:1381 | |
11766 msgid "External hook execution" | |
11767 msgstr "" | |
11768 | |
11769 #. type: Content of: <book><chapter><sect1><sect2><para> | |
11770 #: ../en/ch10-hook.xml:1383 | |
11771 msgid "" | |
11772 "An external hook is passed to the shell of the user running Mercurial. " | |
11773 "Features of that shell, such as variable substitution and command " | |
11774 "redirection, are available. The hook is run in the root directory of the " | |
11775 "repository (unlike in-process hooks, which are run in the same directory that " | |
11776 "Mercurial was run in)." | |
11777 msgstr "" | |
11778 | |
11779 #. type: Content of: <book><chapter><sect1><sect2><para> | |
11780 #: ../en/ch10-hook.xml:1391 | |
11781 msgid "" | |
11782 "Hook parameters are passed to the hook as environment variables. Each " | |
11783 "environment variable's name is converted in upper case and prefixed with the " | |
11784 "string <quote><literal>HG_</literal></quote>. For example, if the name of a " | |
11785 "parameter is <quote><literal>node</literal></quote>, the name of the " | |
11786 "environment variable representing that parameter will be " | |
11787 "<quote><literal>HG_NODE</literal></quote>." | |
11788 msgstr "" | |
11789 | |
11790 #. type: Content of: <book><chapter><sect1><sect2><para> | |
11791 #: ../en/ch10-hook.xml:1400 | |
11792 msgid "" | |
11793 "A boolean parameter is represented as the string <quote><literal>1</literal></" | |
11794 "quote> for <quote>true</quote>, <quote><literal>0</literal></quote> for " | |
11795 "<quote>false</quote>. If an environment variable is named <envar>HG_NODE</" | |
11796 "envar>, <envar>HG_PARENT1</envar> or <envar>HG_PARENT2</envar>, it contains a " | |
11797 "changeset ID represented as a hexadecimal string. The empty string is used " | |
11798 "to represent <quote>null changeset ID</quote> instead of a string of zeroes. " | |
11799 "If an environment variable is named <envar>HG_URL</envar>, it will contain " | |
11800 "the URL of a remote repository, if that can be determined." | |
11801 msgstr "" | |
11802 | |
11803 #. type: Content of: <book><chapter><sect1><sect2><para> | |
11804 #: ../en/ch10-hook.xml:1412 | |
11805 msgid "" | |
11806 "If a hook exits with a status of zero, it is considered to have succeeded. " | |
11807 "If it exits with a non-zero status, it is considered to have failed." | |
11808 msgstr "" | |
11809 | |
11810 #. type: Content of: <book><chapter><sect1><sect2><title> | |
11811 #: ../en/ch10-hook.xml:1419 | |
11812 msgid "Finding out where changesets come from" | |
11813 msgstr "" | |
11814 | |
11815 #. type: Content of: <book><chapter><sect1><sect2><para> | |
11816 #: ../en/ch10-hook.xml:1421 | |
11817 msgid "" | |
11818 "A hook that involves the transfer of changesets between a local repository " | |
11819 "and another may be able to find out information about the <quote>far side</" | |
11820 "quote>. Mercurial knows <emphasis>how</emphasis> changes are being " | |
11821 "transferred, and in many cases <emphasis>where</emphasis> they are being " | |
11822 "transferred to or from." | |
11823 msgstr "" | |
11824 | |
11825 #. type: Content of: <book><chapter><sect1><sect2><sect3><title> | |
11826 #: ../en/ch10-hook.xml:1430 | |
11827 msgid "Sources of changesets" | |
11828 msgstr "" | |
11829 | |
11830 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
11831 #: ../en/ch10-hook.xml:1432 | |
11832 msgid "" | |
11833 "Mercurial will tell a hook what means are, or were, used to transfer " | |
11834 "changesets between repositories. This is provided by Mercurial in a Python " | |
11835 "parameter named <literal>source</literal>, or an environment variable named " | |
11836 "<envar>HG_SOURCE</envar>." | |
11837 msgstr "" | |
11838 | |
11839 #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para> | |
11840 #: ../en/ch10-hook.xml:1440 | |
11841 msgid "" | |
11842 "<literal>serve</literal>: Changesets are transferred to or from a remote " | |
11843 "repository over http or ssh." | |
11844 msgstr "" | |
11845 | |
11846 #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para> | |
11847 #: ../en/ch10-hook.xml:1445 | |
11848 msgid "" | |
11849 "<literal>pull</literal>: Changesets are being transferred via a pull from one " | |
11850 "repository into another." | |
11851 msgstr "" | |
11852 | |
11853 #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para> | |
11854 #: ../en/ch10-hook.xml:1450 | |
11855 msgid "" | |
11856 "<literal>push</literal>: Changesets are being transferred via a push from one " | |
11857 "repository into another." | |
11858 msgstr "" | |
11859 | |
11860 #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para> | |
11861 #: ../en/ch10-hook.xml:1455 | |
11862 msgid "" | |
11863 "<literal>bundle</literal>: Changesets are being transferred to or from a " | |
11864 "bundle." | |
11865 msgstr "" | |
11866 | |
11867 #. type: Content of: <book><chapter><sect1><sect2><sect3><title> | |
11868 #: ../en/ch10-hook.xml:1462 | |
11869 msgid "Where changes are going&emdash;remote repository URLs" | |
11870 msgstr "" | |
11871 | |
11872 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
11873 #: ../en/ch10-hook.xml:1465 | |
11874 msgid "" | |
11875 "When possible, Mercurial will tell a hook the location of the <quote>far " | |
11876 "side</quote> of an activity that transfers changeset data between " | |
11877 "repositories. This is provided by Mercurial in a Python parameter named " | |
11878 "<literal>url</literal>, or an environment variable named <envar>HG_URL</" | |
11879 "envar>." | |
11880 msgstr "" | |
11881 | |
11882 #. type: Content of: <book><chapter><sect1><sect2><sect3><para> | |
11883 #: ../en/ch10-hook.xml:1473 | |
11884 msgid "" | |
11885 "This information is not always known. If a hook is invoked in a repository " | |
11886 "that is being served via http or ssh, Mercurial cannot tell where the remote " | |
11887 "repository is, but it may know where the client is connecting from. In such " | |
11888 "cases, the URL will take one of the following forms:" | |
11889 msgstr "" | |
11890 | |
11891 #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para> | |
11892 #: ../en/ch10-hook.xml:1480 | |
11893 msgid "" | |
11894 "<literal>remote:ssh:1.2.3.4</literal>&emdash;remote ssh client, at the IP " | |
11895 "address <literal>1.2.3.4</literal>." | |
11896 msgstr "" | |
11897 | |
11898 #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para> | |
11899 #: ../en/ch10-hook.xml:1485 | |
11900 msgid "" | |
11901 "<literal>remote:http:1.2.3.4</literal>&emdash;remote http client, at the IP " | |
11902 "address <literal>1.2.3.4</literal>. If the client is using SSL, this will be " | |
11903 "of the form <literal>remote:https:1.2.3.4</literal>." | |
11904 msgstr "" | |
11905 | |
11906 #. type: Content of: <book><chapter><sect1><sect2><sect3><itemizedlist><listitem><para> | |
11907 #: ../en/ch10-hook.xml:1492 | |
11908 msgid "Empty&emdash;no information could be discovered about the remote client." | |
11909 msgstr "" | |
11910 | |
11911 #. type: Content of: <book><chapter><sect1><title> | |
11912 #: ../en/ch10-hook.xml:1501 | |
11913 msgid "Hook reference" | |
11914 msgstr "" | |
11915 | |
11916 #. type: Content of: <book><chapter><sect1><sect2><title> | |
11917 #: ../en/ch10-hook.xml:1504 | |
11918 msgid "" | |
11919 "<literal role=\"hook\">changegroup</literal>&emdash;after remote changesets " | |
11920 "added" | |
11921 msgstr "" | |
11922 | |
11923 #. type: Content of: <book><chapter><sect1><sect2><para> | |
11924 #: ../en/ch10-hook.xml:1507 | |
11925 msgid "" | |
11926 "This hook is run after a group of pre-existing changesets has been added to " | |
11927 "the repository, for example via a <command role=\"hg-cmd\">hg pull</command> " | |
11928 "or <command role=\"hg-cmd\">hg unbundle</command>. This hook is run once per " | |
11929 "operation that added one or more changesets. This is in contrast to the " | |
11930 "<literal role=\"hook\">incoming</literal> hook, which is run once per " | |
11931 "changeset, regardless of whether the changesets arrive in a group." | |
11932 msgstr "" | |
11933 | |
11934 #. type: Content of: <book><chapter><sect1><sect2><para> | |
11935 #: ../en/ch10-hook.xml:1517 | |
11936 msgid "" | |
11937 "Some possible uses for this hook include kicking off an automated build or " | |
11938 "test of the added changesets, updating a bug database, or notifying " | |
11939 "subscribers that a repository contains new changes." | |
11940 msgstr "" | |
11941 | |
11942 #. type: Content of: <book><chapter><sect1><sect2><para> | |
11943 #: ../en/ch10-hook.xml:1523 ../en/ch10-hook.xml:1564 ../en/ch10-hook.xml:1607 | |
11944 #: ../en/ch10-hook.xml:1649 ../en/ch10-hook.xml:1704 ../en/ch10-hook.xml:1744 | |
11945 #: ../en/ch10-hook.xml:1780 ../en/ch10-hook.xml:1815 ../en/ch10-hook.xml:1877 | |
11946 #: ../en/ch10-hook.xml:1935 ../en/ch10-hook.xml:1969 ../en/ch10-hook.xml:1997 | |
11947 msgid "Parameters to this hook:" | |
11948 msgstr "" | |
11949 | |
11950 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
11951 #: ../en/ch10-hook.xml:1526 ../en/ch10-hook.xml:1880 | |
11952 msgid "" | |
11953 "<literal>node</literal>: A changeset ID. The changeset ID of the first " | |
11954 "changeset in the group that was added. All changesets between this and " | |
11955 "\\index{tags!<literal>tip</literal>}<literal>tip</literal>, inclusive, were " | |
11956 "added by a single <command role=\"hg-cmd\">hg pull</command>, <command role=" | |
11957 "\"hg-cmd\">hg push</command> or <command role=\"hg-cmd\">hg unbundle</" | |
11958 "command>." | |
11959 msgstr "" | |
11960 | |
11961 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
11962 #: ../en/ch10-hook.xml:1536 ../en/ch10-hook.xml:1614 ../en/ch10-hook.xml:1707 | |
11963 #: ../en/ch10-hook.xml:1890 | |
11964 msgid "" | |
11965 "<literal>source</literal>: A string. The source of these changes. See " | |
11966 "section <xref linkend=\"sec.hook.sources\"/> for details." | |
11967 msgstr "" | |
11968 | |
11969 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
11970 #: ../en/ch10-hook.xml:1541 ../en/ch10-hook.xml:1619 ../en/ch10-hook.xml:1670 | |
11971 #: ../en/ch10-hook.xml:1712 ../en/ch10-hook.xml:1794 ../en/ch10-hook.xml:1895 | |
11972 msgid "" | |
11973 "<literal>url</literal>: A URL. The location of the remote repository, if " | |
11974 "known. See section <xref linkend=\"sec.hook.url\"/> for more information." | |
11975 msgstr "" | |
11976 | |
11977 #. type: Content of: <book><chapter><sect1><sect2><para> | |
11978 #: ../en/ch10-hook.xml:1548 | |
11979 msgid "" | |
11980 "See also: <literal role=\"hook\">incoming</literal> (section <xref linkend=" | |
11981 "\"sec.hook.incoming\"/>), <literal role=\"hook\">prechangegroup</literal> " | |
11982 "(section <xref linkend=\"sec.hook.prechangegroup\"/>), <literal role=\"hook" | |
11983 "\">pretxnchangegroup</literal> (section <xref linkend=\"sec.hook." | |
11984 "pretxnchangegroup\"/>)" | |
11985 msgstr "" | |
11986 | |
11987 #. type: Content of: <book><chapter><sect1><sect2><title> | |
11988 #: ../en/ch10-hook.xml:1558 | |
11989 msgid "" | |
11990 "<literal role=\"hook\">commit</literal>&emdash;after a new changeset is " | |
11991 "created" | |
11992 msgstr "" | |
11993 | |
11994 #. type: Content of: <book><chapter><sect1><sect2><para> | |
11995 #: ../en/ch10-hook.xml:1561 | |
11996 msgid "This hook is run after a new changeset has been created." | |
11997 msgstr "" | |
11998 | |
11999 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
12000 #: ../en/ch10-hook.xml:1567 ../en/ch10-hook.xml:1938 | |
12001 msgid "" | |
12002 "<literal>node</literal>: A changeset ID. The changeset ID of the newly " | |
12003 "committed changeset." | |
12004 msgstr "" | |
12005 | |
12006 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
12007 #: ../en/ch10-hook.xml:1571 ../en/ch10-hook.xml:1942 | |
12008 msgid "" | |
12009 "<literal>parent1</literal>: A changeset ID. The changeset ID of the first " | |
12010 "parent of the newly committed changeset." | |
12011 msgstr "" | |
12012 | |
12013 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
12014 #: ../en/ch10-hook.xml:1576 ../en/ch10-hook.xml:1947 | |
12015 msgid "" | |
12016 "<literal>parent2</literal>: A changeset ID. The changeset ID of the second " | |
12017 "parent of the newly committed changeset." | |
12018 msgstr "" | |
12019 | |
12020 #. type: Content of: <book><chapter><sect1><sect2><para> | |
12021 #: ../en/ch10-hook.xml:1582 | |
12022 msgid "" | |
12023 "See also: <literal role=\"hook\">precommit</literal> (section <xref linkend=" | |
12024 "\"sec.hook.precommit\"/>), <literal role=\"hook\">pretxncommit</literal> " | |
12025 "(section <xref linkend=\"sec.hook.pretxncommit\"/>)" | |
12026 msgstr "" | |
12027 | |
12028 #. type: Content of: <book><chapter><sect1><sect2><title> | |
12029 #: ../en/ch10-hook.xml:1590 | |
12030 msgid "" | |
12031 "<literal role=\"hook\">incoming</literal>&emdash;after one remote changeset " | |
12032 "is added" | |
12033 msgstr "" | |
12034 | |
12035 #. type: Content of: <book><chapter><sect1><sect2><para> | |
12036 #: ../en/ch10-hook.xml:1593 | |
12037 msgid "" | |
12038 "This hook is run after a pre-existing changeset has been added to the " | |
12039 "repository, for example via a <command role=\"hg-cmd\">hg push</command>. If " | |
12040 "a group of changesets was added in a single operation, this hook is called " | |
12041 "once for each added changeset." | |
12042 msgstr "" | |
12043 | |
12044 #. type: Content of: <book><chapter><sect1><sect2><para> | |
12045 #: ../en/ch10-hook.xml:1600 | |
12046 msgid "" | |
12047 "You can use this hook for the same purposes as the <literal role=\"hook" | |
12048 "\">changegroup</literal> hook (section <xref linkend=\"sec.hook.changegroup\"/" | |
12049 ">); it's simply more convenient sometimes to run a hook once per group of " | |
12050 "changesets, while other times it's handier once per changeset." | |
12051 msgstr "" | |
12052 | |
12053 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
12054 #: ../en/ch10-hook.xml:1610 | |
12055 msgid "" | |
12056 "<literal>node</literal>: A changeset ID. The ID of the newly added changeset." | |
12057 msgstr "" | |
12058 | |
12059 #. type: Content of: <book><chapter><sect1><sect2><para> | |
12060 #: ../en/ch10-hook.xml:1626 | |
12061 msgid "" | |
12062 "See also: <literal role=\"hook\">changegroup</literal> (section <xref linkend=" | |
12063 "\"sec.hook.changegroup\"/>) <literal role=\"hook\">prechangegroup</literal> " | |
12064 "(section <xref linkend=\"sec.hook.prechangegroup\"/>), <literal role=\"hook" | |
12065 "\">pretxnchangegroup</literal> (section <xref linkend=\"sec.hook." | |
12066 "pretxnchangegroup\"/>)" | |
12067 msgstr "" | |
12068 | |
12069 #. type: Content of: <book><chapter><sect1><sect2><title> | |
12070 #: ../en/ch10-hook.xml:1636 | |
12071 msgid "" | |
12072 "<literal role=\"hook\">outgoing</literal>&emdash;after changesets are " | |
12073 "propagated" | |
12074 msgstr "" | |
12075 | |
12076 #. type: Content of: <book><chapter><sect1><sect2><para> | |
12077 #: ../en/ch10-hook.xml:1639 | |
12078 msgid "" | |
12079 "This hook is run after a group of changesets has been propagated out of this " | |
12080 "repository, for example by a <command role=\"hg-cmd\">hg push</command> or " | |
12081 "<command role=\"hg-cmd\">hg bundle</command> command." | |
12082 msgstr "" | |
12083 | |
12084 #. type: Content of: <book><chapter><sect1><sect2><para> | |
12085 #: ../en/ch10-hook.xml:1645 | |
12086 msgid "" | |
12087 "One possible use for this hook is to notify administrators that changes have " | |
12088 "been pulled." | |
12089 msgstr "" | |
12090 | |
12091 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
12092 #: ../en/ch10-hook.xml:1652 | |
12093 msgid "" | |
12094 "<literal>node</literal>: A changeset ID. The changeset ID of the first " | |
12095 "changeset of the group that was sent." | |
12096 msgstr "" | |
12097 | |
12098 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
12099 #: ../en/ch10-hook.xml:1657 | |
12100 msgid "" | |
12101 "<literal>source</literal>: A string. The source of the of the operation (see " | |
12102 "section <xref linkend=\"sec.hook.sources\"/>). If a remote client pulled " | |
12103 "changes from this repository, <literal>source</literal> will be " | |
12104 "<literal>serve</literal>. If the client that obtained changes from this " | |
12105 "repository was local, <literal>source</literal> will be <literal>bundle</" | |
12106 "literal>, <literal>pull</literal>, or <literal>push</literal>, depending on " | |
12107 "the operation the client performed." | |
12108 msgstr "" | |
12109 | |
12110 #. type: Content of: <book><chapter><sect1><sect2><para> | |
12111 #: ../en/ch10-hook.xml:1677 | |
12112 msgid "" | |
12113 "See also: <literal role=\"hook\">preoutgoing</literal> (section <xref linkend=" | |
12114 "\"sec.hook.preoutgoing\"/>)" | |
12115 msgstr "" | |
12116 | |
12117 #. type: Content of: <book><chapter><sect1><sect2><title> | |
12118 #: ../en/ch10-hook.xml:1683 | |
12119 msgid "" | |
12120 "<literal role=\"hook\">prechangegroup</literal>&emdash;before starting to add " | |
12121 "remote changesets" | |
12122 msgstr "" | |
12123 | |
12124 #. type: Content of: <book><chapter><sect1><sect2><para> | |
12125 #: ../en/ch10-hook.xml:1687 | |
12126 msgid "" | |
12127 "This controlling hook is run before Mercurial begins to add a group of " | |
12128 "changesets from another repository." | |
12129 msgstr "" | |
12130 | |
12131 #. type: Content of: <book><chapter><sect1><sect2><para> | |
12132 #: ../en/ch10-hook.xml:1691 | |
12133 msgid "" | |
12134 "This hook does not have any information about the changesets to be added, " | |
12135 "because it is run before transmission of those changesets is allowed to " | |
12136 "begin. If this hook fails, the changesets will not be transmitted." | |
12137 msgstr "" | |
12138 | |
12139 #. type: Content of: <book><chapter><sect1><sect2><para> | |
12140 #: ../en/ch10-hook.xml:1697 | |
12141 msgid "" | |
12142 "One use for this hook is to prevent external changes from being added to a " | |
12143 "repository. For example, you could use this to <quote>freeze</quote> a " | |
12144 "server-hosted branch temporarily or permanently so that users cannot push to " | |
12145 "it, while still allowing a local administrator to modify the repository." | |
12146 msgstr "" | |
12147 | |
12148 #. type: Content of: <book><chapter><sect1><sect2><para> | |
12149 #: ../en/ch10-hook.xml:1719 | |
12150 msgid "" | |
12151 "See also: <literal role=\"hook\">changegroup</literal> (section <xref linkend=" | |
12152 "\"sec.hook.changegroup\"/>), <literal role=\"hook\">incoming</literal> " | |
12153 "(section <xref linkend=\"sec.hook.incoming\"/>), , <literal role=\"hook" | |
12154 "\">pretxnchangegroup</literal> (section <xref linkend=\"sec.hook." | |
12155 "pretxnchangegroup\"/>)" | |
12156 msgstr "" | |
12157 | |
12158 #. type: Content of: <book><chapter><sect1><sect2><title> | |
12159 #: ../en/ch10-hook.xml:1729 | |
12160 msgid "" | |
12161 "<literal role=\"hook\">precommit</literal>&emdash;before starting to commit a " | |
12162 "changeset" | |
12163 msgstr "" | |
12164 | |
12165 #. type: Content of: <book><chapter><sect1><sect2><para> | |
12166 #: ../en/ch10-hook.xml:1732 | |
12167 msgid "" | |
12168 "This hook is run before Mercurial begins to commit a new changeset. It is run " | |
12169 "before Mercurial has any of the metadata for the commit, such as the files to " | |
12170 "be committed, the commit message, or the commit date." | |
12171 msgstr "" | |
12172 | |
12173 #. type: Content of: <book><chapter><sect1><sect2><para> | |
12174 #: ../en/ch10-hook.xml:1738 | |
12175 msgid "" | |
12176 "One use for this hook is to disable the ability to commit new changesets, " | |
12177 "while still allowing incoming changesets. Another is to run a build or test, " | |
12178 "and only allow the commit to begin if the build or test succeeds." | |
12179 msgstr "" | |
12180 | |
12181 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
12182 #: ../en/ch10-hook.xml:1747 | |
12183 msgid "" | |
12184 "<literal>parent1</literal>: A changeset ID. The changeset ID of the first " | |
12185 "parent of the working directory." | |
12186 msgstr "" | |
12187 | |
12188 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
12189 #: ../en/ch10-hook.xml:1752 | |
12190 msgid "" | |
12191 "<literal>parent2</literal>: A changeset ID. The changeset ID of the second " | |
12192 "parent of the working directory." | |
12193 msgstr "" | |
12194 | |
12195 #. type: Content of: <book><chapter><sect1><sect2><para> | |
12196 #: ../en/ch10-hook.xml:1757 | |
12197 msgid "" | |
12198 "If the commit proceeds, the parents of the working directory will become the " | |
12199 "parents of the new changeset." | |
12200 msgstr "" | |
12201 | |
12202 #. type: Content of: <book><chapter><sect1><sect2><para> | |
12203 #: ../en/ch10-hook.xml:1761 | |
12204 msgid "" | |
12205 "See also: <literal role=\"hook\">commit</literal> (section <xref linkend=" | |
12206 "\"sec.hook.commit\"/>), <literal role=\"hook\">pretxncommit</literal> " | |
12207 "(section <xref linkend=\"sec.hook.pretxncommit\"/>)" | |
12208 msgstr "" | |
12209 | |
12210 #. type: Content of: <book><chapter><sect1><sect2><title> | |
12211 #: ../en/ch10-hook.xml:1769 | |
12212 msgid "" | |
12213 "<literal role=\"hook\">preoutgoing</literal>&emdash;before starting to " | |
12214 "propagate changesets" | |
12215 msgstr "" | |
12216 | |
12217 #. type: Content of: <book><chapter><sect1><sect2><para> | |
12218 #: ../en/ch10-hook.xml:1772 | |
12219 msgid "" | |
12220 "This hook is invoked before Mercurial knows the identities of the changesets " | |
12221 "to be transmitted." | |
12222 msgstr "" | |
12223 | |
12224 #. type: Content of: <book><chapter><sect1><sect2><para> | |
12225 #: ../en/ch10-hook.xml:1776 | |
12226 msgid "" | |
12227 "One use for this hook is to prevent changes from being transmitted to another " | |
12228 "repository." | |
12229 msgstr "" | |
12230 | |
12231 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
12232 #: ../en/ch10-hook.xml:1783 | |
12233 msgid "" | |
12234 "<literal>source</literal>: A string. The source of the operation that is " | |
12235 "attempting to obtain changes from this repository (see section <xref linkend=" | |
12236 "\"sec.hook.sources\"/>). See the documentation for the <literal>source</" | |
12237 "literal> parameter to the <literal role=\"hook\">outgoing</literal> hook, in " | |
12238 "section <xref linkend=\"sec.hook.outgoing\"/>, for possible values of this " | |
12239 "parameter." | |
12240 msgstr "" | |
12241 | |
12242 #. type: Content of: <book><chapter><sect1><sect2><para> | |
12243 #: ../en/ch10-hook.xml:1801 | |
12244 msgid "" | |
12245 "See also: <literal role=\"hook\">outgoing</literal> (section <xref linkend=" | |
12246 "\"sec.hook.outgoing\"/>)" | |
12247 msgstr "" | |
12248 | |
12249 #. type: Content of: <book><chapter><sect1><sect2><title> | |
12250 #: ../en/ch10-hook.xml:1807 | |
12251 msgid "" | |
12252 "<literal role=\"hook\">pretag</literal>&emdash;before tagging a changeset" | |
12253 msgstr "" | |
12254 | |
12255 #. type: Content of: <book><chapter><sect1><sect2><para> | |
12256 #: ../en/ch10-hook.xml:1810 | |
12257 msgid "" | |
12258 "This controlling hook is run before a tag is created. If the hook succeeds, " | |
12259 "creation of the tag proceeds. If the hook fails, the tag is not created." | |
12260 msgstr "" | |
12261 | |
12262 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
12263 #: ../en/ch10-hook.xml:1818 | |
12264 msgid "" | |
12265 "<literal>local</literal>: A boolean. Whether the tag is local to this " | |
12266 "repository instance (i.e. stored in <filename role=\"special\">.hg/localtags</" | |
12267 "filename>) or managed by Mercurial (stored in <filename role=\"special\">." | |
12268 "hgtags</filename>)." | |
12269 msgstr "" | |
12270 | |
12271 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
12272 #: ../en/ch10-hook.xml:1825 | |
12273 msgid "" | |
12274 "<literal>node</literal>: A changeset ID. The ID of the changeset to be " | |
12275 "tagged." | |
12276 msgstr "" | |
12277 | |
12278 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
12279 #: ../en/ch10-hook.xml:1829 | |
12280 msgid "<literal>tag</literal>: A string. The name of the tag to be created." | |
12281 msgstr "" | |
12282 | |
12283 #. type: Content of: <book><chapter><sect1><sect2><para> | |
12284 #: ../en/ch10-hook.xml:1834 | |
12285 msgid "" | |
12286 "If the tag to be created is revision-controlled, the <literal role=\"hook" | |
12287 "\">precommit</literal> and <literal role=\"hook\">pretxncommit</literal> " | |
12288 "hooks (sections <xref linkend=\"sec.hook.commit\"/> and <xref linkend=\"sec." | |
12289 "hook.pretxncommit\"/>) will also be run." | |
12290 msgstr "" | |
12291 | |
12292 #. type: Content of: <book><chapter><sect1><sect2><para> | |
12293 #: ../en/ch10-hook.xml:1841 | |
12294 msgid "" | |
12295 "See also: <literal role=\"hook\">tag</literal> (section <xref linkend=\"sec." | |
12296 "hook.tag\"/>)" | |
12297 msgstr "" | |
12298 | |
12299 #. type: Content of: <book><chapter><sect1><sect2><title> | |
12300 #: ../en/ch10-hook.xml:1846 | |
12301 msgid "" | |
12302 "<literal role=\"hook\">pretxnchangegroup</literal>&emdash;before completing " | |
12303 "addition of remote changesets" | |
12304 msgstr "" | |
12305 | |
12306 #. type: Content of: <book><chapter><sect1><sect2><para> | |
12307 #: ../en/ch10-hook.xml:1850 | |
12308 msgid "" | |
12309 "This controlling hook is run before a transaction&emdash;that manages the " | |
12310 "addition of a group of new changesets from outside the repository&emdash;" | |
12311 "completes. If the hook succeeds, the transaction completes, and all of the " | |
12312 "changesets become permanent within this repository. If the hook fails, the " | |
12313 "transaction is rolled back, and the data for the changesets is erased." | |
12314 msgstr "" | |
12315 | |
12316 #. type: Content of: <book><chapter><sect1><sect2><para> | |
12317 #: ../en/ch10-hook.xml:1859 | |
12318 msgid "" | |
12319 "This hook can access the metadata associated with the almost-added " | |
12320 "changesets, but it should not do anything permanent with this data. It must " | |
12321 "also not modify the working directory." | |
12322 msgstr "" | |
12323 | |
12324 #. type: Content of: <book><chapter><sect1><sect2><para> | |
12325 #: ../en/ch10-hook.xml:1865 | |
12326 msgid "" | |
12327 "While this hook is running, if other Mercurial processes access this " | |
12328 "repository, they will be able to see the almost-added changesets as if they " | |
12329 "are permanent. This may lead to race conditions if you do not take steps to " | |
12330 "avoid them." | |
12331 msgstr "" | |
12332 | |
12333 #. type: Content of: <book><chapter><sect1><sect2><para> | |
12334 #: ../en/ch10-hook.xml:1872 | |
12335 msgid "" | |
12336 "This hook can be used to automatically vet a group of changesets. If the " | |
12337 "hook fails, all of the changesets are <quote>rejected</quote> when the " | |
12338 "transaction rolls back." | |
12339 msgstr "" | |
12340 | |
12341 #. type: Content of: <book><chapter><sect1><sect2><para> | |
12342 #: ../en/ch10-hook.xml:1902 | |
12343 msgid "" | |
12344 "See also: <literal role=\"hook\">changegroup</literal> (section <xref linkend=" | |
12345 "\"sec.hook.changegroup\"/>), <literal role=\"hook\">incoming</literal> " | |
12346 "(section <xref linkend=\"sec.hook.incoming\"/>), <literal role=\"hook" | |
12347 "\">prechangegroup</literal> (section <xref linkend=\"sec.hook.prechangegroup" | |
12348 "\"/>)" | |
12349 msgstr "" | |
12350 | |
12351 #. type: Content of: <book><chapter><sect1><sect2><title> | |
12352 #: ../en/ch10-hook.xml:1912 | |
12353 msgid "" | |
12354 "<literal role=\"hook\">pretxncommit</literal>&emdash;before completing commit " | |
12355 "of new changeset" | |
12356 msgstr "" | |
12357 | |
12358 #. type: Content of: <book><chapter><sect1><sect2><para> | |
12359 #: ../en/ch10-hook.xml:1915 | |
12360 msgid "" | |
12361 "This controlling hook is run before a transaction&emdash;that manages a new " | |
12362 "commit&emdash;completes. If the hook succeeds, the transaction completes and " | |
12363 "the changeset becomes permanent within this repository. If the hook fails, " | |
12364 "the transaction is rolled back, and the commit data is erased." | |
12365 msgstr "" | |
12366 | |
12367 #. type: Content of: <book><chapter><sect1><sect2><para> | |
12368 #: ../en/ch10-hook.xml:1923 | |
12369 msgid "" | |
12370 "This hook can access the metadata associated with the almost-new changeset, " | |
12371 "but it should not do anything permanent with this data. It must also not " | |
12372 "modify the working directory." | |
12373 msgstr "" | |
12374 | |
12375 #. type: Content of: <book><chapter><sect1><sect2><para> | |
12376 #: ../en/ch10-hook.xml:1929 | |
12377 msgid "" | |
12378 "While this hook is running, if other Mercurial processes access this " | |
12379 "repository, they will be able to see the almost-new changeset as if it is " | |
12380 "permanent. This may lead to race conditions if you do not take steps to " | |
12381 "avoid them." | |
12382 msgstr "" | |
12383 | |
12384 #. type: Content of: <book><chapter><sect1><sect2><para> | |
12385 #: ../en/ch10-hook.xml:1953 | |
12386 msgid "" | |
12387 "See also: <literal role=\"hook\">precommit</literal> (section <xref linkend=" | |
12388 "\"sec.hook.precommit\"/>)" | |
12389 msgstr "" | |
12390 | |
12391 #. type: Content of: <book><chapter><sect1><sect2><title> | |
12392 #: ../en/ch10-hook.xml:1959 | |
12393 msgid "" | |
12394 "<literal role=\"hook\">preupdate</literal>&emdash;before updating or merging " | |
12395 "working directory" | |
12396 msgstr "" | |
12397 | |
12398 #. type: Content of: <book><chapter><sect1><sect2><para> | |
12399 #: ../en/ch10-hook.xml:1962 | |
12400 msgid "" | |
12401 "This controlling hook is run before an update or merge of the working " | |
12402 "directory begins. It is run only if Mercurial's normal pre-update checks " | |
12403 "determine that the update or merge can proceed. If the hook succeeds, the " | |
12404 "update or merge may proceed; if it fails, the update or merge does not start." | |
12405 msgstr "" | |
12406 | |
12407 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
12408 #: ../en/ch10-hook.xml:1972 | |
12409 msgid "" | |
12410 "<literal>parent1</literal>: A changeset ID. The ID of the parent that the " | |
12411 "working directory is to be updated to. If the working directory is being " | |
12412 "merged, it will not change this parent." | |
12413 msgstr "" | |
12414 | |
12415 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
12416 #: ../en/ch10-hook.xml:1978 | |
12417 msgid "" | |
12418 "<literal>parent2</literal>: A changeset ID. Only set if the working " | |
12419 "directory is being merged. The ID of the revision that the working directory " | |
12420 "is being merged with." | |
12421 msgstr "" | |
12422 | |
12423 #. type: Content of: <book><chapter><sect1><sect2><para> | |
12424 #: ../en/ch10-hook.xml:1985 | |
12425 msgid "" | |
12426 "See also: <literal role=\"hook\">update</literal> (section <xref linkend=" | |
12427 "\"sec.hook.update\"/>)" | |
12428 msgstr "" | |
12429 | |
12430 #. type: Content of: <book><chapter><sect1><sect2><title> | |
12431 #: ../en/ch10-hook.xml:1991 | |
12432 msgid "<literal role=\"hook\">tag</literal>&emdash;after tagging a changeset" | |
12433 msgstr "" | |
12434 | |
12435 #. type: Content of: <book><chapter><sect1><sect2><para> | |
12436 #: ../en/ch10-hook.xml:1994 | |
12437 msgid "This hook is run after a tag has been created." | |
12438 msgstr "" | |
12439 | |
12440 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
12441 #: ../en/ch10-hook.xml:2000 | |
12442 msgid "" | |
12443 "<literal>local</literal>: A boolean. Whether the new tag is local to this " | |
12444 "repository instance (i.e. stored in <filename role=\"special\">.hg/" | |
12445 "localtags</filename>) or managed by Mercurial (stored in <filename role=" | |
12446 "\"special\">.hgtags</filename>)." | |
12447 msgstr "" | |
12448 | |
12449 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
12450 #: ../en/ch10-hook.xml:2008 | |
12451 msgid "" | |
12452 "<literal>node</literal>: A changeset ID. The ID of the changeset that was " | |
12453 "tagged." | |
12454 msgstr "" | |
12455 | |
12456 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
12457 #: ../en/ch10-hook.xml:2012 | |
12458 msgid "<literal>tag</literal>: A string. The name of the tag that was created." | |
12459 msgstr "" | |
12460 | |
12461 #. type: Content of: <book><chapter><sect1><sect2><para> | |
12462 #: ../en/ch10-hook.xml:2017 | |
12463 msgid "" | |
12464 "If the created tag is revision-controlled, the <literal role=\"hook\">commit</" | |
12465 "literal> hook (section <xref linkend=\"sec.hook.commit\"/>) is run before " | |
12466 "this hook." | |
12467 msgstr "" | |
12468 | |
12469 #. type: Content of: <book><chapter><sect1><sect2><para> | |
12470 #: ../en/ch10-hook.xml:2022 | |
12471 msgid "" | |
12472 "See also: <literal role=\"hook\">pretag</literal> (section <xref linkend=" | |
12473 "\"sec.hook.pretag\"/>)" | |
12474 msgstr "" | |
12475 | |
12476 #. type: Content of: <book><chapter><sect1><sect2><title> | |
12477 #: ../en/ch10-hook.xml:2028 | |
12478 msgid "" | |
12479 "<literal role=\"hook\">update</literal>&emdash;after updating or merging " | |
12480 "working directory" | |
12481 msgstr "" | |
12482 | |
12483 #. type: Content of: <book><chapter><sect1><sect2><para> | |
12484 #: ../en/ch10-hook.xml:2031 | |
12485 msgid "" | |
12486 "This hook is run after an update or merge of the working directory " | |
12487 "completes. Since a merge can fail (if the external <command>hgmerge</" | |
12488 "command> command fails to resolve conflicts in a file), this hook " | |
12489 "communicates whether the update or merge completed cleanly." | |
12490 msgstr "" | |
12491 | |
12492 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
12493 #: ../en/ch10-hook.xml:2039 | |
12494 msgid "" | |
12495 "<literal>error</literal>: A boolean. Indicates whether the update or merge " | |
12496 "completed successfully." | |
12497 msgstr "" | |
12498 | |
12499 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
12500 #: ../en/ch10-hook.xml:2044 | |
12501 msgid "" | |
12502 "<literal>parent1</literal>: A changeset ID. The ID of the parent that the " | |
12503 "working directory was updated to. If the working directory was merged, it " | |
12504 "will not have changed this parent." | |
12505 msgstr "" | |
12506 | |
12507 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
12508 #: ../en/ch10-hook.xml:2050 | |
12509 msgid "" | |
12510 "<literal>parent2</literal>: A changeset ID. Only set if the working " | |
12511 "directory was merged. The ID of the revision that the working directory was " | |
12512 "merged with." | |
12513 msgstr "" | |
12514 | |
12515 #. type: Content of: <book><chapter><sect1><sect2><para> | |
12516 #: ../en/ch10-hook.xml:2056 | |
12517 msgid "" | |
12518 "See also: <literal role=\"hook\">preupdate</literal> (section <xref linkend=" | |
12519 "\"sec.hook.preupdate\"/>)" | |
12520 msgstr "" | |
12521 | |
12522 #. type: Content of: <book><chapter><title> | |
12523 #: ../en/ch11-template.xml:5 | |
12524 msgid "Customising the output of Mercurial" | |
12525 msgstr "定制 Mercurial 的输出" | |
12526 | |
12527 #. type: Content of: <book><chapter><para> | |
12528 #: ../en/ch11-template.xml:7 | |
12529 msgid "" | |
12530 "Mercurial provides a powerful mechanism to let you control how it displays " | |
12531 "information. The mechanism is based on templates. You can use templates to " | |
12532 "generate specific output for a single command, or to customise the entire " | |
12533 "appearance of the built-in web interface." | |
12534 msgstr "" | |
12535 | |
12536 #. type: Content of: <book><chapter><sect1><title> | |
12537 #: ../en/ch11-template.xml:14 | |
12538 msgid "Using precanned output styles" | |
12539 msgstr "" | |
12540 | |
12541 #. type: Content of: <book><chapter><sect1><para> | |
12542 #: ../en/ch11-template.xml:16 | |
12543 msgid "" | |
12544 "Packaged with Mercurial are some output styles that you can use immediately. " | |
12545 "A style is simply a precanned template that someone wrote and installed " | |
12546 "somewhere that Mercurial can find." | |
12547 msgstr "" | |
12548 | |
12549 #. type: Content of: <book><chapter><sect1><para> | |
12550 #: ../en/ch11-template.xml:21 | |
12551 msgid "" | |
12552 "Before we take a look at Mercurial's bundled styles, let's review its normal " | |
12553 "output." | |
12554 msgstr "" | |
12555 | |
12556 #. type: Content of: <book><chapter><sect1><para> | |
12557 #: ../en/ch11-template.xml:26 | |
12558 msgid "" | |
12559 "This is somewhat informative, but it takes up a lot of space&emdash;five " | |
12560 "lines of output per changeset. The <literal>compact</literal> style reduces " | |
12561 "this to three lines, presented in a sparse manner." | |
12562 msgstr "" | |
12563 | |
12564 #. type: Content of: <book><chapter><sect1><para> | |
12565 #: ../en/ch11-template.xml:33 | |
12566 msgid "" | |
12567 "The <literal>changelog</literal> style hints at the expressive power of " | |
12568 "Mercurial's templating engine. This style attempts to follow the GNU " | |
12569 "Project's changelog guidelines<citation>web:changelog</citation>." | |
12570 msgstr "" | |
12571 | |
12572 #. type: Content of: <book><chapter><sect1><para> | |
12573 #: ../en/ch11-template.xml:40 | |
12574 msgid "" | |
12575 "You will not be shocked to learn that Mercurial's default output style is " | |
12576 "named <literal>default</literal>." | |
12577 msgstr "" | |
12578 | |
12579 #. type: Content of: <book><chapter><sect1><sect2><title> | |
12580 #: ../en/ch11-template.xml:44 | |
12581 msgid "Setting a default style" | |
12582 msgstr "" | |
12583 | |
12584 #. type: Content of: <book><chapter><sect1><sect2><para> | |
12585 #: ../en/ch11-template.xml:46 | |
12586 msgid "" | |
12587 "You can modify the output style that Mercurial will use for every command by " | |
12588 "editing your <filename role=\"special\"> /.hgrc</filename>\\ file, naming the " | |
12589 "style you would prefer to use." | |
12590 msgstr "" | |
12591 | |
12592 #. type: Content of: <book><chapter><sect1><sect2><para> | |
12593 #: ../en/ch11-template.xml:53 | |
12594 msgid "" | |
12595 "If you write a style of your own, you can use it by either providing the path " | |
12596 "to your style file, or copying your style file into a location where " | |
12597 "Mercurial can find it (typically the <literal>templates</literal> " | |
12598 "subdirectory of your Mercurial install directory)." | |
12599 msgstr "" | |
12600 | |
12601 #. type: Content of: <book><chapter><sect1><title> | |
12602 #: ../en/ch11-template.xml:62 | |
12603 msgid "Commands that support styles and templates" | |
12604 msgstr "" | |
12605 | |
12606 #. type: Content of: <book><chapter><sect1><para> | |
12607 #: ../en/ch11-template.xml:64 | |
12608 msgid "" | |
12609 "All of Mercurial's <quote><literal>log</literal>-like</quote> commands let " | |
12610 "you use styles and templates: <command role=\"hg-cmd\">hg incoming</command>, " | |
12611 "<command role=\"hg-cmd\">hg log</command>, <command role=\"hg-cmd\">hg " | |
12612 "outgoing</command>, and <command role=\"hg-cmd\">hg tip</command>." | |
12613 msgstr "" | |
12614 | |
12615 #. type: Content of: <book><chapter><sect1><para> | |
12616 #: ../en/ch11-template.xml:71 | |
12617 msgid "" | |
12618 "As I write this manual, these are so far the only commands that support " | |
12619 "styles and templates. Since these are the most important commands that need " | |
12620 "customisable output, there has been little pressure from the Mercurial user " | |
12621 "community to add style and template support to other commands." | |
12622 msgstr "" | |
12623 | |
12624 #. type: Content of: <book><chapter><sect1><title> | |
12625 #: ../en/ch11-template.xml:79 | |
12626 msgid "The basics of templating" | |
12627 msgstr "" | |
12628 | |
12629 #. type: Content of: <book><chapter><sect1><para> | |
12630 #: ../en/ch11-template.xml:81 | |
12631 msgid "" | |
12632 "At its simplest, a Mercurial template is a piece of text. Some of the text " | |
12633 "never changes, while other parts are <emphasis>expanded</emphasis>, or " | |
12634 "replaced with new text, when necessary." | |
12635 msgstr "" | |
12636 | |
12637 #. type: Content of: <book><chapter><sect1><para> | |
12638 #: ../en/ch11-template.xml:86 | |
12639 msgid "" | |
12640 "Before we continue, let's look again at a simple example of Mercurial's " | |
12641 "normal output." | |
12642 msgstr "" | |
12643 | |
12644 #. type: Content of: <book><chapter><sect1><para> | |
12645 #: ../en/ch11-template.xml:91 | |
12646 msgid "" | |
12647 "Now, let's run the same command, but using a template to change its output." | |
12648 msgstr "" | |
12649 | |
12650 #. type: Content of: <book><chapter><sect1><para> | |
12651 #: ../en/ch11-template.xml:96 | |
12652 msgid "" | |
12653 "The example above illustrates the simplest possible template; it's just a " | |
12654 "piece of static text, printed once for each changeset. The <option role=\"hg-" | |
12655 "opt-log\">--template</option> option to the <command role=\"hg-cmd\">hg log</" | |
12656 "command> command tells Mercurial to use the given text as the template when " | |
12657 "printing each changeset." | |
12658 msgstr "" | |
12659 | |
12660 #. type: Content of: <book><chapter><sect1><para> | |
12661 #: ../en/ch11-template.xml:104 | |
12662 msgid "" | |
12663 "Notice that the template string above ends with the text <quote><literal>\\n</" | |
12664 "literal></quote>. This is an <emphasis>escape sequence</emphasis>, telling " | |
12665 "Mercurial to print a newline at the end of each template item. If you omit " | |
12666 "this newline, Mercurial will run each piece of output together. See section " | |
12667 "<xref linkend=\"sec.template.escape\"/> for more details of escape sequences." | |
12668 msgstr "" | |
12669 | |
12670 #. type: Content of: <book><chapter><sect1><para> | |
12671 #: ../en/ch11-template.xml:112 | |
12672 msgid "" | |
12673 "A template that prints a fixed string of text all the time isn't very useful; " | |
12674 "let's try something a bit more complex." | |
12675 msgstr "" | |
12676 | |
12677 #. type: Content of: <book><chapter><sect1><para> | |
12678 #: ../en/ch11-template.xml:118 | |
12679 msgid "" | |
12680 "As you can see, the string <quote><literal>{desc}</literal></quote> in the " | |
12681 "template has been replaced in the output with the description of each " | |
12682 "changeset. Every time Mercurial finds text enclosed in curly braces " | |
12683 "(<quote><literal>{</literal></quote> and <quote><literal>}</literal></" | |
12684 "quote>), it will try to replace the braces and text with the expansion of " | |
12685 "whatever is inside. To print a literal curly brace, you must escape it, as " | |
12686 "described in section <xref linkend=\"sec.template.escape\"/>." | |
12687 msgstr "" | |
12688 | |
12689 #. type: Content of: <book><chapter><sect1><title> | |
12690 #: ../en/ch11-template.xml:131 | |
12691 msgid "Common template keywords" | |
12692 msgstr "" | |
12693 | |
12694 #. type: Content of: <book><chapter><sect1><para> | |
12695 #: ../en/ch11-template.xml:133 | |
12696 msgid "" | |
12697 "You can start writing simple templates immediately using the keywords below." | |
12698 msgstr "" | |
12699 | |
12700 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
12701 #: ../en/ch11-template.xml:137 | |
12702 msgid "" | |
12703 "<literal role=\"template-keyword\">author</literal>: String. The unmodified " | |
12704 "author of the changeset." | |
12705 msgstr "" | |
12706 | |
12707 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
12708 #: ../en/ch11-template.xml:141 | |
12709 msgid "" | |
12710 "<literal role=\"template-keyword\">branches</literal>: String. The name of " | |
12711 "the branch on which the changeset was committed. Will be empty if the branch " | |
12712 "name was <literal>default</literal>." | |
12713 msgstr "" | |
12714 | |
12715 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
12716 #: ../en/ch11-template.xml:147 | |
12717 msgid "" | |
12718 "<literal role=\"template-keyword\">date</literal>: Date information. The " | |
12719 "date when the changeset was committed. This is <emphasis>not</emphasis> " | |
12720 "human-readable; you must pass it through a filter that will render it " | |
12721 "appropriately. See section <xref linkend=\"sec.template.filter\"/> for more " | |
12722 "information on filters. The date is expressed as a pair of numbers. The " | |
12723 "first number is a Unix UTC timestamp (seconds since January 1, 1970); the " | |
12724 "second is the offset of the committer's timezone from UTC, in seconds." | |
12725 msgstr "" | |
12726 | |
12727 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
12728 #: ../en/ch11-template.xml:158 | |
12729 msgid "" | |
12730 "<literal role=\"template-keyword\">desc</literal>: String. The text of the " | |
12731 "changeset description." | |
12732 msgstr "" | |
12733 | |
12734 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
12735 #: ../en/ch11-template.xml:161 | |
12736 msgid "" | |
12737 "<literal role=\"template-keyword\">files</literal>: List of strings. All " | |
12738 "files modified, added, or removed by this changeset." | |
12739 msgstr "" | |
12740 | |
12741 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
12742 #: ../en/ch11-template.xml:166 | |
12743 msgid "" | |
12744 "<literal role=\"template-keyword\">file_adds</literal>: List of strings. " | |
12745 "Files added by this changeset." | |
12746 msgstr "" | |
12747 | |
12748 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
12749 #: ../en/ch11-template.xml:170 | |
12750 msgid "" | |
12751 "<literal role=\"template-keyword\">file_dels</literal>: List of strings. " | |
12752 "Files removed by this changeset." | |
12753 msgstr "" | |
12754 | |
12755 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
12756 #: ../en/ch11-template.xml:174 | |
12757 msgid "" | |
12758 "<literal role=\"template-keyword\">node</literal>: String. The changeset " | |
12759 "identification hash, as a 40-character hexadecimal string." | |
12760 msgstr "" | |
12761 | |
12762 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
12763 #: ../en/ch11-template.xml:178 | |
12764 msgid "" | |
12765 "<literal role=\"template-keyword\">parents</literal>: List of strings. The " | |
12766 "parents of the changeset." | |
12767 msgstr "" | |
12768 | |
12769 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
12770 #: ../en/ch11-template.xml:182 | |
12771 msgid "" | |
12772 "<literal role=\"template-keyword\">rev</literal>: Integer. The repository-" | |
12773 "local changeset revision number." | |
12774 msgstr "" | |
12775 | |
12776 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
12777 #: ../en/ch11-template.xml:186 | |
12778 msgid "" | |
12779 "<literal role=\"template-keyword\">tags</literal>: List of strings. Any tags " | |
12780 "associated with the changeset." | |
12781 msgstr "" | |
12782 | |
12783 #. type: Content of: <book><chapter><sect1><para> | |
12784 #: ../en/ch11-template.xml:191 | |
12785 msgid "" | |
12786 "A few simple experiments will show us what to expect when we use these " | |
12787 "keywords; you can see the results below." | |
12788 msgstr "" | |
12789 | |
12790 #. type: Content of: <book><chapter><sect1><para> | |
12791 #: ../en/ch11-template.xml:196 | |
12792 msgid "" | |
12793 "As we noted above, the date keyword does not produce human-readable output, " | |
12794 "so we must treat it specially. This involves using a <emphasis>filter</" | |
12795 "emphasis>, about which more in section <xref linkend=\"sec.template.filter\"/" | |
12796 ">." | |
12797 msgstr "" | |
12798 | |
12799 #. type: Content of: <book><chapter><sect1><title> | |
12800 #: ../en/ch11-template.xml:206 | |
12801 msgid "Escape sequences" | |
12802 msgstr "" | |
12803 | |
12804 #. type: Content of: <book><chapter><sect1><para> | |
12805 #: ../en/ch11-template.xml:208 | |
12806 msgid "" | |
12807 "Mercurial's templating engine recognises the most commonly used escape " | |
12808 "sequences in strings. When it sees a backslash (<quote><literal>\\</" | |
12809 "literal></quote>) character, it looks at the following character and " | |
12810 "substitutes the two characters with a single replacement, as described below." | |
12811 msgstr "" | |
12812 | |
12813 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
12814 #: ../en/ch11-template.xml:215 | |
12815 msgid "" | |
12816 "<literal>\\textbackslash\\textbackslash</literal>: Backslash, <quote><literal>" | |
12817 "\\</literal></quote>, ASCII 134." | |
12818 msgstr "" | |
12819 | |
12820 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
12821 #: ../en/ch11-template.xml:219 | |
12822 msgid "<literal>\\textbackslash n</literal>: Newline, ASCII 12." | |
12823 msgstr "" | |
12824 | |
12825 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
12826 #: ../en/ch11-template.xml:222 | |
12827 msgid "<literal>\\textbackslash r</literal>: Carriage return, ASCII 15." | |
12828 msgstr "" | |
12829 | |
12830 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
12831 #: ../en/ch11-template.xml:225 | |
12832 msgid "<literal>\\textbackslash t</literal>: Tab, ASCII 11." | |
12833 msgstr "" | |
12834 | |
12835 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
12836 #: ../en/ch11-template.xml:228 | |
12837 msgid "<literal>\\textbackslash v</literal>: Vertical tab, ASCII 13." | |
12838 msgstr "" | |
12839 | |
12840 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
12841 #: ../en/ch11-template.xml:231 | |
12842 msgid "" | |
12843 "<literal>\\textbackslash {</literal>: Open curly brace, <quote><literal>{</" | |
12844 "literal></quote>, ASCII 173." | |
12845 msgstr "" | |
12846 | |
12847 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
12848 #: ../en/ch11-template.xml:235 | |
12849 msgid "" | |
12850 "<literal>\\textbackslash }</literal>: Close curly brace, <quote><literal>}</" | |
12851 "literal></quote>, ASCII 175." | |
12852 msgstr "" | |
12853 | |
12854 #. type: Content of: <book><chapter><sect1><para> | |
12855 #: ../en/ch11-template.xml:240 | |
12856 msgid "" | |
12857 "As indicated above, if you want the expansion of a template to contain a " | |
12858 "literal <quote><literal>\\</literal></quote>, <quote><literal>{</literal></" | |
12859 "quote>, or <quote><literal>{</literal></quote> character, you must escape it." | |
12860 msgstr "" | |
12861 | |
12862 #. type: Content of: <book><chapter><sect1><title> | |
12863 #: ../en/ch11-template.xml:248 | |
12864 msgid "Filtering keywords to change their results" | |
12865 msgstr "" | |
12866 | |
12867 #. type: Content of: <book><chapter><sect1><para> | |
12868 #: ../en/ch11-template.xml:250 | |
12869 msgid "" | |
12870 "Some of the results of template expansion are not immediately easy to use. " | |
12871 "Mercurial lets you specify an optional chain of <emphasis>filters</emphasis> " | |
12872 "to modify the result of expanding a keyword. You have already seen a common " | |
12873 "filter, <literal role=\"template-kw-filt-date\">isodate</literal>, in action " | |
12874 "above, to make a date readable." | |
12875 msgstr "" | |
12876 | |
12877 #. type: Content of: <book><chapter><sect1><para> | |
12878 #: ../en/ch11-template.xml:257 | |
12879 msgid "" | |
12880 "Below is a list of the most commonly used filters that Mercurial supports. " | |
12881 "While some filters can be applied to any text, others can only be used in " | |
12882 "specific circumstances. The name of each filter is followed first by an " | |
12883 "indication of where it can be used, then a description of its effect." | |
12884 msgstr "" | |
12885 | |
12886 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
12887 #: ../en/ch11-template.xml:264 | |
12888 msgid "" | |
12889 "<literal role=\"template-filter\">addbreaks</literal>: Any text. Add an XHTML " | |
12890 "<quote><literal><br/></literal></quote> tag before the end of every " | |
12891 "line except the last. For example, <quote><literal>foo\\nbar</literal></" | |
12892 "quote> becomes <quote><literal>foo<br/>\\nbar</literal></quote>." | |
12893 msgstr "" | |
12894 | |
12895 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
12896 #: ../en/ch11-template.xml:271 | |
12897 msgid "" | |
12898 "<literal role=\"template-kw-filt-date\">age</literal>: <literal role=" | |
12899 "\"template-keyword\">date</literal> keyword. Render the age of the date, " | |
12900 "relative to the current time. Yields a string like <quote><literal>10 " | |
12901 "minutes</literal></quote>." | |
12902 msgstr "" | |
12903 | |
12904 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
12905 #: ../en/ch11-template.xml:278 | |
12906 msgid "" | |
12907 "<literal role=\"template-filter\">basename</literal>: Any text, but most " | |
12908 "useful for the <literal role=\"template-keyword\">files</literal> keyword and " | |
12909 "its relatives. Treat the text as a path, and return the basename. For " | |
12910 "example, <quote><literal>foo/bar/baz</literal></quote> becomes " | |
12911 "<quote><literal>baz</literal></quote>." | |
12912 msgstr "" | |
12913 | |
12914 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
12915 #: ../en/ch11-template.xml:287 | |
12916 msgid "" | |
12917 "<literal role=\"template-kw-filt-date\">date</literal>: <literal role=" | |
12918 "\"template-keyword\">date</literal> keyword. Render a date in a similar " | |
12919 "format to the Unix <literal role=\"template-keyword\">date</literal> command, " | |
12920 "but with timezone included. Yields a string like <quote><literal>Mon Sep 04 " | |
12921 "15:13:13 2006 -0700</literal></quote>." | |
12922 msgstr "" | |
12923 | |
12924 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
12925 #: ../en/ch11-template.xml:295 | |
12926 msgid "" | |
12927 "<literal role=\"template-kw-filt-author\">domain</literal>: Any text, but " | |
12928 "most useful for the <literal role=\"template-keyword\">author</literal> " | |
12929 "keyword. Finds the first string that looks like an email address, and " | |
12930 "extract just the domain component. For example, <quote><literal>Bryan " | |
12931 "O'Sullivan <bos@serpentine.com></literal></quote> becomes " | |
12932 "<quote><literal>serpentine.com</literal></quote>." | |
12933 msgstr "" | |
12934 | |
12935 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
12936 #: ../en/ch11-template.xml:305 | |
12937 msgid "" | |
12938 "<literal role=\"template-kw-filt-author\">email</literal>: Any text, but most " | |
12939 "useful for the <literal role=\"template-keyword\">author</literal> keyword. " | |
12940 "Extract the first string that looks like an email address. For example, " | |
12941 "<quote><literal>Bryan O'Sullivan <bos@serpentine.com></literal></quote> " | |
12942 "becomes <quote><literal>bos@serpentine.com</literal></quote>." | |
12943 msgstr "" | |
12944 | |
12945 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
12946 #: ../en/ch11-template.xml:314 | |
12947 msgid "" | |
12948 "<literal role=\"template-filter\">escape</literal>: Any text. Replace the " | |
12949 "special XML/XHTML characters <quote><literal>&</literal></quote>, " | |
12950 "<quote><literal><</literal></quote> and <quote><literal>></literal></" | |
12951 "quote> with XML entities." | |
12952 msgstr "" | |
12953 | |
12954 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
12955 #: ../en/ch11-template.xml:322 | |
12956 msgid "" | |
12957 "<literal role=\"template-filter\">fill68</literal>: Any text. Wrap the text " | |
12958 "to fit in 68 columns. This is useful before you pass text through the " | |
12959 "<literal role=\"template-filter\">tabindent</literal> filter, and still want " | |
12960 "it to fit in an 80-column fixed-font window." | |
12961 msgstr "" | |
12962 | |
12963 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
12964 #: ../en/ch11-template.xml:330 | |
12965 msgid "" | |
12966 "<literal role=\"template-filter\">fill76</literal>: Any text. Wrap the text " | |
12967 "to fit in 76 columns." | |
12968 msgstr "" | |
12969 | |
12970 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
12971 #: ../en/ch11-template.xml:334 | |
12972 msgid "" | |
12973 "<literal role=\"template-filter\">firstline</literal>: Any text. Yield the " | |
12974 "first line of text, without any trailing newlines." | |
12975 msgstr "" | |
12976 | |
12977 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
12978 #: ../en/ch11-template.xml:339 | |
12979 msgid "" | |
12980 "<literal role=\"template-kw-filt-date\">hgdate</literal>: <literal role=" | |
12981 "\"template-keyword\">date</literal> keyword. Render the date as a pair of " | |
12982 "readable numbers. Yields a string like <quote><literal>1157407993 25200</" | |
12983 "literal></quote>." | |
12984 msgstr "" | |
12985 | |
12986 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
12987 #: ../en/ch11-template.xml:346 | |
12988 msgid "" | |
12989 "<literal role=\"template-kw-filt-date\">isodate</literal>: <literal role=" | |
12990 "\"template-keyword\">date</literal> keyword. Render the date as a text " | |
12991 "string in ISO 8601 format. Yields a string like <quote><literal>2006-09-04 " | |
12992 "15:13:13 -0700</literal></quote>." | |
12993 msgstr "" | |
12994 | |
12995 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
12996 #: ../en/ch11-template.xml:353 | |
12997 msgid "" | |
12998 "<literal role=\"template-filter\">obfuscate</literal>: Any text, but most " | |
12999 "useful for the <literal role=\"template-keyword\">author</literal> keyword. " | |
13000 "Yield the input text rendered as a sequence of XML entities. This helps to " | |
13001 "defeat some particularly stupid screen-scraping email harvesting spambots." | |
13002 msgstr "" | |
13003 | |
13004 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
13005 #: ../en/ch11-template.xml:361 | |
13006 msgid "" | |
13007 "<literal role=\"template-kw-filt-author\">person</literal>: Any text, but " | |
13008 "most useful for the <literal role=\"template-keyword\">author</literal> " | |
13009 "keyword. Yield the text before an email address. For example, " | |
13010 "<quote><literal>Bryan O'Sullivan <bos@serpentine.com></literal></quote> " | |
13011 "becomes <quote><literal>Bryan O'Sullivan</literal></quote>." | |
13012 msgstr "" | |
13013 | |
13014 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
13015 #: ../en/ch11-template.xml:370 | |
13016 msgid "" | |
13017 "<literal role=\"template-kw-filt-date\">rfc822date</literal>: <literal role=" | |
13018 "\"template-keyword\">date</literal> keyword. Render a date using the same " | |
13019 "format used in email headers. Yields a string like <quote><literal>Mon, 04 " | |
13020 "Sep 2006 15:13:13 -0700</literal></quote>." | |
13021 msgstr "" | |
13022 | |
13023 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
13024 #: ../en/ch11-template.xml:377 | |
13025 msgid "" | |
13026 "<literal role=\"template-kw-filt-node\">short</literal>: Changeset hash. " | |
13027 "Yield the short form of a changeset hash, i.e. a 12-character hexadecimal " | |
13028 "string." | |
13029 msgstr "" | |
13030 | |
13031 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
13032 #: ../en/ch11-template.xml:382 | |
13033 msgid "" | |
13034 "<literal role=\"template-kw-filt-date\">shortdate</literal>: <literal role=" | |
13035 "\"template-keyword\">date</literal> keyword. Render the year, month, and day " | |
13036 "of the date. Yields a string like <quote><literal>2006-09-04</literal></" | |
13037 "quote>." | |
13038 msgstr "" | |
13039 | |
13040 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
13041 #: ../en/ch11-template.xml:388 | |
13042 msgid "" | |
13043 "<literal role=\"template-filter\">strip</literal>: Any text. Strip all " | |
13044 "leading and trailing whitespace from the string." | |
13045 msgstr "" | |
13046 | |
13047 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
13048 #: ../en/ch11-template.xml:392 | |
13049 msgid "" | |
13050 "<literal role=\"template-filter\">tabindent</literal>: Any text. Yield the " | |
13051 "text, with every line except the first starting with a tab character." | |
13052 msgstr "" | |
13053 | |
13054 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
13055 #: ../en/ch11-template.xml:397 | |
13056 msgid "" | |
13057 "<literal role=\"template-filter\">urlescape</literal>: Any text. Escape all " | |
13058 "characters that are considered <quote>special</quote> by URL parsers. For " | |
13059 "example, <literal>foo bar</literal> becomes <literal>foo%20bar</literal>." | |
13060 msgstr "" | |
13061 | |
13062 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
13063 #: ../en/ch11-template.xml:404 | |
13064 msgid "" | |
13065 "<literal role=\"template-kw-filt-author\">user</literal>: Any text, but most " | |
13066 "useful for the <literal role=\"template-keyword\">author</literal> keyword. " | |
13067 "Return the <quote>user</quote> portion of an email address. For example, " | |
13068 "<quote><literal>Bryan O'Sullivan <bos@serpentine.com></literal></quote> " | |
13069 "becomes <quote><literal>bos</literal></quote>." | |
13070 msgstr "" | |
13071 | |
13072 #. type: Content of: <book><chapter><sect1><note><para> | |
13073 #: ../en/ch11-template.xml:417 | |
13074 msgid "" | |
13075 "If you try to apply a filter to a piece of data that it cannot process, " | |
13076 "Mercurial will fail and print a Python exception. For example, trying to run " | |
13077 "the output of the <literal role=\"template-keyword\">desc</literal> keyword " | |
13078 "into the <literal role=\"template-kw-filt-date\">isodate</literal> filter is " | |
13079 "not a good idea." | |
13080 msgstr "" | |
13081 | |
13082 #. type: Content of: <book><chapter><sect1><sect2><title> | |
13083 #: ../en/ch11-template.xml:426 | |
13084 msgid "Combining filters" | |
13085 msgstr "" | |
13086 | |
13087 #. type: Content of: <book><chapter><sect1><sect2><para> | |
13088 #: ../en/ch11-template.xml:428 | |
13089 msgid "" | |
13090 "It is easy to combine filters to yield output in the form you would like. " | |
13091 "The following chain of filters tidies up a description, then makes sure that " | |
13092 "it fits cleanly into 68 columns, then indents it by a further 8 characters " | |
13093 "(at least on Unix-like systems, where a tab is conventionally 8 characters " | |
13094 "wide)." | |
13095 msgstr "" | |
13096 | |
13097 #. type: Content of: <book><chapter><sect1><sect2><para> | |
13098 #: ../en/ch11-template.xml:437 | |
13099 msgid "" | |
13100 "Note the use of <quote><literal>\\t</literal></quote> (a tab character) in " | |
13101 "the template to force the first line to be indented; this is necessary since " | |
13102 "<literal role=\"template-keyword\">tabindent</literal> indents all lines " | |
13103 "<emphasis>except</emphasis> the first." | |
13104 msgstr "" | |
13105 | |
13106 #. type: Content of: <book><chapter><sect1><sect2><para> | |
13107 #: ../en/ch11-template.xml:443 | |
13108 msgid "" | |
13109 "Keep in mind that the order of filters in a chain is significant. The first " | |
13110 "filter is applied to the result of the keyword; the second to the result of " | |
13111 "the first filter; and so on. For example, using <literal>fill68|tabindent</" | |
13112 "literal> gives very different results from <literal>tabindent|fill68</" | |
13113 "literal>." | |
13114 msgstr "" | |
13115 | |
13116 #. type: Content of: <book><chapter><sect1><title> | |
13117 #: ../en/ch11-template.xml:454 | |
13118 msgid "From templates to styles" | |
13119 msgstr "" | |
13120 | |
13121 #. type: Content of: <book><chapter><sect1><para> | |
13122 #: ../en/ch11-template.xml:456 | |
13123 msgid "" | |
13124 "A command line template provides a quick and simple way to format some " | |
13125 "output. Templates can become verbose, though, and it's useful to be able to " | |
13126 "give a template a name. A style file is a template with a name, stored in a " | |
13127 "file." | |
13128 msgstr "" | |
13129 | |
13130 #. type: Content of: <book><chapter><sect1><para> | |
13131 #: ../en/ch11-template.xml:461 | |
13132 msgid "" | |
13133 "More than that, using a style file unlocks the power of Mercurial's " | |
13134 "templating engine in ways that are not possible using the command line " | |
13135 "<option role=\"hg-opt-log\">--template</option> option." | |
13136 msgstr "" | |
13137 | |
13138 #. type: Content of: <book><chapter><sect1><sect2><title> | |
13139 #: ../en/ch11-template.xml:467 | |
13140 msgid "The simplest of style files" | |
13141 msgstr "" | |
13142 | |
13143 #. type: Content of: <book><chapter><sect1><sect2><para> | |
13144 #: ../en/ch11-template.xml:469 | |
13145 msgid "Our simple style file contains just one line:" | |
13146 msgstr "" | |
13147 | |
13148 #. type: Content of: <book><chapter><sect1><sect2><para> | |
13149 #: ../en/ch11-template.xml:473 | |
13150 msgid "" | |
13151 "This tells Mercurial, <quote>if you're printing a changeset, use the text on " | |
13152 "the right as the template</quote>." | |
13153 msgstr "" | |
13154 | |
13155 #. type: Content of: <book><chapter><sect1><sect2><title> | |
13156 #: ../en/ch11-template.xml:479 | |
13157 msgid "Style file syntax" | |
13158 msgstr "" | |
13159 | |
13160 #. type: Content of: <book><chapter><sect1><sect2><para> | |
13161 #: ../en/ch11-template.xml:481 | |
13162 msgid "The syntax rules for a style file are simple." | |
13163 msgstr "" | |
13164 | |
13165 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
13166 #: ../en/ch11-template.xml:484 | |
13167 msgid "The file is processed one line at a time." | |
13168 msgstr "" | |
13169 | |
13170 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
13171 #: ../en/ch11-template.xml:487 | |
13172 msgid "Leading and trailing white space are ignored." | |
13173 msgstr "" | |
13174 | |
13175 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
13176 #: ../en/ch11-template.xml:490 | |
13177 msgid "Empty lines are skipped." | |
13178 msgstr "" | |
13179 | |
13180 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
13181 #: ../en/ch11-template.xml:492 | |
13182 msgid "" | |
13183 "If a line starts with either of the characters <quote><literal>#</literal></" | |
13184 "quote> or <quote><literal>;</literal></quote>, the entire line is treated as " | |
13185 "a comment, and skipped as if empty." | |
13186 msgstr "" | |
13187 | |
13188 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
13189 #: ../en/ch11-template.xml:497 | |
13190 msgid "" | |
13191 "A line starts with a keyword. This must start with an alphabetic character " | |
13192 "or underscore, and can subsequently contain any alphanumeric character or " | |
13193 "underscore. (In regexp notation, a keyword must match <literal>[A-Za-z_][A-" | |
13194 "Za-z0-9_]*</literal>.)" | |
13195 msgstr "" | |
13196 | |
13197 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
13198 #: ../en/ch11-template.xml:503 | |
13199 msgid "" | |
13200 "The next element must be an <quote><literal>=</literal></quote> character, " | |
13201 "which can be preceded or followed by an arbitrary amount of white space." | |
13202 msgstr "" | |
13203 | |
13204 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
13205 #: ../en/ch11-template.xml:508 | |
13206 msgid "" | |
13207 "If the rest of the line starts and ends with matching quote characters " | |
13208 "(either single or double quote), it is treated as a template body." | |
13209 msgstr "" | |
13210 | |
13211 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
13212 #: ../en/ch11-template.xml:512 | |
13213 msgid "" | |
13214 "If the rest of the line <emphasis>does not</emphasis> start with a quote " | |
13215 "character, it is treated as the name of a file; the contents of this file " | |
13216 "will be read and used as a template body." | |
13217 msgstr "" | |
13218 | |
13219 #. type: Content of: <book><chapter><sect1><title> | |
13220 #: ../en/ch11-template.xml:521 | |
13221 msgid "Style files by example" | |
13222 msgstr "" | |
13223 | |
13224 #. type: Content of: <book><chapter><sect1><para> | |
13225 #: ../en/ch11-template.xml:523 | |
13226 msgid "" | |
13227 "To illustrate how to write a style file, we will construct a few by example. " | |
13228 "Rather than provide a complete style file and walk through it, we'll mirror " | |
13229 "the usual process of developing a style file by starting with something very " | |
13230 "simple, and walking through a series of successively more complete examples." | |
13231 msgstr "" | |
13232 | |
13233 #. type: Content of: <book><chapter><sect1><sect2><title> | |
13234 #: ../en/ch11-template.xml:530 | |
13235 msgid "Identifying mistakes in style files" | |
13236 msgstr "" | |
13237 | |
13238 #. type: Content of: <book><chapter><sect1><sect2><para> | |
13239 #: ../en/ch11-template.xml:532 | |
13240 msgid "" | |
13241 "If Mercurial encounters a problem in a style file you are working on, it " | |
13242 "prints a terse error message that, once you figure out what it means, is " | |
13243 "actually quite useful." | |
13244 msgstr "" | |
13245 | |
13246 #. type: Content of: <book><chapter><sect1><sect2><para> | |
13247 #: ../en/ch11-template.xml:538 | |
13248 msgid "" | |
13249 "Notice that <filename>broken.style</filename> attempts to define a " | |
13250 "<literal>changeset</literal> keyword, but forgets to give any content for it. " | |
13251 "When instructed to use this style file, Mercurial promptly complains." | |
13252 msgstr "" | |
13253 | |
13254 #. type: Content of: <book><chapter><sect1><sect2><para> | |
13255 #: ../en/ch11-template.xml:545 | |
13256 msgid "This error message looks intimidating, but it is not too hard to follow." | |
13257 msgstr "" | |
13258 | |
13259 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
13260 #: ../en/ch11-template.xml:549 | |
13261 msgid "" | |
13262 "The first component is simply Mercurial's way of saying <quote>I am giving " | |
13263 "up</quote>." | |
13264 msgstr "" | |
13265 | |
13266 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
13267 #: ../en/ch11-template.xml:554 | |
13268 msgid "Next comes the name of the style file that contains the error." | |
13269 msgstr "" | |
13270 | |
13271 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
13272 #: ../en/ch11-template.xml:560 | |
13273 msgid "" | |
13274 "Following the file name is the line number where the error was encountered." | |
13275 msgstr "" | |
13276 | |
13277 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
13278 #: ../en/ch11-template.xml:565 | |
13279 msgid "Finally, a description of what went wrong." | |
13280 msgstr "" | |
13281 | |
13282 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
13283 #: ../en/ch11-template.xml:570 | |
13284 msgid "" | |
13285 "The description of the problem is not always clear (as in this case), but " | |
13286 "even when it is cryptic, it is almost always trivial to visually inspect the " | |
13287 "offending line in the style file and see what is wrong." | |
13288 msgstr "" | |
13289 | |
13290 #. type: Content of: <book><chapter><sect1><sect2><title> | |
13291 #: ../en/ch11-template.xml:578 | |
13292 msgid "Uniquely identifying a repository" | |
13293 msgstr "" | |
13294 | |
13295 #. type: Content of: <book><chapter><sect1><sect2><para> | |
13296 #: ../en/ch11-template.xml:580 | |
13297 msgid "" | |
13298 "If you would like to be able to identify a Mercurial repository <quote>fairly " | |
13299 "uniquely</quote> using a short string as an identifier, you can use the first " | |
13300 "revision in the repository." | |
13301 msgstr "" | |
13302 | |
13303 #. type: Content of: <book><chapter><sect1><sect2><para> | |
13304 #: ../en/ch11-template.xml:587 | |
13305 msgid "" | |
13306 "This is not guaranteed to be unique, but it is nevertheless useful in many " | |
13307 "cases." | |
13308 msgstr "" | |
13309 | |
13310 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
13311 #: ../en/ch11-template.xml:590 | |
13312 msgid "" | |
13313 "It will not work in a completely empty repository, because such a repository " | |
13314 "does not have a revision zero." | |
13315 msgstr "" | |
13316 | |
13317 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
13318 #: ../en/ch11-template.xml:594 | |
13319 msgid "" | |
13320 "Neither will it work in the (extremely rare) case where a repository is a " | |
13321 "merge of two or more formerly independent repositories, and you still have " | |
13322 "those repositories around." | |
13323 msgstr "" | |
13324 | |
13325 #. type: Content of: <book><chapter><sect1><sect2><para> | |
13326 #: ../en/ch11-template.xml:599 | |
13327 msgid "Here are some uses to which you could put this identifier:" | |
13328 msgstr "" | |
13329 | |
13330 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
13331 #: ../en/ch11-template.xml:602 | |
13332 msgid "" | |
13333 "As a key into a table for a database that manages repositories on a server." | |
13334 msgstr "" | |
13335 | |
13336 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
13337 #: ../en/ch11-template.xml:605 | |
13338 msgid "" | |
13339 "As half of a {<emphasis>repository ID</emphasis>, <emphasis>revision ID</" | |
13340 "emphasis>} tuple. Save this information away when you run an automated build " | |
13341 "or other activity, so that you can <quote>replay</quote> the build later if " | |
13342 "necessary." | |
13343 msgstr "" | |
13344 | |
13345 #. type: Content of: <book><chapter><sect1><sect2><title> | |
13346 #: ../en/ch11-template.xml:614 | |
13347 msgid "Mimicking Subversion's output" | |
13348 msgstr "" | |
13349 | |
13350 # | |
13351 #. type: Content of: <book><chapter><sect1><sect2><para> | |
13352 #: ../en/ch11-template.xml:616 | |
13353 msgid "" | |
13354 "Let's try to emulate the default output format used by another revision " | |
13355 "control tool, Subversion." | |
13356 msgstr "" | |
13357 | |
13358 # | |
13359 #. type: Content of: <book><chapter><sect1><sect2><para> | |
13360 #: ../en/ch11-template.xml:621 | |
13361 msgid "" | |
13362 "Since Subversion's output style is fairly simple, it is easy to copy-and-" | |
13363 "paste a hunk of its output into a file, and replace the text produced above " | |
13364 "by Subversion with the template values we'd like to see expanded." | |
13365 msgstr "" | |
13366 | |
13367 #. type: Content of: <book><chapter><sect1><sect2><para> | |
13368 #: ../en/ch11-template.xml:628 | |
13369 msgid "" | |
13370 "There are a few small ways in which this template deviates from the output " | |
13371 "produced by Subversion." | |
13372 msgstr "" | |
13373 | |
13374 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
13375 #: ../en/ch11-template.xml:631 | |
13376 msgid "" | |
13377 "Subversion prints a <quote>readable</quote> date (the <quote><literal>Wed, 27 " | |
13378 "Sep 2006</literal></quote> in the example output above) in parentheses. " | |
13379 "Mercurial's templating engine does not provide a way to display a date in " | |
13380 "this format without also printing the time and time zone." | |
13381 msgstr "" | |
13382 | |
13383 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
13384 #: ../en/ch11-template.xml:638 | |
13385 msgid "" | |
13386 "We emulate Subversion's printing of <quote>separator</quote> lines full of " | |
13387 "<quote><literal>-</literal></quote> characters by ending the template with " | |
13388 "such a line. We use the templating engine's <literal role=\"template-keyword" | |
13389 "\">header</literal> keyword to print a separator line as the first line of " | |
13390 "output (see below), thus achieving similar output to Subversion." | |
13391 msgstr "" | |
13392 | |
13393 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
13394 #: ../en/ch11-template.xml:647 | |
13395 msgid "" | |
13396 "Subversion's output includes a count in the header of the number of lines in " | |
13397 "the commit message. We cannot replicate this in Mercurial; the templating " | |
13398 "engine does not currently provide a filter that counts the number of lines " | |
13399 "the template generates." | |
13400 msgstr "" | |
13401 | |
13402 # | |
13403 #. type: Content of: <book><chapter><sect1><sect2><para> | |
13404 #: ../en/ch11-template.xml:653 | |
13405 msgid "" | |
13406 "It took me no more than a minute or two of work to replace literal text from " | |
13407 "an example of Subversion's output with some keywords and filters to give the " | |
13408 "template above. The style file simply refers to the template." | |
13409 msgstr "" | |
13410 | |
13411 #. type: Content of: <book><chapter><sect1><sect2><para> | |
13412 #: ../en/ch11-template.xml:660 | |
13413 msgid "" | |
13414 "We could have included the text of the template file directly in the style " | |
13415 "file by enclosing it in quotes and replacing the newlines with " | |
13416 "<quote><literal>\\n</literal></quote> sequences, but it would have made the " | |
13417 "style file too difficult to read. Readability is a good guide when you're " | |
13418 "trying to decide whether some text belongs in a style file, or in a template " | |
13419 "file that the style file points to. If the style file will look too big or " | |
13420 "cluttered if you insert a literal piece of text, drop it into a template " | |
13421 "instead." | |
13422 msgstr "" | |
13423 | |
13424 #. type: Content of: <book><chapter><title> | |
13425 #: ../en/ch12-mq.xml:5 | |
13426 msgid "Managing change with Mercurial Queues" | |
13427 msgstr "使用 MQ 管理修改" | |
13428 | |
13429 #. type: Content of: <book><chapter><sect1><title> | |
13430 #: ../en/ch12-mq.xml:8 | |
13431 msgid "The patch management problem" | |
13432 msgstr "" | |
13433 | |
13434 #. type: Content of: <book><chapter><sect1><para> | |
13435 #: ../en/ch12-mq.xml:10 | |
13436 msgid "" | |
13437 "Here is a common scenario: you need to install a software package from " | |
13438 "source, but you find a bug that you must fix in the source before you can " | |
13439 "start using the package. You make your changes, forget about the package for " | |
13440 "a while, and a few months later you need to upgrade to a newer version of the " | |
13441 "package. If the newer version of the package still has the bug, you must " | |
13442 "extract your fix from the older source tree and apply it against the newer " | |
13443 "version. This is a tedious task, and it's easy to make mistakes." | |
13444 msgstr "" | |
13445 | |
13446 #. type: Content of: <book><chapter><sect1><para> | |
13447 #: ../en/ch12-mq.xml:20 | |
13448 msgid "" | |
13449 "This is a simple case of the <quote>patch management</quote> problem. You " | |
13450 "have an <quote>upstream</quote> source tree that you can't change; you need " | |
13451 "to make some local changes on top of the upstream tree; and you'd like to be " | |
13452 "able to keep those changes separate, so that you can apply them to newer " | |
13453 "versions of the upstream source." | |
13454 msgstr "" | |
13455 | |
13456 #. type: Content of: <book><chapter><sect1><para> | |
13457 #: ../en/ch12-mq.xml:27 | |
13458 msgid "" | |
13459 "The patch management problem arises in many situations. Probably the most " | |
13460 "visible is that a user of an open source software project will contribute a " | |
13461 "bug fix or new feature to the project's maintainers in the form of a patch." | |
13462 msgstr "" | |
13463 | |
13464 #. type: Content of: <book><chapter><sect1><para> | |
13465 #: ../en/ch12-mq.xml:32 | |
13466 msgid "" | |
13467 "Distributors of operating systems that include open source software often " | |
13468 "need to make changes to the packages they distribute so that they will build " | |
13469 "properly in their environments." | |
13470 msgstr "" | |
13471 | |
13472 #. type: Content of: <book><chapter><sect1><para> | |
13473 #: ../en/ch12-mq.xml:37 | |
13474 msgid "" | |
13475 "When you have few changes to maintain, it is easy to manage a single patch " | |
13476 "using the standard <command>diff</command> and <command>patch</command> " | |
13477 "programs (see section <xref linkend=\"sec.mq.patch\"/> for a discussion of " | |
13478 "these tools). Once the number of changes grows, it starts to make sense to " | |
13479 "maintain patches as discrete <quote>chunks of work,</quote> so that for " | |
13480 "example a single patch will contain only one bug fix (the patch might modify " | |
13481 "several files, but it's doing <quote>only one thing</quote>), and you may " | |
13482 "have a number of such patches for different bugs you need fixed and local " | |
13483 "changes you require. In this situation, if you submit a bug fix patch to the " | |
13484 "upstream maintainers of a package and they include your fix in a subsequent " | |
13485 "release, you can simply drop that single patch when you're updating to the " | |
13486 "newer release." | |
13487 msgstr "" | |
13488 | |
13489 #. type: Content of: <book><chapter><sect1><para> | |
13490 #: ../en/ch12-mq.xml:52 | |
13491 msgid "" | |
13492 "Maintaining a single patch against an upstream tree is a little tedious and " | |
13493 "error-prone, but not difficult. However, the complexity of the problem grows " | |
13494 "rapidly as the number of patches you have to maintain increases. With more " | |
13495 "than a tiny number of patches in hand, understanding which ones you have " | |
13496 "applied and maintaining them moves from messy to overwhelming." | |
13497 msgstr "" | |
13498 | |
13499 #. type: Content of: <book><chapter><sect1><para> | |
13500 #: ../en/ch12-mq.xml:59 | |
13501 msgid "" | |
13502 "Fortunately, Mercurial includes a powerful extension, Mercurial Queues (or " | |
13503 "simply <quote>MQ</quote>), that massively simplifies the patch management " | |
13504 "problem." | |
13505 msgstr "" | |
13506 | |
13507 #. type: Content of: <book><chapter><sect1><title> | |
13508 #: ../en/ch12-mq.xml:65 | |
13509 msgid "The prehistory of Mercurial Queues" | |
13510 msgstr "" | |
13511 | |
13512 #. type: Content of: <book><chapter><sect1><para> | |
13513 #: ../en/ch12-mq.xml:67 | |
13514 msgid "" | |
13515 "During the late 1990s, several Linux kernel developers started to maintain " | |
13516 "<quote>patch series</quote> that modified the behaviour of the Linux kernel. " | |
13517 "Some of these series were focused on stability, some on feature coverage, and " | |
13518 "others were more speculative." | |
13519 msgstr "" | |
13520 | |
13521 #. type: Content of: <book><chapter><sect1><para> | |
13522 #: ../en/ch12-mq.xml:73 | |
13523 msgid "" | |
13524 "The sizes of these patch series grew rapidly. In 2002, Andrew Morton " | |
13525 "published some shell scripts he had been using to automate the task of " | |
13526 "managing his patch queues. Andrew was successfully using these scripts to " | |
13527 "manage hundreds (sometimes thousands) of patches on top of the Linux kernel." | |
13528 msgstr "" | |
13529 | |
13530 #. type: Content of: <book><chapter><sect1><sect2><title> | |
13531 #: ../en/ch12-mq.xml:80 | |
13532 msgid "A patchwork quilt" | |
13533 msgstr "" | |
13534 | |
13535 #. type: Content of: <book><chapter><sect1><sect2><para> | |
13536 #: ../en/ch12-mq.xml:82 | |
13537 msgid "" | |
13538 "In early 2003, Andreas Gruenbacher and Martin Quinson borrowed the approach " | |
13539 "of Andrew's scripts and published a tool called <quote>patchwork quilt</" | |
13540 "quote> <citation>web:quilt</citation>, or simply <quote>quilt</quote> (see " | |
13541 "<citation>gruenbacher:2005</citation> for a paper describing it). Because " | |
13542 "quilt substantially automated patch management, it rapidly gained a large " | |
13543 "following among open source software developers." | |
13544 msgstr "" | |
13545 | |
13546 #. type: Content of: <book><chapter><sect1><sect2><para> | |
13547 #: ../en/ch12-mq.xml:91 | |
13548 msgid "" | |
13549 "Quilt manages a <emphasis>stack of patches</emphasis> on top of a directory " | |
13550 "tree. To begin, you tell quilt to manage a directory tree, and tell it which " | |
13551 "files you want to manage; it stores away the names and contents of those " | |
13552 "files. To fix a bug, you create a new patch (using a single command), edit " | |
13553 "the files you need to fix, then <quote>refresh</quote> the patch." | |
13554 msgstr "" | |
13555 | |
13556 #. type: Content of: <book><chapter><sect1><sect2><para> | |
13557 #: ../en/ch12-mq.xml:99 | |
13558 msgid "" | |
13559 "The refresh step causes quilt to scan the directory tree; it updates the " | |
13560 "patch with all of the changes you have made. You can create another patch on " | |
13561 "top of the first, which will track the changes required to modify the tree " | |
13562 "from <quote>tree with one patch applied</quote> to <quote>tree with two " | |
13563 "patches applied</quote>." | |
13564 msgstr "" | |
13565 | |
13566 #. type: Content of: <book><chapter><sect1><sect2><para> | |
13567 #: ../en/ch12-mq.xml:106 | |
13568 msgid "" | |
13569 "You can <emphasis>change</emphasis> which patches are applied to the tree. " | |
13570 "If you <quote>pop</quote> a patch, the changes made by that patch will vanish " | |
13571 "from the directory tree. Quilt remembers which patches you have popped, " | |
13572 "though, so you can <quote>push</quote> a popped patch again, and the " | |
13573 "directory tree will be restored to contain the modifications in the patch. " | |
13574 "Most importantly, you can run the <quote>refresh</quote> command at any time, " | |
13575 "and the topmost applied patch will be updated. This means that you can, at " | |
13576 "any time, change both which patches are applied and what modifications those " | |
13577 "patches make." | |
13578 msgstr "" | |
13579 | |
13580 #. type: Content of: <book><chapter><sect1><sect2><para> | |
13581 #: ../en/ch12-mq.xml:118 | |
13582 msgid "" | |
13583 "Quilt knows nothing about revision control tools, so it works equally well on " | |
13584 "top of an unpacked tarball or a Subversion working copy." | |
13585 msgstr "" | |
13586 | |
13587 #. type: Content of: <book><chapter><sect1><sect2><title> | |
13588 #: ../en/ch12-mq.xml:124 | |
13589 msgid "From patchwork quilt to Mercurial Queues" | |
13590 msgstr "" | |
13591 | |
13592 #. type: Content of: <book><chapter><sect1><sect2><para> | |
13593 #: ../en/ch12-mq.xml:126 | |
13594 msgid "" | |
13595 "In mid-2005, Chris Mason took the features of quilt and wrote an extension " | |
13596 "that he called Mercurial Queues, which added quilt-like behaviour to " | |
13597 "Mercurial." | |
13598 msgstr "" | |
13599 | |
13600 #. type: Content of: <book><chapter><sect1><sect2><para> | |
13601 #: ../en/ch12-mq.xml:130 | |
13602 msgid "" | |
13603 "The key difference between quilt and MQ is that quilt knows nothing about " | |
13604 "revision control systems, while MQ is <emphasis>integrated</emphasis> into " | |
13605 "Mercurial. Each patch that you push is represented as a Mercurial " | |
13606 "changeset. Pop a patch, and the changeset goes away." | |
13607 msgstr "" | |
13608 | |
13609 #. type: Content of: <book><chapter><sect1><sect2><para> | |
13610 #: ../en/ch12-mq.xml:136 | |
13611 msgid "" | |
13612 "Because quilt does not care about revision control tools, it is still a " | |
13613 "tremendously useful piece of software to know about for situations where you " | |
13614 "cannot use Mercurial and MQ." | |
13615 msgstr "" | |
13616 | |
13617 #. type: Content of: <book><chapter><sect1><title> | |
13618 #: ../en/ch12-mq.xml:144 | |
13619 msgid "The huge advantage of MQ" | |
13620 msgstr "" | |
13621 | |
13622 #. type: Content of: <book><chapter><sect1><para> | |
13623 #: ../en/ch12-mq.xml:146 | |
13624 msgid "" | |
13625 "I cannot overstate the value that MQ offers through the unification of " | |
13626 "patches and revision control." | |
13627 msgstr "" | |
13628 | |
13629 #. type: Content of: <book><chapter><sect1><para> | |
13630 #: ../en/ch12-mq.xml:149 | |
13631 msgid "" | |
13632 "A major reason that patches have persisted in the free software and open " | |
13633 "source world&emdash;in spite of the availability of increasingly capable " | |
13634 "revision control tools over the years&emdash;is the <emphasis>agility</" | |
13635 "emphasis> they offer." | |
13636 msgstr "" | |
13637 | |
13638 #. type: Content of: <book><chapter><sect1><para> | |
13639 #: ../en/ch12-mq.xml:155 | |
13640 msgid "" | |
13641 "Traditional revision control tools make a permanent, irreversible record of " | |
13642 "everything that you do. While this has great value, it's also somewhat " | |
13643 "stifling. If you want to perform a wild-eyed experiment, you have to be " | |
13644 "careful in how you go about it, or you risk leaving unneeded&emdash;or worse, " | |
13645 "misleading or destabilising&emdash;traces of your missteps and errors in the " | |
13646 "permanent revision record." | |
13647 msgstr "" | |
13648 | |
13649 #. type: Content of: <book><chapter><sect1><para> | |
13650 #: ../en/ch12-mq.xml:163 | |
13651 msgid "" | |
13652 "By contrast, MQ's marriage of distributed revision control with patches makes " | |
13653 "it much easier to isolate your work. Your patches live on top of normal " | |
13654 "revision history, and you can make them disappear or reappear at will. If " | |
13655 "you don't like a patch, you can drop it. If a patch isn't quite as you want " | |
13656 "it to be, simply fix it&emdash;as many times as you need to, until you have " | |
13657 "refined it into the form you desire." | |
13658 msgstr "" | |
13659 | |
13660 #. type: Content of: <book><chapter><sect1><para> | |
13661 #: ../en/ch12-mq.xml:171 | |
13662 msgid "" | |
13663 "As an example, the integration of patches with revision control makes " | |
13664 "understanding patches and debugging their effects&emdash;and their interplay " | |
13665 "with the code they're based on&emdash;<emphasis>enormously</emphasis> easier. " | |
13666 "Since every applied patch has an associated changeset, you can give <command " | |
13667 "role=\"hg-cmd\">hg log</command> a file name to see which changesets and " | |
13668 "patches affected the file. You can use the <command role=\"hg-cmd\">hg " | |
13669 "bisect</command> command to binary-search through all changesets and applied " | |
13670 "patches to see where a bug got introduced or fixed. You can use the <command " | |
13671 "role=\"hg-cmd\">hg annotate</command> command to see which changeset or patch " | |
13672 "modified a particular line of a source file. And so on." | |
13673 msgstr "" | |
13674 | |
13675 #. type: Content of: <book><chapter><sect1><title> | |
13676 #: ../en/ch12-mq.xml:187 | |
13677 msgid "Understanding patches" | |
13678 msgstr "" | |
13679 | |
13680 #. type: Content of: <book><chapter><sect1><para> | |
13681 #: ../en/ch12-mq.xml:189 | |
13682 msgid "" | |
13683 "Because MQ doesn't hide its patch-oriented nature, it is helpful to " | |
13684 "understand what patches are, and a little about the tools that work with them." | |
13685 msgstr "" | |
13686 | |
13687 #. type: Content of: <book><chapter><sect1><para> | |
13688 #: ../en/ch12-mq.xml:193 | |
13689 msgid "" | |
13690 "The traditional Unix <command>diff</command> command compares two files, and " | |
13691 "prints a list of differences between them. The <command>patch</command> " | |
13692 "command understands these differences as <emphasis>modifications</emphasis> " | |
13693 "to make to a file. Take a look below for a simple example of these commands " | |
13694 "in action." | |
13695 msgstr "" | |
13696 | |
13697 #. type: Content of: <book><chapter><sect1><para> | |
13698 #: ../en/ch12-mq.xml:202 | |
13699 msgid "" | |
13700 "The type of file that <command>diff</command> generates (and <command>patch</" | |
13701 "command> takes as input) is called a <quote>patch</quote> or a <quote>diff</" | |
13702 "quote>; there is no difference between a patch and a diff. (We'll use the " | |
13703 "term <quote>patch</quote>, since it's more commonly used.)" | |
13704 msgstr "" | |
13705 | |
13706 #. type: Content of: <book><chapter><sect1><para> | |
13707 #: ../en/ch12-mq.xml:208 | |
13708 msgid "" | |
13709 "A patch file can start with arbitrary text; the <command>patch</command> " | |
13710 "command ignores this text, but MQ uses it as the commit message when creating " | |
13711 "changesets. To find the beginning of the patch content, <command>patch</" | |
13712 "command> searches for the first line that starts with the string " | |
13713 "<quote><literal>diff -</literal></quote>." | |
13714 msgstr "" | |
13715 | |
13716 #. type: Content of: <book><chapter><sect1><para> | |
13717 #: ../en/ch12-mq.xml:215 | |
13718 msgid "" | |
13719 "MQ works with <emphasis>unified</emphasis> diffs (<command>patch</command> " | |
13720 "can accept several other diff formats, but MQ doesn't). A unified diff " | |
13721 "contains two kinds of header. The <emphasis>file header</emphasis> describes " | |
13722 "the file being modified; it contains the name of the file to modify. When " | |
13723 "<command>patch</command> sees a new file header, it looks for a file with " | |
13724 "that name to start modifying." | |
13725 msgstr "" | |
13726 | |
13727 #. type: Content of: <book><chapter><sect1><para> | |
13728 #: ../en/ch12-mq.xml:223 | |
13729 msgid "" | |
13730 "After the file header comes a series of <emphasis>hunks</emphasis>. Each " | |
13731 "hunk starts with a header; this identifies the range of line numbers within " | |
13732 "the file that the hunk should modify. Following the header, a hunk starts " | |
13733 "and ends with a few (usually three) lines of text from the unmodified file; " | |
13734 "these are called the <emphasis>context</emphasis> for the hunk. If there's " | |
13735 "only a small amount of context between successive hunks, <command>diff</" | |
13736 "command> doesn't print a new hunk header; it just runs the hunks together, " | |
13737 "with a few lines of context between modifications." | |
13738 msgstr "" | |
13739 | |
13740 #. type: Content of: <book><chapter><sect1><para> | |
13741 #: ../en/ch12-mq.xml:235 | |
13742 msgid "" | |
13743 "Each line of context begins with a space character. Within the hunk, a line " | |
13744 "that begins with <quote><literal>-</literal></quote> means <quote>remove this " | |
13745 "line,</quote> while a line that begins with <quote><literal>+</literal></" | |
13746 "quote> means <quote>insert this line.</quote> For example, a line that is " | |
13747 "modified is represented by one deletion and one insertion." | |
13748 msgstr "" | |
13749 | |
13750 #. type: Content of: <book><chapter><sect1><para> | |
13751 #: ../en/ch12-mq.xml:243 | |
13752 msgid "" | |
13753 "We will return to some of the more subtle aspects of patches later (in " | |
13754 "section <xref linkend=\"sec.mq.adv-patch\"/>), but you should have enough " | |
13755 "information now to use MQ." | |
13756 msgstr "" | |
13757 | |
13758 #. type: Content of: <book><chapter><sect1><title> | |
13759 #: ../en/ch12-mq.xml:250 | |
13760 msgid "Getting started with Mercurial Queues" | |
13761 msgstr "" | |
13762 | |
13763 #. type: Content of: <book><chapter><sect1><para> | |
13764 #: ../en/ch12-mq.xml:252 | |
13765 msgid "" | |
13766 "Because MQ is implemented as an extension, you must explicitly enable before " | |
13767 "you can use it. (You don't need to download anything; MQ ships with the " | |
13768 "standard Mercurial distribution.) To enable MQ, edit your <filename role=" | |
13769 "\"home\">~/.hgrc</filename> file, and add the lines below." | |
13770 msgstr "" | |
13771 | |
13772 #. type: Content of: <book><chapter><sect1><para> | |
13773 #: ../en/ch12-mq.xml:261 | |
13774 msgid "" | |
13775 "Once the extension is enabled, it will make a number of new commands " | |
13776 "available. To verify that the extension is working, you can use <command " | |
13777 "role=\"hg-cmd\">hg help</command> to see if the <command role=\"hg-ext-mq" | |
13778 "\">qinit</command> command is now available." | |
13779 msgstr "" | |
13780 | |
13781 #. type: Content of: <book><chapter><sect1><para> | |
13782 #: ../en/ch12-mq.xml:269 | |
13783 msgid "" | |
13784 "You can use MQ with <emphasis>any</emphasis> Mercurial repository, and its " | |
13785 "commands only operate within that repository. To get started, simply prepare " | |
13786 "the repository using the <command role=\"hg-ext-mq\">qinit</command> command." | |
13787 msgstr "" | |
13788 | |
13789 #. type: Content of: <book><chapter><sect1><para> | |
13790 #: ../en/ch12-mq.xml:276 | |
13791 msgid "" | |
13792 "This command creates an empty directory called <filename role=\"special\" " | |
13793 "class=\"directory\">.hg/patches</filename>, where MQ will keep its metadata. " | |
13794 "As with many Mercurial commands, the <command role=\"hg-ext-mq\">qinit</" | |
13795 "command> command prints nothing if it succeeds." | |
13796 msgstr "" | |
13797 | |
13798 #. type: Content of: <book><chapter><sect1><sect2><title> | |
13799 #: ../en/ch12-mq.xml:283 | |
13800 msgid "Creating a new patch" | |
13801 msgstr "" | |
13802 | |
13803 #. type: Content of: <book><chapter><sect1><sect2><para> | |
13804 #: ../en/ch12-mq.xml:285 | |
13805 msgid "" | |
13806 "To begin work on a new patch, use the <command role=\"hg-ext-mq\">qnew</" | |
13807 "command> command. This command takes one argument, the name of the patch to " | |
13808 "create." | |
13809 msgstr "" | |
13810 | |
13811 #. type: Content of: <book><chapter><sect1><sect2><para> | |
13812 #: ../en/ch12-mq.xml:289 | |
13813 msgid "" | |
13814 "MQ will use this as the name of an actual file in the <filename role=\"special" | |
13815 "\" class=\"directory\">.hg/patches</filename> directory, as you can see below." | |
13816 msgstr "" | |
13817 | |
13818 #. type: Content of: <book><chapter><sect1><sect2><para> | |
13819 #: ../en/ch12-mq.xml:296 | |
13820 msgid "" | |
13821 "Also newly present in the <filename role=\"special\" class=\"directory\">.hg/" | |
13822 "patches</filename> directory are two other files, <filename role=\"special" | |
13823 "\">series</filename> and <filename role=\"special\">status</filename>. The " | |
13824 "<filename role=\"special\">series</filename> file lists all of the patches " | |
13825 "that MQ knows about for this repository, with one patch per line. Mercurial " | |
13826 "uses the <filename role=\"special\">status</filename> file for internal book-" | |
13827 "keeping; it tracks all of the patches that MQ has <emphasis>applied</" | |
13828 "emphasis> in this repository." | |
13829 msgstr "" | |
13830 | |
13831 #. type: Content of: <book><chapter><sect1><sect2><note><para> | |
13832 #: ../en/ch12-mq.xml:308 | |
13833 msgid "" | |
13834 "You may sometimes want to edit the <filename role=\"special\">series</" | |
13835 "filename> file by hand; for example, to change the sequence in which some " | |
13836 "patches are applied. However, manually editing the <filename role=\"special" | |
13837 "\">status</filename> file is almost always a bad idea, as it's easy to " | |
13838 "corrupt MQ's idea of what is happening." | |
13839 msgstr "" | |
13840 | |
13841 #. type: Content of: <book><chapter><sect1><sect2><para> | |
13842 #: ../en/ch12-mq.xml:317 | |
13843 msgid "" | |
13844 "Once you have created your new patch, you can edit files in the working " | |
13845 "directory as you usually would. All of the normal Mercurial commands, such " | |
13846 "as <command role=\"hg-cmd\">hg diff</command> and <command role=\"hg-cmd\">hg " | |
13847 "annotate</command>, work exactly as they did before." | |
13848 msgstr "" | |
13849 | |
13850 #. type: Content of: <book><chapter><sect1><sect2><title> | |
13851 #: ../en/ch12-mq.xml:325 | |
13852 msgid "Refreshing a patch" | |
13853 msgstr "" | |
13854 | |
13855 #. type: Content of: <book><chapter><sect1><sect2><para> | |
13856 #: ../en/ch12-mq.xml:327 | |
13857 msgid "" | |
13858 "When you reach a point where you want to save your work, use the <command " | |
13859 "role=\"hg-ext-mq\">qrefresh</command> command to update the patch you are " | |
13860 "working on." | |
13861 msgstr "" | |
13862 | |
13863 #. type: Content of: <book><chapter><sect1><sect2><para> | |
13864 #: ../en/ch12-mq.xml:333 | |
13865 msgid "" | |
13866 "This command folds the changes you have made in the working directory into " | |
13867 "your patch, and updates its corresponding changeset to contain those changes." | |
13868 msgstr "" | |
13869 | |
13870 #. type: Content of: <book><chapter><sect1><sect2><para> | |
13871 #: ../en/ch12-mq.xml:337 | |
13872 msgid "" | |
13873 "You can run <command role=\"hg-ext-mq\">qrefresh</command> as often as you " | |
13874 "like, so it's a good way to <quote>checkpoint</quote> your work. Refresh " | |
13875 "your patch at an opportune time; try an experiment; and if the experiment " | |
13876 "doesn't work out, <command role=\"hg-cmd\">hg revert</command> your " | |
13877 "modifications back to the last time you refreshed." | |
13878 msgstr "" | |
13879 | |
13880 #. type: Content of: <book><chapter><sect1><sect2><title> | |
13881 #: ../en/ch12-mq.xml:348 | |
13882 msgid "Stacking and tracking patches" | |
13883 msgstr "" | |
13884 | |
13885 #. type: Content of: <book><chapter><sect1><sect2><para> | |
13886 #: ../en/ch12-mq.xml:350 | |
13887 msgid "" | |
13888 "Once you have finished working on a patch, or need to work on another, you " | |
13889 "can use the <command role=\"hg-ext-mq\">qnew</command> command again to " | |
13890 "create a new patch. Mercurial will apply this patch on top of your existing " | |
13891 "patch." | |
13892 msgstr "" | |
13893 | |
13894 #. type: Content of: <book><chapter><sect1><sect2><para> | |
13895 #: ../en/ch12-mq.xml:357 | |
13896 msgid "" | |
13897 "Notice that the patch contains the changes in our prior patch as part of its " | |
13898 "context (you can see this more clearly in the output of <command role=\"hg-cmd" | |
13899 "\">hg annotate</command>)." | |
13900 msgstr "" | |
13901 | |
13902 #. type: Content of: <book><chapter><sect1><sect2><para> | |
13903 #: ../en/ch12-mq.xml:362 | |
13904 msgid "" | |
13905 "So far, with the exception of <command role=\"hg-ext-mq\">qnew</command> and " | |
13906 "<command role=\"hg-ext-mq\">qrefresh</command>, we've been careful to only " | |
13907 "use regular Mercurial commands. However, MQ provides many commands that are " | |
13908 "easier to use when you are thinking about patches, as illustrated below." | |
13909 msgstr "" | |
13910 | |
13911 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
13912 #: ../en/ch12-mq.xml:372 | |
13913 msgid "" | |
13914 "The <command role=\"hg-ext-mq\">qseries</command> command lists every patch " | |
13915 "that MQ knows about in this repository, from oldest to newest (most recently " | |
13916 "<emphasis>created</emphasis>)." | |
13917 msgstr "" | |
13918 | |
13919 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
13920 #: ../en/ch12-mq.xml:378 | |
13921 msgid "" | |
13922 "The <command role=\"hg-ext-mq\">qapplied</command> command lists every patch " | |
13923 "that MQ has <emphasis>applied</emphasis> in this repository, again from " | |
13924 "oldest to newest (most recently applied)." | |
13925 msgstr "" | |
13926 | |
13927 #. type: Content of: <book><chapter><sect1><sect2><title> | |
13928 #: ../en/ch12-mq.xml:387 | |
13929 msgid "Manipulating the patch stack" | |
13930 msgstr "" | |
13931 | |
13932 #. type: Content of: <book><chapter><sect1><sect2><para> | |
13933 #: ../en/ch12-mq.xml:389 | |
13934 msgid "" | |
13935 "The previous discussion implied that there must be a difference between " | |
13936 "<quote>known</quote> and <quote>applied</quote> patches, and there is. MQ " | |
13937 "can manage a patch without it being applied in the repository." | |
13938 msgstr "" | |
13939 | |
13940 #. type: Content of: <book><chapter><sect1><sect2><para> | |
13941 #: ../en/ch12-mq.xml:394 | |
13942 msgid "" | |
13943 "An <emphasis>applied</emphasis> patch has a corresponding changeset in the " | |
13944 "repository, and the effects of the patch and changeset are visible in the " | |
13945 "working directory. You can undo the application of a patch using the " | |
13946 "<command role=\"hg-ext-mq\">qpop</command> command. MQ still <emphasis>knows " | |
13947 "about</emphasis>, or manages, a popped patch, but the patch no longer has a " | |
13948 "corresponding changeset in the repository, and the working directory does not " | |
13949 "contain the changes made by the patch. Figure <xref linkend=\"fig.mq.stack\"/" | |
13950 "> illustrates the difference between applied and tracked patches." | |
13951 msgstr "" | |
13952 | |
13953 #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject> | |
13954 #: ../en/ch12-mq.xml:407 | |
13955 msgid "<imageobject><imagedata fileref=\"images/mq-stack.png\"/></imageobject>" | |
13956 msgstr "" | |
13957 | |
13958 #. type: Content of: <book><chapter><sect1><sect2><informalfigure><mediaobject><caption><para> | |
13959 #: ../en/ch12-mq.xml:409 | |
13960 msgid "Applied and unapplied patches in the MQ patch stack" | |
13961 msgstr "" | |
13962 | |
13963 #. type: Content of: <book><chapter><sect1><sect2><para> | |
13964 #: ../en/ch12-mq.xml:414 | |
13965 msgid "" | |
13966 "You can reapply an unapplied, or popped, patch using the <command role=\"hg-" | |
13967 "ext-mq\">qpush</command> command. This creates a new changeset to correspond " | |
13968 "to the patch, and the patch's changes once again become present in the " | |
13969 "working directory. See below for examples of <command role=\"hg-ext-mq" | |
13970 "\">qpop</command> and <command role=\"hg-ext-mq\">qpush</command> in action." | |
13971 msgstr "" | |
13972 | |
13973 #. type: Content of: <book><chapter><sect1><sect2><para> | |
13974 #: ../en/ch12-mq.xml:423 | |
13975 msgid "" | |
13976 "Notice that once we have popped a patch or two patches, the output of " | |
13977 "<command role=\"hg-ext-mq\">qseries</command> remains the same, while that of " | |
13978 "<command role=\"hg-ext-mq\">qapplied</command> has changed." | |
13979 msgstr "" | |
13980 | |
13981 #. type: Content of: <book><chapter><sect1><sect2><title> | |
13982 #: ../en/ch12-mq.xml:431 | |
13983 msgid "Pushing and popping many patches" | |
13984 msgstr "" | |
13985 | |
13986 #. type: Content of: <book><chapter><sect1><sect2><para> | |
13987 #: ../en/ch12-mq.xml:433 | |
13988 msgid "" | |
13989 "While <command role=\"hg-ext-mq\">qpush</command> and <command role=\"hg-ext-" | |
13990 "mq\">qpop</command> each operate on a single patch at a time by default, you " | |
13991 "can push and pop many patches in one go. The <option role=\"hg-ext-mq-cmd-" | |
13992 "qpush-opt\">hg -a</option> option to <command role=\"hg-ext-mq\">qpush</" | |
13993 "command> causes it to push all unapplied patches, while the <option role=\"hg-" | |
13994 "ext-mq-cmd-qpop-opt\">-a</option> option to <command role=\"hg-ext-mq\">qpop</" | |
13995 "command> causes it to pop all applied patches. (For some more ways to push " | |
13996 "and pop many patches, see section <xref linkend=\"sec.mq.perf\"/> below.)" | |
13997 msgstr "" | |
13998 | |
13999 #. type: Content of: <book><chapter><sect1><sect2><title> | |
14000 #: ../en/ch12-mq.xml:450 | |
14001 msgid "Safety checks, and overriding them" | |
14002 msgstr "" | |
14003 | |
14004 #. type: Content of: <book><chapter><sect1><sect2><para> | |
14005 #: ../en/ch12-mq.xml:452 | |
14006 msgid "" | |
14007 "Several MQ commands check the working directory before they do anything, and " | |
14008 "fail if they find any modifications. They do this to ensure that you won't " | |
14009 "lose any changes that you have made, but not yet incorporated into a patch. " | |
14010 "The example below illustrates this; the <command role=\"hg-ext-mq\">qnew</" | |
14011 "command> command will not create a new patch if there are outstanding " | |
14012 "changes, caused in this case by the <command role=\"hg-cmd\">hg add</command> " | |
14013 "of <filename>file3</filename>." | |
14014 msgstr "" | |
14015 | |
14016 #. type: Content of: <book><chapter><sect1><sect2><para> | |
14017 #: ../en/ch12-mq.xml:464 | |
14018 msgid "" | |
14019 "Commands that check the working directory all take an <quote>I know what I'm " | |
14020 "doing</quote> option, which is always named <option>-f</option>. The exact " | |
14021 "meaning of <option>-f</option> depends on the command. For example, <command " | |
14022 "role=\"hg-cmd\">hg qnew <option role=\"hg-ext-mq-cmd-qnew-opt\">hg -f</" | |
14023 "option></command> will incorporate any outstanding changes into the new patch " | |
14024 "it creates, but <command role=\"hg-cmd\">hg qpop <option role=\"hg-ext-mq-cmd-" | |
14025 "qpop-opt\">hg -f</option></command> will revert modifications to any files " | |
14026 "affected by the patch that it is popping. Be sure to read the documentation " | |
14027 "for a command's <option>-f</option> option before you use it!" | |
14028 msgstr "" | |
14029 | |
14030 #. type: Content of: <book><chapter><sect1><sect2><title> | |
14031 #: ../en/ch12-mq.xml:479 | |
14032 msgid "Working on several patches at once" | |
14033 msgstr "" | |
14034 | |
14035 #. type: Content of: <book><chapter><sect1><sect2><para> | |
14036 #: ../en/ch12-mq.xml:481 | |
14037 msgid "" | |
14038 "The <command role=\"hg-ext-mq\">qrefresh</command> command always refreshes " | |
14039 "the <emphasis>topmost</emphasis> applied patch. This means that you can " | |
14040 "suspend work on one patch (by refreshing it), pop or push to make a different " | |
14041 "patch the top, and work on <emphasis>that</emphasis> patch for a while." | |
14042 msgstr "" | |
14043 | |
14044 #. type: Content of: <book><chapter><sect1><sect2><para> | |
14045 #: ../en/ch12-mq.xml:488 | |
14046 msgid "" | |
14047 "Here's an example that illustrates how you can use this ability. Let's say " | |
14048 "you're developing a new feature as two patches. The first is a change to the " | |
14049 "core of your software, and the second&emdash;layered on top of the " | |
14050 "first&emdash;changes the user interface to use the code you just added to the " | |
14051 "core. If you notice a bug in the core while you're working on the UI patch, " | |
14052 "it's easy to fix the core. Simply <command role=\"hg-ext-mq\">qrefresh</" | |
14053 "command> the UI patch to save your in-progress changes, and <command role=" | |
14054 "\"hg-ext-mq\">qpop</command> down to the core patch. Fix the core bug, " | |
14055 "<command role=\"hg-ext-mq\">qrefresh</command> the core patch, and <command " | |
14056 "role=\"hg-ext-mq\">qpush</command> back to the UI patch to continue where you " | |
14057 "left off." | |
14058 msgstr "" | |
14059 | |
14060 #. type: Content of: <book><chapter><sect1><title> | |
14061 #: ../en/ch12-mq.xml:505 | |
14062 msgid "More about patches" | |
14063 msgstr "" | |
14064 | |
14065 #. type: Content of: <book><chapter><sect1><para> | |
14066 #: ../en/ch12-mq.xml:507 | |
14067 msgid "" | |
14068 "MQ uses the GNU <command>patch</command> command to apply patches, so it's " | |
14069 "helpful to know a few more detailed aspects of how <command>patch</command> " | |
14070 "works, and about patches themselves." | |
14071 msgstr "" | |
14072 | |
14073 #. type: Content of: <book><chapter><sect1><sect2><title> | |
14074 #: ../en/ch12-mq.xml:513 | |
14075 msgid "The strip count" | |
14076 msgstr "" | |
14077 | |
14078 #. type: Content of: <book><chapter><sect1><sect2><para> | |
14079 #: ../en/ch12-mq.xml:515 | |
14080 msgid "" | |
14081 "If you look at the file headers in a patch, you will notice that the " | |
14082 "pathnames usually have an extra component on the front that isn't present in " | |
14083 "the actual path name. This is a holdover from the way that people used to " | |
14084 "generate patches (people still do this, but it's somewhat rare with modern " | |
14085 "revision control tools)." | |
14086 msgstr "" | |
14087 | |
14088 #. type: Content of: <book><chapter><sect1><sect2><para> | |
14089 #: ../en/ch12-mq.xml:522 | |
14090 msgid "" | |
14091 "Alice would unpack a tarball, edit her files, then decide that she wanted to " | |
14092 "create a patch. So she'd rename her working directory, unpack the tarball " | |
14093 "again (hence the need for the rename), and use the <option role=\"cmd-opt-diff" | |
14094 "\">-r</option> and <option role=\"cmd-opt-diff\">-N</option> options to " | |
14095 "<command>diff</command> to recursively generate a patch between the " | |
14096 "unmodified directory and the modified one. The result would be that the name " | |
14097 "of the unmodified directory would be at the front of the left-hand path in " | |
14098 "every file header, and the name of the modified directory would be at the " | |
14099 "front of the right-hand path." | |
14100 msgstr "" | |
14101 | |
14102 #. type: Content of: <book><chapter><sect1><sect2><para> | |
14103 #: ../en/ch12-mq.xml:535 | |
14104 msgid "" | |
14105 "Since someone receiving a patch from the Alices of the net would be unlikely " | |
14106 "to have unmodified and modified directories with exactly the same names, the " | |
14107 "<command>patch</command> command has a <option role=\"cmd-opt-patch\">-p</" | |
14108 "option> option that indicates the number of leading path name components to " | |
14109 "strip when trying to apply a patch. This number is called the " | |
14110 "<emphasis>strip count</emphasis>." | |
14111 msgstr "" | |
14112 | |
14113 #. type: Content of: <book><chapter><sect1><sect2><para> | |
14114 #: ../en/ch12-mq.xml:543 | |
14115 msgid "" | |
14116 "An option of <quote><literal>-p1</literal></quote> means <quote>use a strip " | |
14117 "count of one</quote>. If <command>patch</command> sees a file name " | |
14118 "<filename>foo/bar/baz</filename> in a file header, it will strip " | |
14119 "<filename>foo</filename> and try to patch a file named <filename>bar/baz</" | |
14120 "filename>. (Strictly speaking, the strip count refers to the number of " | |
14121 "<emphasis>path separators</emphasis> (and the components that go with them ) " | |
14122 "to strip. A strip count of one will turn <filename>foo/bar</filename> into " | |
14123 "<filename>bar</filename>, but <filename>/foo/bar</filename> (notice the extra " | |
14124 "leading slash) into <filename>foo/bar</filename>.)" | |
14125 msgstr "" | |
14126 | |
14127 #. type: Content of: <book><chapter><sect1><sect2><para> | |
14128 #: ../en/ch12-mq.xml:556 | |
14129 msgid "" | |
14130 "The <quote>standard</quote> strip count for patches is one; almost all " | |
14131 "patches contain one leading path name component that needs to be stripped. " | |
14132 "Mercurial's <command role=\"hg-cmd\">hg diff</command> command generates path " | |
14133 "names in this form, and the <command role=\"hg-cmd\">hg import</command> " | |
14134 "command and MQ expect patches to have a strip count of one." | |
14135 msgstr "" | |
14136 | |
14137 #. type: Content of: <book><chapter><sect1><sect2><para> | |
14138 #: ../en/ch12-mq.xml:564 | |
14139 msgid "" | |
14140 "If you receive a patch from someone that you want to add to your patch queue, " | |
14141 "and the patch needs a strip count other than one, you cannot just <command " | |
14142 "role=\"hg-ext-mq\">qimport</command> the patch, because <command role=\"hg-" | |
14143 "ext-mq\">qimport</command> does not yet have a <literal>-p</literal> option " | |
14144 "(see <ulink role=\"hg-bug\" url=\"http://www.selenic.com/mercurial/bts/" | |
14145 "issue311\">issue 311</ulink>). Your best bet is to <command role=\"hg-ext-mq" | |
14146 "\">qnew</command> a patch of your own, then use <command>patch -pN</command> " | |
14147 "to apply their patch, followed by <command role=\"hg-cmd\">hg addremove</" | |
14148 "command> to pick up any files added or removed by the patch, followed by " | |
14149 "<command role=\"hg-ext-mq\">hg qrefresh</command>. This complexity may become " | |
14150 "unnecessary; see <ulink role=\"hg-bug\" url=\"http://www.selenic.com/" | |
14151 "mercurial/bts/issue311\">issue 311</ulink> for details." | |
14152 msgstr "" | |
14153 | |
14154 #. type: Content of: <book><chapter><sect1><sect2><title> | |
14155 #: ../en/ch12-mq.xml:583 | |
14156 msgid "Strategies for applying a patch" | |
14157 msgstr "" | |
14158 | |
14159 #. type: Content of: <book><chapter><sect1><sect2><para> | |
14160 #: ../en/ch12-mq.xml:585 | |
14161 msgid "" | |
14162 "When <command>patch</command> applies a hunk, it tries a handful of " | |
14163 "successively less accurate strategies to try to make the hunk apply. This " | |
14164 "falling-back technique often makes it possible to take a patch that was " | |
14165 "generated against an old version of a file, and apply it against a newer " | |
14166 "version of that file." | |
14167 msgstr "" | |
14168 | |
14169 #. type: Content of: <book><chapter><sect1><sect2><para> | |
14170 #: ../en/ch12-mq.xml:592 | |
14171 msgid "" | |
14172 "First, <command>patch</command> tries an exact match, where the line numbers, " | |
14173 "the context, and the text to be modified must apply exactly. If it cannot " | |
14174 "make an exact match, it tries to find an exact match for the context, without " | |
14175 "honouring the line numbering information. If this succeeds, it prints a line " | |
14176 "of output saying that the hunk was applied, but at some <emphasis>offset</" | |
14177 "emphasis> from the original line number." | |
14178 msgstr "" | |
14179 | |
14180 #. type: Content of: <book><chapter><sect1><sect2><para> | |
14181 #: ../en/ch12-mq.xml:601 | |
14182 msgid "" | |
14183 "If a context-only match fails, <command>patch</command> removes the first and " | |
14184 "last lines of the context, and tries a <emphasis>reduced</emphasis> context-" | |
14185 "only match. If the hunk with reduced context succeeds, it prints a message " | |
14186 "saying that it applied the hunk with a <emphasis>fuzz factor</emphasis> (the " | |
14187 "number after the fuzz factor indicates how many lines of context " | |
14188 "<command>patch</command> had to trim before the patch applied)." | |
14189 msgstr "" | |
14190 | |
14191 #. type: Content of: <book><chapter><sect1><sect2><para> | |
14192 #: ../en/ch12-mq.xml:610 | |
14193 msgid "" | |
14194 "When neither of these techniques works, <command>patch</command> prints a " | |
14195 "message saying that the hunk in question was rejected. It saves rejected " | |
14196 "hunks (also simply called <quote>rejects</quote>) to a file with the same " | |
14197 "name, and an added <filename role=\"special\">.rej</filename> extension. It " | |
14198 "also saves an unmodified copy of the file with a <filename role=\"special\">." | |
14199 "orig</filename> extension; the copy of the file without any extensions will " | |
14200 "contain any changes made by hunks that <emphasis>did</emphasis> apply " | |
14201 "cleanly. If you have a patch that modifies <filename>foo</filename> with six " | |
14202 "hunks, and one of them fails to apply, you will have: an unmodified " | |
14203 "<filename>foo.orig</filename>, a <filename>foo.rej</filename> containing one " | |
14204 "hunk, and <filename>foo</filename>, containing the changes made by the five " | |
14205 "successful hunks." | |
14206 msgstr "" | |
14207 | |
14208 #. type: Content of: <book><chapter><sect1><sect2><title> | |
14209 #: ../en/ch12-mq.xml:628 | |
14210 msgid "Some quirks of patch representation" | |
14211 msgstr "" | |
14212 | |
14213 #. type: Content of: <book><chapter><sect1><sect2><para> | |
14214 #: ../en/ch12-mq.xml:630 | |
14215 msgid "" | |
14216 "There are a few useful things to know about how <command>patch</command> " | |
14217 "works with files." | |
14218 msgstr "" | |
14219 | |
14220 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
14221 #: ../en/ch12-mq.xml:633 | |
14222 msgid "" | |
14223 "This should already be obvious, but <command>patch</command> cannot handle " | |
14224 "binary files." | |
14225 msgstr "" | |
14226 | |
14227 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
14228 #: ../en/ch12-mq.xml:637 | |
14229 msgid "" | |
14230 "Neither does it care about the executable bit; it creates new files as " | |
14231 "readable, but not executable." | |
14232 msgstr "" | |
14233 | |
14234 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
14235 #: ../en/ch12-mq.xml:641 | |
14236 msgid "" | |
14237 "<command>patch</command> treats the removal of a file as a diff between the " | |
14238 "file to be removed and the empty file. So your idea of <quote>I deleted this " | |
14239 "file</quote> looks like <quote>every line of this file was deleted</quote> in " | |
14240 "a patch." | |
14241 msgstr "" | |
14242 | |
14243 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
14244 #: ../en/ch12-mq.xml:647 | |
14245 msgid "" | |
14246 "It treats the addition of a file as a diff between the empty file and the " | |
14247 "file to be added. So in a patch, your idea of <quote>I added this file</" | |
14248 "quote> looks like <quote>every line of this file was added</quote>." | |
14249 msgstr "" | |
14250 | |
14251 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
14252 #: ../en/ch12-mq.xml:653 | |
14253 msgid "" | |
14254 "It treats a renamed file as the removal of the old name, and the addition of " | |
14255 "the new name. This means that renamed files have a big footprint in " | |
14256 "patches. (Note also that Mercurial does not currently try to infer when " | |
14257 "files have been renamed or copied in a patch.)" | |
14258 msgstr "" | |
14259 | |
14260 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
14261 #: ../en/ch12-mq.xml:659 | |
14262 msgid "" | |
14263 "<command>patch</command> cannot represent empty files, so you cannot use a " | |
14264 "patch to represent the notion <quote>I added this empty file to the tree</" | |
14265 "quote>." | |
14266 msgstr "" | |
14267 | |
14268 #. type: Content of: <book><chapter><sect1><sect2><title> | |
14269 #: ../en/ch12-mq.xml:666 | |
14270 msgid "Beware the fuzz" | |
14271 msgstr "" | |
14272 | |
14273 #. type: Content of: <book><chapter><sect1><sect2><para> | |
14274 #: ../en/ch12-mq.xml:668 | |
14275 msgid "" | |
14276 "While applying a hunk at an offset, or with a fuzz factor, will often be " | |
14277 "completely successful, these inexact techniques naturally leave open the " | |
14278 "possibility of corrupting the patched file. The most common cases typically " | |
14279 "involve applying a patch twice, or at an incorrect location in the file. If " | |
14280 "<command>patch</command> or <command role=\"hg-ext-mq\">qpush</command> ever " | |
14281 "mentions an offset or fuzz factor, you should make sure that the modified " | |
14282 "files are correct afterwards." | |
14283 msgstr "" | |
14284 | |
14285 #. type: Content of: <book><chapter><sect1><sect2><para> | |
14286 #: ../en/ch12-mq.xml:678 | |
14287 msgid "" | |
14288 "It's often a good idea to refresh a patch that has applied with an offset or " | |
14289 "fuzz factor; refreshing the patch generates new context information that will " | |
14290 "make it apply cleanly. I say <quote>often,</quote> not <quote>always,</" | |
14291 "quote> because sometimes refreshing a patch will make it fail to apply " | |
14292 "against a different revision of the underlying files. In some cases, such as " | |
14293 "when you're maintaining a patch that must sit on top of multiple versions of " | |
14294 "a source tree, it's acceptable to have a patch apply with some fuzz, provided " | |
14295 "you've verified the results of the patching process in such cases." | |
14296 msgstr "" | |
14297 | |
14298 #. type: Content of: <book><chapter><sect1><sect2><title> | |
14299 #: ../en/ch12-mq.xml:691 | |
14300 msgid "Handling rejection" | |
14301 msgstr "" | |
14302 | |
14303 #. type: Content of: <book><chapter><sect1><sect2><para> | |
14304 #: ../en/ch12-mq.xml:693 | |
14305 msgid "" | |
14306 "If <command role=\"hg-ext-mq\">qpush</command> fails to apply a patch, it " | |
14307 "will print an error message and exit. If it has left <filename role=\"special" | |
14308 "\">.rej</filename> files behind, it is usually best to fix up the rejected " | |
14309 "hunks before you push more patches or do any further work." | |
14310 msgstr "" | |
14311 | |
14312 #. type: Content of: <book><chapter><sect1><sect2><para> | |
14313 #: ../en/ch12-mq.xml:699 | |
14314 msgid "" | |
14315 "If your patch <emphasis>used to</emphasis> apply cleanly, and no longer does " | |
14316 "because you've changed the underlying code that your patches are based on, " | |
14317 "Mercurial Queues can help; see section <xref linkend=\"sec.mq.merge\"/> for " | |
14318 "details." | |
14319 msgstr "" | |
14320 | |
14321 #. type: Content of: <book><chapter><sect1><sect2><para> | |
14322 #: ../en/ch12-mq.xml:705 | |
14323 msgid "" | |
14324 "Unfortunately, there aren't any great techniques for dealing with rejected " | |
14325 "hunks. Most often, you'll need to view the <filename role=\"special\">.rej</" | |
14326 "filename> file and edit the target file, applying the rejected hunks by hand." | |
14327 msgstr "" | |
14328 | |
14329 #. type: Content of: <book><chapter><sect1><sect2><para> | |
14330 #: ../en/ch12-mq.xml:710 | |
14331 msgid "" | |
14332 "If you're feeling adventurous, Neil Brown, a Linux kernel hacker, wrote a " | |
14333 "tool called <command>wiggle</command> <citation>web:wiggle</citation>, which " | |
14334 "is more vigorous than <command>patch</command> in its attempts to make a " | |
14335 "patch apply." | |
14336 msgstr "" | |
14337 | |
14338 #. type: Content of: <book><chapter><sect1><sect2><para> | |
14339 #: ../en/ch12-mq.xml:716 | |
14340 msgid "" | |
14341 "Another Linux kernel hacker, Chris Mason (the author of Mercurial Queues), " | |
14342 "wrote a similar tool called <command>mpatch</command> <citation>web:mpatch</" | |
14343 "citation>, which takes a simple approach to automating the application of " | |
14344 "hunks rejected by <command>patch</command>. The <command>mpatch</command> " | |
14345 "command can help with four common reasons that a hunk may be rejected:" | |
14346 msgstr "" | |
14347 | |
14348 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
14349 #: ../en/ch12-mq.xml:725 | |
14350 msgid "The context in the middle of a hunk has changed." | |
14351 msgstr "" | |
14352 | |
14353 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
14354 #: ../en/ch12-mq.xml:728 | |
14355 msgid "A hunk is missing some context at the beginning or end." | |
14356 msgstr "" | |
14357 | |
14358 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
14359 #: ../en/ch12-mq.xml:731 | |
14360 msgid "" | |
14361 "A large hunk might apply better&emdash;either entirely or in part&emdash;if " | |
14362 "it was broken up into smaller hunks." | |
14363 msgstr "" | |
14364 | |
14365 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
14366 #: ../en/ch12-mq.xml:735 | |
14367 msgid "" | |
14368 "A hunk removes lines with slightly different content than those currently " | |
14369 "present in the file." | |
14370 msgstr "" | |
14371 | |
14372 #. type: Content of: <book><chapter><sect1><sect2><para> | |
14373 #: ../en/ch12-mq.xml:739 | |
14374 msgid "" | |
14375 "If you use <command>wiggle</command> or <command>mpatch</command>, you should " | |
14376 "be doubly careful to check your results when you're done. In fact, " | |
14377 "<command>mpatch</command> enforces this method of double-checking the tool's " | |
14378 "output, by automatically dropping you into a merge program when it has done " | |
14379 "its job, so that you can verify its work and finish off any remaining merges." | |
14380 msgstr "" | |
14381 | |
14382 #. type: Content of: <book><chapter><sect1><title> | |
14383 #: ../en/ch12-mq.xml:751 | |
14384 msgid "Getting the best performance out of MQ" | |
14385 msgstr "" | |
14386 | |
14387 #. type: Content of: <book><chapter><sect1><para> | |
14388 #: ../en/ch12-mq.xml:753 | |
14389 msgid "" | |
14390 "MQ is very efficient at handling a large number of patches. I ran some " | |
14391 "performance experiments in mid-2006 for a talk that I gave at the 2006 " | |
14392 "EuroPython conference <citation>web:europython</citation>. I used as my data " | |
14393 "set the Linux 2.6.17-mm1 patch series, which consists of 1,738 patches. I " | |
14394 "applied these on top of a Linux kernel repository containing all 27,472 " | |
14395 "revisions between Linux 2.6.12-rc2 and Linux 2.6.17." | |
14396 msgstr "" | |
14397 | |
14398 #. type: Content of: <book><chapter><sect1><para> | |
14399 #: ../en/ch12-mq.xml:762 | |
14400 msgid "" | |
14401 "On my old, slow laptop, I was able to <command role=\"hg-cmd\">hg qpush " | |
14402 "<option role=\"hg-ext-mq-cmd-qpush-opt\">hg -a</option></command> all 1,738 " | |
14403 "patches in 3.5 minutes, and <command role=\"hg-cmd\">hg qpop <option role=" | |
14404 "\"hg-ext-mq-cmd-qpop-opt\">hg -a</option></command> them all in 30 seconds. " | |
14405 "(On a newer laptop, the time to push all patches dropped to two minutes.) I " | |
14406 "could <command role=\"hg-ext-mq\">qrefresh</command> one of the biggest " | |
14407 "patches (which made 22,779 lines of changes to 287 files) in 6.6 seconds." | |
14408 msgstr "" | |
14409 | |
14410 #. type: Content of: <book><chapter><sect1><para> | |
14411 #: ../en/ch12-mq.xml:773 | |
14412 msgid "" | |
14413 "Clearly, MQ is well suited to working in large trees, but there are a few " | |
14414 "tricks you can use to get the best performance of it." | |
14415 msgstr "" | |
14416 | |
14417 #. type: Content of: <book><chapter><sect1><para> | |
14418 #: ../en/ch12-mq.xml:777 | |
14419 msgid "" | |
14420 "First of all, try to <quote>batch</quote> operations together. Every time " | |
14421 "you run <command role=\"hg-ext-mq\">qpush</command> or <command role=\"hg-ext-" | |
14422 "mq\">qpop</command>, these commands scan the working directory once to make " | |
14423 "sure you haven't made some changes and then forgotten to run <command role=" | |
14424 "\"hg-ext-mq\">qrefresh</command>. On a small tree, the time that this scan " | |
14425 "takes is unnoticeable. However, on a medium-sized tree (containing tens of " | |
14426 "thousands of files), it can take a second or more." | |
14427 msgstr "" | |
14428 | |
14429 #. type: Content of: <book><chapter><sect1><para> | |
14430 #: ../en/ch12-mq.xml:788 | |
14431 msgid "" | |
14432 "The <command role=\"hg-ext-mq\">qpush</command> and <command role=\"hg-ext-mq" | |
14433 "\">qpop</command> commands allow you to push and pop multiple patches at a " | |
14434 "time. You can identify the <quote>destination patch</quote> that you want to " | |
14435 "end up at. When you <command role=\"hg-ext-mq\">qpush</command> with a " | |
14436 "destination specified, it will push patches until that patch is at the top of " | |
14437 "the applied stack. When you <command role=\"hg-ext-mq\">qpop</command> to a " | |
14438 "destination, MQ will pop patches until the destination patch is at the top." | |
14439 msgstr "" | |
14440 | |
14441 #. type: Content of: <book><chapter><sect1><para> | |
14442 #: ../en/ch12-mq.xml:798 | |
14443 msgid "" | |
14444 "You can identify a destination patch using either the name of the patch, or " | |
14445 "by number. If you use numeric addressing, patches are counted from zero; " | |
14446 "this means that the first patch is zero, the second is one, and so on." | |
14447 msgstr "" | |
14448 | |
14449 #. type: Content of: <book><chapter><sect1><title> | |
14450 #: ../en/ch12-mq.xml:805 | |
14451 msgid "Updating your patches when the underlying code changes" | |
14452 msgstr "" | |
14453 | |
14454 #. type: Content of: <book><chapter><sect1><para> | |
14455 #: ../en/ch12-mq.xml:808 | |
14456 msgid "" | |
14457 "It's common to have a stack of patches on top of an underlying repository " | |
14458 "that you don't modify directly. If you're working on changes to third-party " | |
14459 "code, or on a feature that is taking longer to develop than the rate of " | |
14460 "change of the code beneath, you will often need to sync up with the " | |
14461 "underlying code, and fix up any hunks in your patches that no longer apply. " | |
14462 "This is called <emphasis>rebasing</emphasis> your patch series." | |
14463 msgstr "" | |
14464 | |
14465 #. type: Content of: <book><chapter><sect1><para> | |
14466 #: ../en/ch12-mq.xml:817 | |
14467 msgid "" | |
14468 "The simplest way to do this is to <command role=\"hg-cmd\">hg qpop <option " | |
14469 "role=\"hg-ext-mq-cmd-qpop-opt\">hg -a</option></command> your patches, then " | |
14470 "<command role=\"hg-cmd\">hg pull</command> changes into the underlying " | |
14471 "repository, and finally <command role=\"hg-cmd\">hg qpush <option role=\"hg-" | |
14472 "ext-mq-cmd-qpop-opt\">hg -a</option></command> your patches again. MQ will " | |
14473 "stop pushing any time it runs across a patch that fails to apply during " | |
14474 "conflicts, allowing you to fix your conflicts, <command role=\"hg-ext-mq" | |
14475 "\">qrefresh</command> the affected patch, and continue pushing until you have " | |
14476 "fixed your entire stack." | |
14477 msgstr "" | |
14478 | |
14479 #. type: Content of: <book><chapter><sect1><para> | |
14480 #: ../en/ch12-mq.xml:829 | |
14481 msgid "" | |
14482 "This approach is easy to use and works well if you don't expect changes to " | |
14483 "the underlying code to affect how well your patches apply. If your patch " | |
14484 "stack touches code that is modified frequently or invasively in the " | |
14485 "underlying repository, however, fixing up rejected hunks by hand quickly " | |
14486 "becomes tiresome." | |
14487 msgstr "" | |
14488 | |
14489 #. type: Content of: <book><chapter><sect1><para> | |
14490 #: ../en/ch12-mq.xml:836 | |
14491 msgid "" | |
14492 "It's possible to partially automate the rebasing process. If your patches " | |
14493 "apply cleanly against some revision of the underlying repo, MQ can use this " | |
14494 "information to help you to resolve conflicts between your patches and a " | |
14495 "different revision." | |
14496 msgstr "" | |
14497 | |
14498 #. type: Content of: <book><chapter><sect1><para> | |
14499 #: ../en/ch12-mq.xml:842 | |
14500 msgid "The process is a little involved." | |
14501 msgstr "" | |
14502 | |
14503 #. type: Content of: <book><chapter><sect1><orderedlist><listitem><para> | |
14504 #: ../en/ch12-mq.xml:844 | |
14505 msgid "" | |
14506 "To begin, <command role=\"hg-cmd\">hg qpush -a</command> all of your patches " | |
14507 "on top of the revision where you know that they apply cleanly." | |
14508 msgstr "" | |
14509 | |
14510 #. type: Content of: <book><chapter><sect1><orderedlist><listitem><para> | |
14511 #: ../en/ch12-mq.xml:848 | |
14512 msgid "" | |
14513 "Save a backup copy of your patch directory using <command role=\"hg-cmd\">hg " | |
14514 "qsave <option role=\"hg-ext-mq-cmd-qsave-opt\">hg -e</option> <option role=" | |
14515 "\"hg-ext-mq-cmd-qsave-opt\">hg -c</option></command>. This prints the name " | |
14516 "of the directory that it has saved the patches in. It will save the patches " | |
14517 "to a directory called <filename role=\"special\" class=\"directory\">.hg/" | |
14518 "patches.N</filename>, where <literal>N</literal> is a small integer. It also " | |
14519 "commits a <quote>save changeset</quote> on top of your applied patches; this " | |
14520 "is for internal book-keeping, and records the states of the <filename role=" | |
14521 "\"special\">series</filename> and <filename role=\"special\">status</" | |
14522 "filename> files." | |
14523 msgstr "" | |
14524 | |
14525 #. type: Content of: <book><chapter><sect1><orderedlist><listitem><para> | |
14526 #: ../en/ch12-mq.xml:862 | |
14527 msgid "" | |
14528 "Use <command role=\"hg-cmd\">hg pull</command> to bring new changes into the " | |
14529 "underlying repository. (Don't run <command role=\"hg-cmd\">hg pull -u</" | |
14530 "command>; see below for why.)" | |
14531 msgstr "" | |
14532 | |
14533 #. type: Content of: <book><chapter><sect1><orderedlist><listitem><para> | |
14534 #: ../en/ch12-mq.xml:867 | |
14535 msgid "" | |
14536 "Update to the new tip revision, using <command role=\"hg-cmd\">hg update " | |
14537 "<option role=\"hg-opt-update\">-C</option></command> to override the patches " | |
14538 "you have pushed." | |
14539 msgstr "" | |
14540 | |
14541 #. type: Content of: <book><chapter><sect1><orderedlist><listitem><para> | |
14542 #: ../en/ch12-mq.xml:872 | |
14543 msgid "" | |
14544 "Merge all patches using \\hgcmdargs{qpush}{<option role=\"hg-ext-mq-cmd-qpush-" | |
14545 "opt\">hg -m</option> <option role=\"hg-ext-mq-cmd-qpush-opt\">hg -a</" | |
14546 "option>}. The <option role=\"hg-ext-mq-cmd-qpush-opt\">hg -m</option> option " | |
14547 "to <command role=\"hg-ext-mq\">qpush</command> tells MQ to perform a three-" | |
14548 "way merge if the patch fails to apply." | |
14549 msgstr "" | |
14550 | |
14551 #. type: Content of: <book><chapter><sect1><para> | |
14552 #: ../en/ch12-mq.xml:882 | |
14553 msgid "" | |
14554 "During the <command role=\"hg-cmd\">hg qpush <option role=\"hg-ext-mq-cmd-" | |
14555 "qpush-opt\">hg -m</option></command>, each patch in the <filename role=" | |
14556 "\"special\">series</filename> file is applied normally. If a patch applies " | |
14557 "with fuzz or rejects, MQ looks at the queue you <command role=\"hg-ext-mq" | |
14558 "\">qsave</command>d, and performs a three-way merge with the corresponding " | |
14559 "changeset. This merge uses Mercurial's normal merge machinery, so it may pop " | |
14560 "up a GUI merge tool to help you to resolve problems." | |
14561 msgstr "" | |
14562 | |
14563 #. type: Content of: <book><chapter><sect1><para> | |
14564 #: ../en/ch12-mq.xml:892 | |
14565 msgid "" | |
14566 "When you finish resolving the effects of a patch, MQ refreshes your patch " | |
14567 "based on the result of the merge." | |
14568 msgstr "" | |
14569 | |
14570 #. type: Content of: <book><chapter><sect1><para> | |
14571 #: ../en/ch12-mq.xml:895 | |
14572 msgid "" | |
14573 "At the end of this process, your repository will have one extra head from the " | |
14574 "old patch queue, and a copy of the old patch queue will be in <filename role=" | |
14575 "\"special\" class=\"directory\">.hg/patches.N</filename>. You can remove the " | |
14576 "extra head using <command role=\"hg-cmd\">hg qpop -a -n patches.N</command> " | |
14577 "or <command role=\"hg-cmd\">hg strip</command>. You can delete <filename " | |
14578 "role=\"special\" class=\"directory\">.hg/patches.N</filename> once you are " | |
14579 "sure that you no longer need it as a backup." | |
14580 msgstr "" | |
14581 | |
14582 #. type: Content of: <book><chapter><sect1><title> | |
14583 #: ../en/ch12-mq.xml:907 | |
14584 msgid "Identifying patches" | |
14585 msgstr "" | |
14586 | |
14587 #. type: Content of: <book><chapter><sect1><para> | |
14588 #: ../en/ch12-mq.xml:909 | |
14589 msgid "" | |
14590 "MQ commands that work with patches let you refer to a patch either by using " | |
14591 "its name or by a number. By name is obvious enough; pass the name " | |
14592 "<filename>foo.patch</filename> to <command role=\"hg-ext-mq\">qpush</" | |
14593 "command>, for example, and it will push patches until <filename>foo.patch</" | |
14594 "filename> is applied." | |
14595 msgstr "" | |
14596 | |
14597 #. type: Content of: <book><chapter><sect1><para> | |
14598 #: ../en/ch12-mq.xml:916 | |
14599 msgid "" | |
14600 "As a shortcut, you can refer to a patch using both a name and a numeric " | |
14601 "offset; <literal>foo.patch-2</literal> means <quote>two patches before " | |
14602 "<literal>foo.patch</literal></quote>, while <literal>bar.patch+4</literal> " | |
14603 "means <quote>four patches after <literal>bar.patch</literal></quote>." | |
14604 msgstr "" | |
14605 | |
14606 #. type: Content of: <book><chapter><sect1><para> | |
14607 #: ../en/ch12-mq.xml:922 | |
14608 msgid "" | |
14609 "Referring to a patch by index isn't much different. The first patch printed " | |
14610 "in the output of <command role=\"hg-ext-mq\">qseries</command> is patch zero " | |
14611 "(yes, it's one of those start-at-zero counting systems); the second is patch " | |
14612 "one; and so on." | |
14613 msgstr "" | |
14614 | |
14615 #. type: Content of: <book><chapter><sect1><para> | |
14616 #: ../en/ch12-mq.xml:928 | |
14617 msgid "" | |
14618 "MQ also makes it easy to work with patches when you are using normal " | |
14619 "Mercurial commands. Every command that accepts a changeset ID will also " | |
14620 "accept the name of an applied patch. MQ augments the tags normally in the " | |
14621 "repository with an eponymous one for each applied patch. In addition, the " | |
14622 "special tags \\index{tags!special tag names!<literal>qbase</literal>}" | |
14623 "<literal>qbase</literal> and \\index{tags!special tag names!<literal>qtip</" | |
14624 "literal>}<literal>qtip</literal> identify the <quote>bottom-most</quote> and " | |
14625 "topmost applied patches, respectively." | |
14626 msgstr "" | |
14627 | |
14628 #. type: Content of: <book><chapter><sect1><para> | |
14629 #: ../en/ch12-mq.xml:940 | |
14630 msgid "" | |
14631 "These additions to Mercurial's normal tagging capabilities make dealing with " | |
14632 "patches even more of a breeze." | |
14633 msgstr "" | |
14634 | |
14635 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
14636 #: ../en/ch12-mq.xml:943 | |
14637 msgid "Want to patchbomb a mailing list with your latest series of changes?" | |
14638 msgstr "" | |
14639 | |
14640 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
14641 #: ../en/ch12-mq.xml:947 | |
14642 msgid "" | |
14643 "(Don't know what <quote>patchbombing</quote> is? See section <xref linkend=" | |
14644 "\"sec.hgext.patchbomb\"/>.)" | |
14645 msgstr "" | |
14646 | |
14647 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
14648 #: ../en/ch12-mq.xml:950 | |
14649 msgid "" | |
14650 "Need to see all of the patches since <literal>foo.patch</literal> that have " | |
14651 "touched files in a subdirectory of your tree?" | |
14652 msgstr "" | |
14653 | |
14654 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><programlisting><emphasis> | |
14655 #: ../en/ch12-mq.xml:954 | |
14656 msgid "subdir" | |
14657 msgstr "" | |
14658 | |
14659 #. type: Content of: <book><chapter><sect1><para> | |
14660 #: ../en/ch12-mq.xml:959 | |
14661 msgid "" | |
14662 "Because MQ makes the names of patches available to the rest of Mercurial " | |
14663 "through its normal internal tag machinery, you don't need to type in the " | |
14664 "entire name of a patch when you want to identify it by name." | |
14665 msgstr "" | |
14666 | |
14667 #. type: Content of: <book><chapter><sect1><para> | |
14668 #: ../en/ch12-mq.xml:964 | |
14669 msgid "" | |
14670 "Another nice consequence of representing patch names as tags is that when you " | |
14671 "run the <command role=\"hg-cmd\">hg log</command> command, it will display a " | |
14672 "patch's name as a tag, simply as part of its normal output. This makes it " | |
14673 "easy to visually distinguish applied patches from underlying <quote>normal</" | |
14674 "quote> revisions. The following example shows a few normal Mercurial " | |
14675 "commands in use with applied patches." | |
14676 msgstr "" | |
14677 | |
14678 #. type: Content of: <book><chapter><sect1><title> | |
14679 #: ../en/ch12-mq.xml:977 | |
14680 msgid "Useful things to know about" | |
14681 msgstr "" | |
14682 | |
14683 #. type: Content of: <book><chapter><sect1><para> | |
14684 #: ../en/ch12-mq.xml:979 | |
14685 msgid "" | |
14686 "There are a number of aspects of MQ usage that don't fit tidily into sections " | |
14687 "of their own, but that are good to know. Here they are, in one place." | |
14688 msgstr "" | |
14689 | |
14690 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
14691 #: ../en/ch12-mq.xml:984 | |
14692 msgid "" | |
14693 "Normally, when you <command role=\"hg-ext-mq\">qpop</command> a patch and " | |
14694 "<command role=\"hg-ext-mq\">qpush</command> it again, the changeset that " | |
14695 "represents the patch after the pop/push will have a <emphasis>different " | |
14696 "identity</emphasis> than the changeset that represented the hash beforehand. " | |
14697 "See section <xref linkend=\"sec.mqref.cmd.qpush\"/> for information as to why " | |
14698 "this is." | |
14699 msgstr "" | |
14700 | |
14701 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
14702 #: ../en/ch12-mq.xml:993 | |
14703 msgid "" | |
14704 "It's not a good idea to <command role=\"hg-cmd\">hg merge</command> changes " | |
14705 "from another branch with a patch changeset, at least if you want to maintain " | |
14706 "the <quote>patchiness</quote> of that changeset and changesets below it on " | |
14707 "the patch stack. If you try to do this, it will appear to succeed, but MQ " | |
14708 "will become confused." | |
14709 msgstr "" | |
14710 | |
14711 #. type: Content of: <book><chapter><sect1><title> | |
14712 #: ../en/ch12-mq.xml:1004 | |
14713 msgid "Managing patches in a repository" | |
14714 msgstr "" | |
14715 | |
14716 #. type: Content of: <book><chapter><sect1><para> | |
14717 #: ../en/ch12-mq.xml:1006 | |
14718 msgid "" | |
14719 "Because MQ's <filename role=\"special\" class=\"directory\">.hg/patches</" | |
14720 "filename> directory resides outside a Mercurial repository's working " | |
14721 "directory, the <quote>underlying</quote> Mercurial repository knows nothing " | |
14722 "about the management or presence of patches." | |
14723 msgstr "" | |
14724 | |
14725 #. type: Content of: <book><chapter><sect1><para> | |
14726 #: ../en/ch12-mq.xml:1012 | |
14727 msgid "" | |
14728 "This presents the interesting possibility of managing the contents of the " | |
14729 "patch directory as a Mercurial repository in its own right. This can be a " | |
14730 "useful way to work. For example, you can work on a patch for a while, " | |
14731 "<command role=\"hg-ext-mq\">qrefresh</command> it, then <command role=\"hg-cmd" | |
14732 "\">hg commit</command> the current state of the patch. This lets you " | |
14733 "<quote>roll back</quote> to that version of the patch later on." | |
14734 msgstr "" | |
14735 | |
14736 #. type: Content of: <book><chapter><sect1><para> | |
14737 #: ../en/ch12-mq.xml:1021 | |
14738 msgid "" | |
14739 "You can then share different versions of the same patch stack among multiple " | |
14740 "underlying repositories. I use this when I am developing a Linux kernel " | |
14741 "feature. I have a pristine copy of my kernel sources for each of several CPU " | |
14742 "architectures, and a cloned repository under each that contains the patches I " | |
14743 "am working on. When I want to test a change on a different architecture, I " | |
14744 "push my current patches to the patch repository associated with that kernel " | |
14745 "tree, pop and push all of my patches, and build and test that kernel." | |
14746 msgstr "" | |
14747 | |
14748 #. type: Content of: <book><chapter><sect1><para> | |
14749 #: ../en/ch12-mq.xml:1031 | |
14750 msgid "" | |
14751 "Managing patches in a repository makes it possible for multiple developers to " | |
14752 "work on the same patch series without colliding with each other, all on top " | |
14753 "of an underlying source base that they may or may not control." | |
14754 msgstr "" | |
14755 | |
14756 #. type: Content of: <book><chapter><sect1><sect2><title> | |
14757 #: ../en/ch12-mq.xml:1037 | |
14758 msgid "MQ support for patch repositories" | |
14759 msgstr "" | |
14760 | |
14761 #. type: Content of: <book><chapter><sect1><sect2><para> | |
14762 #: ../en/ch12-mq.xml:1039 | |
14763 msgid "" | |
14764 "MQ helps you to work with the <filename role=\"special\" class=\"directory\">." | |
14765 "hg/patches</filename> directory as a repository; when you prepare a " | |
14766 "repository for working with patches using <command role=\"hg-ext-mq\">qinit</" | |
14767 "command>, you can pass the <option role=\"hg-ext-mq-cmd-qinit-opt\">hg -c</" | |
14768 "option> option to create the <filename role=\"special\" class=\"directory\">." | |
14769 "hg/patches</filename> directory as a Mercurial repository." | |
14770 msgstr "" | |
14771 | |
14772 #. type: Content of: <book><chapter><sect1><sect2><note><para> | |
14773 #: ../en/ch12-mq.xml:1049 | |
14774 msgid "" | |
14775 "If you forget to use the <option role=\"hg-ext-mq-cmd-qinit-opt\">hg -c</" | |
14776 "option> option, you can simply go into the <filename role=\"special\" class=" | |
14777 "\"directory\">.hg/patches</filename> directory at any time and run <command " | |
14778 "role=\"hg-cmd\">hg init</command>. Don't forget to add an entry for the " | |
14779 "<filename role=\"special\">status</filename> file to the <filename role=" | |
14780 "\"special\">.hgignore</filename> file, though" | |
14781 msgstr "" | |
14782 | |
14783 #. type: Content of: <book><chapter><sect1><sect2><note><para> | |
14784 #: ../en/ch12-mq.xml:1058 | |
14785 msgid "" | |
14786 "(<command role=\"hg-cmd\">hg qinit <option role=\"hg-ext-mq-cmd-qinit-opt" | |
14787 "\">hg -c</option></command> does this for you automatically); you " | |
14788 "<emphasis>really</emphasis> don't want to manage the <filename role=\"special" | |
14789 "\">status</filename> file." | |
14790 msgstr "" | |
14791 | |
14792 #. type: Content of: <book><chapter><sect1><sect2><para> | |
14793 #: ../en/ch12-mq.xml:1065 | |
14794 msgid "" | |
14795 "As a convenience, if MQ notices that the <filename class=\"directory\">.hg/" | |
14796 "patches</filename> directory is a repository, it will automatically <command " | |
14797 "role=\"hg-cmd\">hg add</command> every patch that you create and import." | |
14798 msgstr "" | |
14799 | |
14800 #. type: Content of: <book><chapter><sect1><sect2><para> | |
14801 #: ../en/ch12-mq.xml:1070 | |
14802 msgid "" | |
14803 "MQ provides a shortcut command, <command role=\"hg-ext-mq\">qcommit</" | |
14804 "command>, that runs <command role=\"hg-cmd\">hg commit</command> in the " | |
14805 "<filename role=\"special\" class=\"directory\">.hg/patches</filename> " | |
14806 "directory. This saves some bothersome typing." | |
14807 msgstr "" | |
14808 | |
14809 #. type: Content of: <book><chapter><sect1><sect2><para> | |
14810 #: ../en/ch12-mq.xml:1076 | |
14811 msgid "" | |
14812 "Finally, as a convenience to manage the patch directory, you can define the " | |
14813 "alias <command>mq</command> on Unix systems. For example, on Linux systems " | |
14814 "using the <command>bash</command> shell, you can include the following " | |
14815 "snippet in your <filename role=\"home\">~/.bashrc</filename>." | |
14816 msgstr "" | |
14817 | |
14818 #. type: Content of: <book><chapter><sect1><sect2><para> | |
14819 #: ../en/ch12-mq.xml:1086 | |
14820 msgid "" | |
14821 "You can then issue commands of the form <command>mq pull</command> from the " | |
14822 "main repository." | |
14823 msgstr "" | |
14824 | |
14825 #. type: Content of: <book><chapter><sect1><sect2><title> | |
14826 #: ../en/ch12-mq.xml:1091 | |
14827 msgid "A few things to watch out for" | |
14828 msgstr "" | |
14829 | |
14830 #. type: Content of: <book><chapter><sect1><sect2><para> | |
14831 #: ../en/ch12-mq.xml:1093 | |
14832 msgid "" | |
14833 "MQ's support for working with a repository full of patches is limited in a " | |
14834 "few small respects." | |
14835 msgstr "" | |
14836 | |
14837 #. type: Content of: <book><chapter><sect1><sect2><para> | |
14838 #: ../en/ch12-mq.xml:1096 | |
14839 msgid "" | |
14840 "MQ cannot automatically detect changes that you make to the patch directory. " | |
14841 "If you <command role=\"hg-cmd\">hg pull</command>, manually edit, or <command " | |
14842 "role=\"hg-cmd\">hg update</command> changes to patches or the <filename role=" | |
14843 "\"special\">series</filename> file, you will have to <command role=\"hg-cmd" | |
14844 "\">hg qpop <option role=\"hg-ext-mq-cmd-qpop-opt\">hg -a</option></command> " | |
14845 "and then <command role=\"hg-cmd\">hg qpush <option role=\"hg-ext-mq-cmd-qpush-" | |
14846 "opt\">hg -a</option></command> in the underlying repository to see those " | |
14847 "changes show up there. If you forget to do this, you can confuse MQ's idea " | |
14848 "of which patches are applied." | |
14849 msgstr "" | |
14850 | |
14851 #. type: Content of: <book><chapter><sect1><title> | |
14852 #: ../en/ch12-mq.xml:1112 | |
14853 msgid "Third party tools for working with patches" | |
14854 msgstr "" | |
14855 | |
14856 #. type: Content of: <book><chapter><sect1><para> | |
14857 #: ../en/ch12-mq.xml:1114 | |
14858 msgid "" | |
14859 "Once you've been working with patches for a while, you'll find yourself " | |
14860 "hungry for tools that will help you to understand and manipulate the patches " | |
14861 "you're dealing with." | |
14862 msgstr "" | |
14863 | |
14864 #. type: Content of: <book><chapter><sect1><para> | |
14865 #: ../en/ch12-mq.xml:1118 | |
14866 msgid "" | |
14867 "The <command>diffstat</command> command <citation>web:diffstat</citation> " | |
14868 "generates a histogram of the modifications made to each file in a patch. It " | |
14869 "provides a good way to <quote>get a sense of</quote> a patch&emdash;which " | |
14870 "files it affects, and how much change it introduces to each file and as a " | |
14871 "whole. (I find that it's a good idea to use <command>diffstat</command>'s " | |
14872 "<option role=\"cmd-opt-diffstat\">-p</option> option as a matter of course, " | |
14873 "as otherwise it will try to do clever things with prefixes of file names that " | |
14874 "inevitably confuse at least me.)" | |
14875 msgstr "" | |
14876 | |
14877 #. type: Content of: <book><chapter><sect1><para> | |
14878 #: ../en/ch12-mq.xml:1132 | |
14879 msgid "" | |
14880 "The <literal role=\"package\">patchutils</literal> package <citation>web:" | |
14881 "patchutils</citation> is invaluable. It provides a set of small utilities " | |
14882 "that follow the <quote>Unix philosophy;</quote> each does one useful thing " | |
14883 "with a patch. The <literal role=\"package\">patchutils</literal> command I " | |
14884 "use most is <command>filterdiff</command>, which extracts subsets from a " | |
14885 "patch file. For example, given a patch that modifies hundreds of files " | |
14886 "across dozens of directories, a single invocation of <command>filterdiff</" | |
14887 "command> can generate a smaller patch that only touches files whose names " | |
14888 "match a particular glob pattern. See section <xref linkend=\"mq-collab.tips." | |
14889 "interdiff\"/> for another example." | |
14890 msgstr "" | |
14891 | |
14892 #. type: Content of: <book><chapter><sect1><title> | |
14893 #: ../en/ch12-mq.xml:1148 | |
14894 msgid "Good ways to work with patches" | |
14895 msgstr "" | |
14896 | |
14897 #. type: Content of: <book><chapter><sect1><para> | |
14898 #: ../en/ch12-mq.xml:1150 | |
14899 msgid "" | |
14900 "Whether you are working on a patch series to submit to a free software or " | |
14901 "open source project, or a series that you intend to treat as a sequence of " | |
14902 "regular changesets when you're done, you can use some simple techniques to " | |
14903 "keep your work well organised." | |
14904 msgstr "" | |
14905 | |
14906 #. type: Content of: <book><chapter><sect1><para> | |
14907 #: ../en/ch12-mq.xml:1156 | |
14908 msgid "" | |
14909 "Give your patches descriptive names. A good name for a patch might be " | |
14910 "<filename>rework-device-alloc.patch</filename>, because it will immediately " | |
14911 "give you a hint what the purpose of the patch is. Long names shouldn't be a " | |
14912 "problem; you won't be typing the names often, but you <emphasis>will</" | |
14913 "emphasis> be running commands like <command role=\"hg-ext-mq\">qapplied</" | |
14914 "command> and <command role=\"hg-ext-mq\">qtop</command> over and over. Good " | |
14915 "naming becomes especially important when you have a number of patches to work " | |
14916 "with, or if you are juggling a number of different tasks and your patches " | |
14917 "only get a fraction of your attention." | |
14918 msgstr "" | |
14919 | |
14920 #. type: Content of: <book><chapter><sect1><para> | |
14921 #: ../en/ch12-mq.xml:1168 | |
14922 msgid "" | |
14923 "Be aware of what patch you're working on. Use the <command role=\"hg-ext-mq" | |
14924 "\">qtop</command> command and skim over the text of your patches " | |
14925 "frequently&emdash;for example, using <command role=\"hg-cmd\">hg tip <option " | |
14926 "role=\"hg-opt-tip\">-p</option></command>)&emdash;to be sure of where you " | |
14927 "stand. I have several times worked on and <command role=\"hg-ext-mq" | |
14928 "\">qrefresh</command>ed a patch other than the one I intended, and it's often " | |
14929 "tricky to migrate changes into the right patch after making them in the wrong " | |
14930 "one." | |
14931 msgstr "" | |
14932 | |
14933 #. type: Content of: <book><chapter><sect1><para> | |
14934 #: ../en/ch12-mq.xml:1178 | |
14935 msgid "" | |
14936 "For this reason, it is very much worth investing a little time to learn how " | |
14937 "to use some of the third-party tools I described in section <xref linkend=" | |
14938 "\"sec.mq.tools\"/>, particularly <command>diffstat</command> and " | |
14939 "<command>filterdiff</command>. The former will give you a quick idea of what " | |
14940 "changes your patch is making, while the latter makes it easy to splice hunks " | |
14941 "selectively out of one patch and into another." | |
14942 msgstr "" | |
14943 | |
14944 #. type: Content of: <book><chapter><sect1><title> | |
14945 #: ../en/ch12-mq.xml:1189 | |
14946 msgid "MQ cookbook" | |
14947 msgstr "" | |
14948 | |
14949 #. type: Content of: <book><chapter><sect1><sect2><title> | |
14950 #: ../en/ch12-mq.xml:1192 | |
14951 msgid "Manage <quote>trivial</quote> patches" | |
14952 msgstr "" | |
14953 | |
14954 #. type: Content of: <book><chapter><sect1><sect2><para> | |
14955 #: ../en/ch12-mq.xml:1194 | |
14956 msgid "" | |
14957 "Because the overhead of dropping files into a new Mercurial repository is so " | |
14958 "low, it makes a lot of sense to manage patches this way even if you simply " | |
14959 "want to make a few changes to a source tarball that you downloaded." | |
14960 msgstr "" | |
14961 | |
14962 # | |
14963 #. type: Content of: <book><chapter><sect1><sect2><para> | |
14964 #: ../en/ch12-mq.xml:1199 | |
14965 msgid "" | |
14966 "Begin by downloading and unpacking the source tarball, and turning it into a " | |
14967 "Mercurial repository." | |
14968 msgstr "" | |
14969 | |
14970 #. type: Content of: <book><chapter><sect1><sect2><para> | |
14971 #: ../en/ch12-mq.xml:1204 | |
14972 msgid "Continue by creating a patch stack and making your changes." | |
14973 msgstr "" | |
14974 | |
14975 #. type: Content of: <book><chapter><sect1><sect2><para> | |
14976 #: ../en/ch12-mq.xml:1209 | |
14977 msgid "" | |
14978 "Let's say a few weeks or months pass, and your package author releases a new " | |
14979 "version. First, bring their changes into the repository." | |
14980 msgstr "" | |
14981 | |
14982 #. type: Content of: <book><chapter><sect1><sect2><para> | |
14983 #: ../en/ch12-mq.xml:1215 | |
14984 msgid "" | |
14985 "The pipeline starting with <command role=\"hg-cmd\">hg locate</command> above " | |
14986 "deletes all files in the working directory, so that <command role=\"hg-cmd" | |
14987 "\">hg commit</command>'s <option role=\"hg-opt-commit\">--addremove</option> " | |
14988 "option can actually tell which files have really been removed in the newer " | |
14989 "version of the source." | |
14990 msgstr "" | |
14991 | |
14992 #. type: Content of: <book><chapter><sect1><sect2><para> | |
14993 #: ../en/ch12-mq.xml:1223 | |
14994 msgid "Finally, you can apply your patches on top of the new tree." | |
14995 msgstr "" | |
14996 | |
14997 #. type: Content of: <book><chapter><sect1><sect2><title> | |
14998 #: ../en/ch12-mq.xml:1230 | |
14999 msgid "Combining entire patches" | |
15000 msgstr "" | |
15001 | |
15002 #. type: Content of: <book><chapter><sect1><sect2><para> | |
15003 #: ../en/ch12-mq.xml:1232 | |
15004 msgid "" | |
15005 "MQ provides a command, <command role=\"hg-ext-mq\">qfold</command> that lets " | |
15006 "you combine entire patches. This <quote>folds</quote> the patches you name, " | |
15007 "in the order you name them, into the topmost applied patch, and concatenates " | |
15008 "their descriptions onto the end of its description. The patches that you " | |
15009 "fold must be unapplied before you fold them." | |
15010 msgstr "" | |
15011 | |
15012 #. type: Content of: <book><chapter><sect1><sect2><para> | |
15013 #: ../en/ch12-mq.xml:1240 | |
15014 msgid "" | |
15015 "The order in which you fold patches matters. If your topmost applied patch " | |
15016 "is <literal>foo</literal>, and you <command role=\"hg-ext-mq\">qfold</" | |
15017 "command> <literal>bar</literal> and <literal>quux</literal> into it, you will " | |
15018 "end up with a patch that has the same effect as if you applied first " | |
15019 "<literal>foo</literal>, then <literal>bar</literal>, followed by " | |
15020 "<literal>quux</literal>." | |
15021 msgstr "" | |
15022 | |
15023 #. type: Content of: <book><chapter><sect1><sect2><title> | |
15024 #: ../en/ch12-mq.xml:1251 | |
15025 msgid "Merging part of one patch into another" | |
15026 msgstr "" | |
15027 | |
15028 #. type: Content of: <book><chapter><sect1><sect2><para> | |
15029 #: ../en/ch12-mq.xml:1253 | |
15030 msgid "" | |
15031 "Merging <emphasis>part</emphasis> of one patch into another is more difficult " | |
15032 "than combining entire patches." | |
15033 msgstr "" | |
15034 | |
15035 #. type: Content of: <book><chapter><sect1><sect2><para> | |
15036 #: ../en/ch12-mq.xml:1257 | |
15037 msgid "" | |
15038 "If you want to move changes to entire files, you can use <command>filterdiff</" | |
15039 "command>'s <option role=\"cmd-opt-filterdiff\">-i</option> and <option role=" | |
15040 "\"cmd-opt-filterdiff\">-x</option> options to choose the modifications to " | |
15041 "snip out of one patch, concatenating its output onto the end of the patch you " | |
15042 "want to merge into. You usually won't need to modify the patch you've merged " | |
15043 "the changes from. Instead, MQ will report some rejected hunks when you " | |
15044 "<command role=\"hg-ext-mq\">qpush</command> it (from the hunks you moved into " | |
15045 "the other patch), and you can simply <command role=\"hg-ext-mq\">qrefresh</" | |
15046 "command> the patch to drop the duplicate hunks." | |
15047 msgstr "" | |
15048 | |
15049 #. type: Content of: <book><chapter><sect1><sect2><para> | |
15050 #: ../en/ch12-mq.xml:1270 | |
15051 msgid "" | |
15052 "If you have a patch that has multiple hunks modifying a file, and you only " | |
15053 "want to move a few of those hunks, the job becomes more messy, but you can " | |
15054 "still partly automate it. Use <command>lsdiff -nvv</command> to print some " | |
15055 "metadata about the patch." | |
15056 msgstr "" | |
15057 | |
15058 #. type: Content of: <book><chapter><sect1><sect2><para> | |
15059 #: ../en/ch12-mq.xml:1278 | |
15060 msgid "This command prints three different kinds of number:" | |
15061 msgstr "" | |
15062 | |
15063 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
15064 #: ../en/ch12-mq.xml:1281 | |
15065 msgid "" | |
15066 "(in the first column) a <emphasis>file number</emphasis> to identify each " | |
15067 "file modified in the patch;" | |
15068 msgstr "" | |
15069 | |
15070 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
15071 #: ../en/ch12-mq.xml:1285 | |
15072 msgid "" | |
15073 "(on the next line, indented) the line number within a modified file where a " | |
15074 "hunk starts; and" | |
15075 msgstr "" | |
15076 | |
15077 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
15078 #: ../en/ch12-mq.xml:1288 | |
15079 msgid "" | |
15080 "(on the same line) a <emphasis>hunk number</emphasis> to identify that hunk." | |
15081 msgstr "" | |
15082 | |
15083 #. type: Content of: <book><chapter><sect1><sect2><para> | |
15084 #: ../en/ch12-mq.xml:1292 | |
15085 msgid "" | |
15086 "You'll have to use some visual inspection, and reading of the patch, to " | |
15087 "identify the file and hunk numbers you'll want, but you can then pass them to " | |
15088 "to <command>filterdiff</command>'s <option role=\"cmd-opt-filterdiff\">--" | |
15089 "files</option> and <option role=\"cmd-opt-filterdiff\">--hunks</option> " | |
15090 "options, to select exactly the file and hunk you want to extract." | |
15091 msgstr "" | |
15092 | |
15093 #. type: Content of: <book><chapter><sect1><sect2><para> | |
15094 #: ../en/ch12-mq.xml:1300 | |
15095 msgid "" | |
15096 "Once you have this hunk, you can concatenate it onto the end of your " | |
15097 "destination patch and continue with the remainder of section <xref linkend=" | |
15098 "\"sec.mq.combine\"/>." | |
15099 msgstr "" | |
15100 | |
15101 #. type: Content of: <book><chapter><sect1><title> | |
15102 #: ../en/ch12-mq.xml:1307 | |
15103 msgid "Differences between quilt and MQ" | |
15104 msgstr "" | |
15105 | |
15106 #. type: Content of: <book><chapter><sect1><para> | |
15107 #: ../en/ch12-mq.xml:1309 | |
15108 msgid "" | |
15109 "If you are already familiar with quilt, MQ provides a similar command set. " | |
15110 "There are a few differences in the way that it works." | |
15111 msgstr "" | |
15112 | |
15113 #. type: Content of: <book><chapter><sect1><para> | |
15114 #: ../en/ch12-mq.xml:1313 | |
15115 msgid "" | |
15116 "You will already have noticed that most quilt commands have MQ counterparts " | |
15117 "that simply begin with a <quote><literal>q</literal></quote>. The exceptions " | |
15118 "are quilt's <literal>add</literal> and <literal>remove</literal> commands, " | |
15119 "the counterparts for which are the normal Mercurial <command role=\"hg-cmd" | |
15120 "\">hg add</command> and <command role=\"hg-cmd\">hg remove</command> " | |
15121 "commands. There is no MQ equivalent of the quilt <literal>edit</literal> " | |
15122 "command." | |
15123 msgstr "" | |
15124 | |
15125 #. type: Content of: <book><chapter><title> | |
15126 #: ../en/ch13-mq-collab.xml:5 | |
15127 msgid "Advanced uses of Mercurial Queues" | |
15128 msgstr "MQ 的高级用法" | |
15129 | |
15130 #. type: Content of: <book><chapter><para> | |
15131 #: ../en/ch13-mq-collab.xml:7 | |
15132 msgid "" | |
15133 "While it's easy to pick up straightforward uses of Mercurial Queues, use of a " | |
15134 "little discipline and some of MQ's less frequently used capabilities makes it " | |
15135 "possible to work in complicated development environments." | |
15136 msgstr "" | |
15137 | |
15138 #. type: Content of: <book><chapter><para> | |
15139 #: ../en/ch13-mq-collab.xml:12 | |
15140 msgid "" | |
15141 "In this chapter, I will use as an example a technique I have used to manage " | |
15142 "the development of an Infiniband device driver for the Linux kernel. The " | |
15143 "driver in question is large (at least as drivers go), with 25,000 lines of " | |
15144 "code spread across 35 source files. It is maintained by a small team of " | |
15145 "developers." | |
15146 msgstr "" | |
15147 | |
15148 #. type: Content of: <book><chapter><para> | |
15149 #: ../en/ch13-mq-collab.xml:18 | |
15150 msgid "" | |
15151 "While much of the material in this chapter is specific to Linux, the same " | |
15152 "principles apply to any code base for which you're not the primary owner, and " | |
15153 "upon which you need to do a lot of development." | |
15154 msgstr "" | |
15155 | |
15156 #. type: Content of: <book><chapter><sect1><title> | |
15157 #: ../en/ch13-mq-collab.xml:24 | |
15158 msgid "The problem of many targets" | |
15159 msgstr "" | |
15160 | |
15161 #. type: Content of: <book><chapter><sect1><para> | |
15162 #: ../en/ch13-mq-collab.xml:26 | |
15163 msgid "" | |
15164 "The Linux kernel changes rapidly, and has never been internally stable; " | |
15165 "developers frequently make drastic changes between releases. This means that " | |
15166 "a version of the driver that works well with a particular released version of " | |
15167 "the kernel will not even <emphasis>compile</emphasis> correctly against, " | |
15168 "typically, any other version." | |
15169 msgstr "" | |
15170 | |
15171 #. type: Content of: <book><chapter><sect1><para> | |
15172 #: ../en/ch13-mq-collab.xml:33 | |
15173 msgid "" | |
15174 "To maintain a driver, we have to keep a number of distinct versions of Linux " | |
15175 "in mind." | |
15176 msgstr "" | |
15177 | |
15178 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
15179 #: ../en/ch13-mq-collab.xml:36 | |
15180 msgid "" | |
15181 "One target is the main Linux kernel development tree. Maintenance of the code " | |
15182 "is in this case partly shared by other developers in the kernel community, " | |
15183 "who make <quote>drive-by</quote> modifications to the driver as they develop " | |
15184 "and refine kernel subsystems." | |
15185 msgstr "" | |
15186 | |
15187 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
15188 #: ../en/ch13-mq-collab.xml:42 | |
15189 msgid "" | |
15190 "We also maintain a number of <quote>backports</quote> to older versions of " | |
15191 "the Linux kernel, to support the needs of customers who are running older " | |
15192 "Linux distributions that do not incorporate our drivers. (To " | |
15193 "<emphasis>backport</emphasis> a piece of code is to modify it to work in an " | |
15194 "older version of its target environment than the version it was developed " | |
15195 "for.)" | |
15196 msgstr "" | |
15197 | |
15198 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
15199 #: ../en/ch13-mq-collab.xml:50 | |
15200 msgid "" | |
15201 "Finally, we make software releases on a schedule that is necessarily not " | |
15202 "aligned with those used by Linux distributors and kernel developers, so that " | |
15203 "we can deliver new features to customers without forcing them to upgrade " | |
15204 "their entire kernels or distributions." | |
15205 msgstr "" | |
15206 | |
15207 #. type: Content of: <book><chapter><sect1><sect2><title> | |
15208 #: ../en/ch13-mq-collab.xml:58 | |
15209 msgid "Tempting approaches that don't work well" | |
15210 msgstr "" | |
15211 | |
15212 #. type: Content of: <book><chapter><sect1><sect2><para> | |
15213 #: ../en/ch13-mq-collab.xml:60 | |
15214 msgid "" | |
15215 "There are two <quote>standard</quote> ways to maintain a piece of software " | |
15216 "that has to target many different environments." | |
15217 msgstr "" | |
15218 | |
15219 #. type: Content of: <book><chapter><sect1><sect2><para> | |
15220 #: ../en/ch13-mq-collab.xml:64 | |
15221 msgid "" | |
15222 "The first is to maintain a number of branches, each intended for a single " | |
15223 "target. The trouble with this approach is that you must maintain iron " | |
15224 "discipline in the flow of changes between repositories. A new feature or bug " | |
15225 "fix must start life in a <quote>pristine</quote> repository, then percolate " | |
15226 "out to every backport repository. Backport changes are more limited in the " | |
15227 "branches they should propagate to; a backport change that is applied to a " | |
15228 "branch where it doesn't belong will probably stop the driver from compiling." | |
15229 msgstr "" | |
15230 | |
15231 #. type: Content of: <book><chapter><sect1><sect2><para> | |
15232 #: ../en/ch13-mq-collab.xml:74 | |
15233 msgid "" | |
15234 "The second is to maintain a single source tree filled with conditional " | |
15235 "statements that turn chunks of code on or off depending on the intended " | |
15236 "target. Because these <quote>ifdefs</quote> are not allowed in the Linux " | |
15237 "kernel tree, a manual or automatic process must be followed to strip them out " | |
15238 "and yield a clean tree. A code base maintained in this fashion rapidly " | |
15239 "becomes a rat's nest of conditional blocks that are difficult to understand " | |
15240 "and maintain." | |
15241 msgstr "" | |
15242 | |
15243 #. type: Content of: <book><chapter><sect1><sect2><para> | |
15244 #: ../en/ch13-mq-collab.xml:83 | |
15245 msgid "" | |
15246 "Neither of these approaches is well suited to a situation where you don't " | |
15247 "<quote>own</quote> the canonical copy of a source tree. In the case of a " | |
15248 "Linux driver that is distributed with the standard kernel, Linus's tree " | |
15249 "contains the copy of the code that will be treated by the world as " | |
15250 "canonical. The upstream version of <quote>my</quote> driver can be modified " | |
15251 "by people I don't know, without me even finding out about it until after the " | |
15252 "changes show up in Linus's tree." | |
15253 msgstr "" | |
15254 | |
15255 #. type: Content of: <book><chapter><sect1><sect2><para> | |
15256 #: ../en/ch13-mq-collab.xml:93 | |
15257 msgid "" | |
15258 "These approaches have the added weakness of making it difficult to generate " | |
15259 "well-formed patches to submit upstream." | |
15260 msgstr "" | |
15261 | |
15262 #. type: Content of: <book><chapter><sect1><sect2><para> | |
15263 #: ../en/ch13-mq-collab.xml:97 | |
15264 msgid "" | |
15265 "In principle, Mercurial Queues seems like a good candidate to manage a " | |
15266 "development scenario such as the above. While this is indeed the case, MQ " | |
15267 "contains a few added features that make the job more pleasant." | |
15268 msgstr "" | |
15269 | |
15270 #. type: Content of: <book><chapter><sect1><title> | |
15271 #: ../en/ch13-mq-collab.xml:105 | |
15272 msgid "Conditionally applying patches with guards" | |
15273 msgstr "" | |
15274 | |
15275 #. type: Content of: <book><chapter><sect1><para> | |
15276 #: ../en/ch13-mq-collab.xml:107 | |
15277 msgid "" | |
15278 "Perhaps the best way to maintain sanity with so many targets is to be able to " | |
15279 "choose specific patches to apply for a given situation. MQ provides a " | |
15280 "feature called <quote>guards</quote> (which originates with quilt's " | |
15281 "<literal>guards</literal> command) that does just this. To start off, let's " | |
15282 "create a simple repository for experimenting in." | |
15283 msgstr "" | |
15284 | |
15285 #. type: Content of: <book><chapter><sect1><para> | |
15286 #: ../en/ch13-mq-collab.xml:116 | |
15287 msgid "" | |
15288 "This gives us a tiny repository that contains two patches that don't have any " | |
15289 "dependencies on each other, because they touch different files." | |
15290 msgstr "" | |
15291 | |
15292 #. type: Content of: <book><chapter><sect1><para> | |
15293 #: ../en/ch13-mq-collab.xml:120 | |
15294 msgid "" | |
15295 "The idea behind conditional application is that you can <quote>tag</quote> a " | |
15296 "patch with a <emphasis>guard</emphasis>, which is simply a text string of " | |
15297 "your choosing, then tell MQ to select specific guards to use when applying " | |
15298 "patches. MQ will then either apply, or skip over, a guarded patch, depending " | |
15299 "on the guards that you have selected." | |
15300 msgstr "" | |
15301 | |
15302 #. type: Content of: <book><chapter><sect1><para> | |
15303 #: ../en/ch13-mq-collab.xml:127 | |
15304 msgid "" | |
15305 "A patch can have an arbitrary number of guards; each one is " | |
15306 "<emphasis>positive</emphasis> (<quote>apply this patch if this guard is " | |
15307 "selected</quote>) or <emphasis>negative</emphasis> (<quote>skip this patch if " | |
15308 "this guard is selected</quote>). A patch with no guards is always applied." | |
15309 msgstr "" | |
15310 | |
15311 #. type: Content of: <book><chapter><sect1><title> | |
15312 #: ../en/ch13-mq-collab.xml:135 | |
15313 msgid "Controlling the guards on a patch" | |
15314 msgstr "" | |
15315 | |
15316 #. type: Content of: <book><chapter><sect1><para> | |
15317 #: ../en/ch13-mq-collab.xml:137 | |
15318 msgid "" | |
15319 "The <command role=\"hg-ext-mq\">qguard</command> command lets you determine " | |
15320 "which guards should apply to a patch, or display the guards that are already " | |
15321 "in effect. Without any arguments, it displays the guards on the current " | |
15322 "topmost patch." | |
15323 msgstr "" | |
15324 | |
15325 #. type: Content of: <book><chapter><sect1><para> | |
15326 #: ../en/ch13-mq-collab.xml:144 | |
15327 msgid "" | |
15328 "To set a positive guard on a patch, prefix the name of the guard with a " | |
15329 "<quote><literal>+</literal></quote>." | |
15330 msgstr "" | |
15331 | |
15332 #. type: Content of: <book><chapter><sect1><para> | |
15333 #: ../en/ch13-mq-collab.xml:149 | |
15334 msgid "" | |
15335 "To set a negative guard on a patch, prefix the name of the guard with a " | |
15336 "<quote><literal>-</literal></quote>." | |
15337 msgstr "" | |
15338 | |
15339 #. type: Content of: <book><chapter><sect1><note><para> | |
15340 #: ../en/ch13-mq-collab.xml:156 | |
15341 msgid "" | |
15342 "The <command role=\"hg-ext-mq\">qguard</command> command <emphasis>sets</" | |
15343 "emphasis> the guards on a patch; it doesn't <emphasis>modify</emphasis> " | |
15344 "them. What this means is that if you run <command role=\"hg-cmd\">hg qguard " | |
15345 "+a +b</command> on a patch, then <command role=\"hg-cmd\">hg qguard +c</" | |
15346 "command> on the same patch, the <emphasis>only</emphasis> guard that will be " | |
15347 "set on it afterwards is <literal>+c</literal>." | |
15348 msgstr "" | |
15349 | |
15350 # | |
15351 #. type: Content of: <book><chapter><sect1><para> | |
15352 #: ../en/ch13-mq-collab.xml:165 | |
15353 msgid "" | |
15354 "Mercurial stores guards in the <filename role=\"special\">series</filename> " | |
15355 "file; the form in which they are stored is easy both to understand and to " | |
15356 "edit by hand. (In other words, you don't have to use the <command role=\"hg-" | |
15357 "ext-mq\">qguard</command> command if you don't want to; it's okay to simply " | |
15358 "edit the <filename role=\"special\">series</filename> file.)" | |
15359 msgstr "" | |
15360 | |
15361 #. type: Content of: <book><chapter><sect1><title> | |
15362 #: ../en/ch13-mq-collab.xml:177 | |
15363 msgid "Selecting the guards to use" | |
15364 msgstr "" | |
15365 | |
15366 #. type: Content of: <book><chapter><sect1><para> | |
15367 #: ../en/ch13-mq-collab.xml:179 | |
15368 msgid "" | |
15369 "The <command role=\"hg-ext-mq\">qselect</command> command determines which " | |
15370 "guards are active at a given time. The effect of this is to determine which " | |
15371 "patches MQ will apply the next time you run <command role=\"hg-ext-mq" | |
15372 "\">qpush</command>. It has no other effect; in particular, it doesn't do " | |
15373 "anything to patches that are already applied." | |
15374 msgstr "" | |
15375 | |
15376 #. type: Content of: <book><chapter><sect1><para> | |
15377 #: ../en/ch13-mq-collab.xml:186 | |
15378 msgid "" | |
15379 "With no arguments, the <command role=\"hg-ext-mq\">qselect</command> command " | |
15380 "lists the guards currently in effect, one per line of output. Each argument " | |
15381 "is treated as the name of a guard to apply." | |
15382 msgstr "" | |
15383 | |
15384 #. type: Content of: <book><chapter><sect1><para> | |
15385 #: ../en/ch13-mq-collab.xml:193 | |
15386 msgid "" | |
15387 "In case you're interested, the currently selected guards are stored in the " | |
15388 "<filename role=\"special\">guards</filename> file." | |
15389 msgstr "" | |
15390 | |
15391 #. type: Content of: <book><chapter><sect1><para> | |
15392 #: ../en/ch13-mq-collab.xml:198 | |
15393 msgid "" | |
15394 "We can see the effect the selected guards have when we run <command role=\"hg-" | |
15395 "ext-mq\">qpush</command>." | |
15396 msgstr "" | |
15397 | |
15398 #. type: Content of: <book><chapter><sect1><para> | |
15399 #: ../en/ch13-mq-collab.xml:203 | |
15400 msgid "" | |
15401 "A guard cannot start with a <quote><literal>+</literal></quote> or " | |
15402 "<quote><literal>-</literal></quote> character. The name of a guard must not " | |
15403 "contain white space, but most other characters are acceptable. If you try to " | |
15404 "use a guard with an invalid name, MQ will complain:" | |
15405 msgstr "" | |
15406 | |
15407 #. type: Content of: <book><chapter><sect1><para> | |
15408 #: ../en/ch13-mq-collab.xml:212 | |
15409 msgid "Changing the selected guards changes the patches that are applied." | |
15410 msgstr "" | |
15411 | |
15412 #. type: Content of: <book><chapter><sect1><para> | |
15413 #: ../en/ch13-mq-collab.xml:217 | |
15414 msgid "" | |
15415 "You can see in the example below that negative guards take precedence over " | |
15416 "positive guards." | |
15417 msgstr "" | |
15418 | |
15419 #. type: Content of: <book><chapter><sect1><title> | |
15420 #: ../en/ch13-mq-collab.xml:224 | |
15421 msgid "MQ's rules for applying patches" | |
15422 msgstr "" | |
15423 | |
15424 #. type: Content of: <book><chapter><sect1><para> | |
15425 #: ../en/ch13-mq-collab.xml:226 | |
15426 msgid "" | |
15427 "The rules that MQ uses when deciding whether to apply a patch are as follows." | |
15428 msgstr "" | |
15429 | |
15430 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
15431 #: ../en/ch13-mq-collab.xml:229 | |
15432 msgid "A patch that has no guards is always applied." | |
15433 msgstr "" | |
15434 | |
15435 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
15436 #: ../en/ch13-mq-collab.xml:232 | |
15437 msgid "" | |
15438 "If the patch has any negative guard that matches any currently selected " | |
15439 "guard, the patch is skipped." | |
15440 msgstr "" | |
15441 | |
15442 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
15443 #: ../en/ch13-mq-collab.xml:235 | |
15444 msgid "" | |
15445 "If the patch has any positive guard that matches any currently selected " | |
15446 "guard, the patch is applied." | |
15447 msgstr "" | |
15448 | |
15449 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
15450 #: ../en/ch13-mq-collab.xml:238 | |
15451 msgid "" | |
15452 "If the patch has positive or negative guards, but none matches any currently " | |
15453 "selected guard, the patch is skipped." | |
15454 msgstr "" | |
15455 | |
15456 #. type: Content of: <book><chapter><sect1><title> | |
15457 #: ../en/ch13-mq-collab.xml:245 | |
15458 msgid "Trimming the work environment" | |
15459 msgstr "" | |
15460 | |
15461 #. type: Content of: <book><chapter><sect1><para> | |
15462 #: ../en/ch13-mq-collab.xml:247 | |
15463 msgid "" | |
15464 "In working on the device driver I mentioned earlier, I don't apply the " | |
15465 "patches to a normal Linux kernel tree. Instead, I use a repository that " | |
15466 "contains only a snapshot of the source files and headers that are relevant to " | |
15467 "Infiniband development. This repository is 1% the size of a kernel " | |
15468 "repository, so it's easier to work with." | |
15469 msgstr "" | |
15470 | |
15471 #. type: Content of: <book><chapter><sect1><para> | |
15472 #: ../en/ch13-mq-collab.xml:254 | |
15473 msgid "" | |
15474 "I then choose a <quote>base</quote> version on top of which the patches are " | |
15475 "applied. This is a snapshot of the Linux kernel tree as of a revision of my " | |
15476 "choosing. When I take the snapshot, I record the changeset ID from the " | |
15477 "kernel repository in the commit message. Since the snapshot preserves the " | |
15478 "<quote>shape</quote> and content of the relevant parts of the kernel tree, I " | |
15479 "can apply my patches on top of either my tiny repository or a normal kernel " | |
15480 "tree." | |
15481 msgstr "" | |
15482 | |
15483 #. type: Content of: <book><chapter><sect1><para> | |
15484 #: ../en/ch13-mq-collab.xml:263 | |
15485 msgid "" | |
15486 "Normally, the base tree atop which the patches apply should be a snapshot of " | |
15487 "a very recent upstream tree. This best facilitates the development of " | |
15488 "patches that can easily be submitted upstream with few or no modifications." | |
15489 msgstr "" | |
15490 | |
15491 #. type: Content of: <book><chapter><sect1><title> | |
15492 #: ../en/ch13-mq-collab.xml:270 | |
15493 msgid "Dividing up the <filename role=\"special\">series</filename> file" | |
15494 msgstr "" | |
15495 | |
15496 #. type: Content of: <book><chapter><sect1><para> | |
15497 #: ../en/ch13-mq-collab.xml:273 | |
15498 msgid "" | |
15499 "I categorise the patches in the <filename role=\"special\">series</filename> " | |
15500 "file into a number of logical groups. Each section of like patches begins " | |
15501 "with a block of comments that describes the purpose of the patches that " | |
15502 "follow." | |
15503 msgstr "" | |
15504 | |
15505 #. type: Content of: <book><chapter><sect1><para> | |
15506 #: ../en/ch13-mq-collab.xml:279 | |
15507 msgid "" | |
15508 "The sequence of patch groups that I maintain follows. The ordering of these " | |
15509 "groups is important; I'll describe why after I introduce the groups." | |
15510 msgstr "" | |
15511 | |
15512 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
15513 #: ../en/ch13-mq-collab.xml:283 | |
15514 msgid "" | |
15515 "The <quote>accepted</quote> group. Patches that the development team has " | |
15516 "submitted to the maintainer of the Infiniband subsystem, and which he has " | |
15517 "accepted, but which are not present in the snapshot that the tiny repository " | |
15518 "is based on. These are <quote>read only</quote> patches, present only to " | |
15519 "transform the tree into a similar state as it is in the upstream maintainer's " | |
15520 "repository." | |
15521 msgstr "" | |
15522 | |
15523 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
15524 #: ../en/ch13-mq-collab.xml:291 | |
15525 msgid "" | |
15526 "The <quote>rework</quote> group. Patches that I have submitted, but that the " | |
15527 "upstream maintainer has requested modifications to before he will accept them." | |
15528 msgstr "" | |
15529 | |
15530 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
15531 #: ../en/ch13-mq-collab.xml:296 | |
15532 msgid "" | |
15533 "The <quote>pending</quote> group. Patches that I have not yet submitted to " | |
15534 "the upstream maintainer, but which we have finished working on. These will be " | |
15535 "<quote>read only</quote> for a while. If the upstream maintainer accepts " | |
15536 "them upon submission, I'll move them to the end of the <quote>accepted</" | |
15537 "quote> group. If he requests that I modify any, I'll move them to the " | |
15538 "beginning of the <quote>rework</quote> group." | |
15539 msgstr "" | |
15540 | |
15541 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
15542 #: ../en/ch13-mq-collab.xml:305 | |
15543 msgid "" | |
15544 "The <quote>in progress</quote> group. Patches that are actively being " | |
15545 "developed, and should not be submitted anywhere yet." | |
15546 msgstr "" | |
15547 | |
15548 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
15549 #: ../en/ch13-mq-collab.xml:309 | |
15550 msgid "" | |
15551 "The <quote>backport</quote> group. Patches that adapt the source tree to " | |
15552 "older versions of the kernel tree." | |
15553 msgstr "" | |
15554 | |
15555 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
15556 #: ../en/ch13-mq-collab.xml:313 | |
15557 msgid "" | |
15558 "The <quote>do not ship</quote> group. Patches that for some reason should " | |
15559 "never be submitted upstream. For example, one such patch might change " | |
15560 "embedded driver identification strings to make it easier to distinguish, in " | |
15561 "the field, between an out-of-tree version of the driver and a version shipped " | |
15562 "by a distribution vendor." | |
15563 msgstr "" | |
15564 | |
15565 #. type: Content of: <book><chapter><sect1><para> | |
15566 #: ../en/ch13-mq-collab.xml:321 | |
15567 msgid "" | |
15568 "Now to return to the reasons for ordering groups of patches in this way. We " | |
15569 "would like the lowest patches in the stack to be as stable as possible, so " | |
15570 "that we will not need to rework higher patches due to changes in context. " | |
15571 "Putting patches that will never be changed first in the <filename role=" | |
15572 "\"special\">series</filename> file serves this purpose." | |
15573 msgstr "" | |
15574 | |
15575 #. type: Content of: <book><chapter><sect1><para> | |
15576 #: ../en/ch13-mq-collab.xml:329 | |
15577 msgid "" | |
15578 "We would also like the patches that we know we'll need to modify to be " | |
15579 "applied on top of a source tree that resembles the upstream tree as closely " | |
15580 "as possible. This is why we keep accepted patches around for a while." | |
15581 msgstr "" | |
15582 | |
15583 #. type: Content of: <book><chapter><sect1><para> | |
15584 #: ../en/ch13-mq-collab.xml:334 | |
15585 msgid "" | |
15586 "The <quote>backport</quote> and <quote>do not ship</quote> patches float at " | |
15587 "the end of the <filename role=\"special\">series</filename> file. The " | |
15588 "backport patches must be applied on top of all other patches, and the " | |
15589 "<quote>do not ship</quote> patches might as well stay out of harm's way." | |
15590 msgstr "" | |
15591 | |
15592 #. type: Content of: <book><chapter><sect1><title> | |
15593 #: ../en/ch13-mq-collab.xml:343 | |
15594 msgid "Maintaining the patch series" | |
15595 msgstr "" | |
15596 | |
15597 #. type: Content of: <book><chapter><sect1><para> | |
15598 #: ../en/ch13-mq-collab.xml:345 | |
15599 msgid "" | |
15600 "In my work, I use a number of guards to control which patches are to be " | |
15601 "applied." | |
15602 msgstr "" | |
15603 | |
15604 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
15605 #: ../en/ch13-mq-collab.xml:349 | |
15606 msgid "" | |
15607 "<quote>Accepted</quote> patches are guarded with <literal>accepted</" | |
15608 "literal>. I enable this guard most of the time. When I'm applying the " | |
15609 "patches on top of a tree where the patches are already present, I can turn " | |
15610 "this patch off, and the patches that follow it will apply cleanly." | |
15611 msgstr "" | |
15612 | |
15613 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
15614 #: ../en/ch13-mq-collab.xml:356 | |
15615 msgid "" | |
15616 "Patches that are <quote>finished</quote>, but not yet submitted, have no " | |
15617 "guards. If I'm applying the patch stack to a copy of the upstream tree, I " | |
15618 "don't need to enable any guards in order to get a reasonably safe source tree." | |
15619 msgstr "" | |
15620 | |
15621 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
15622 #: ../en/ch13-mq-collab.xml:362 | |
15623 msgid "" | |
15624 "Those patches that need reworking before being resubmitted are guarded with " | |
15625 "<literal>rework</literal>." | |
15626 msgstr "" | |
15627 | |
15628 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
15629 #: ../en/ch13-mq-collab.xml:366 | |
15630 msgid "" | |
15631 "For those patches that are still under development, I use <literal>devel</" | |
15632 "literal>." | |
15633 msgstr "" | |
15634 | |
15635 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
15636 #: ../en/ch13-mq-collab.xml:369 | |
15637 msgid "" | |
15638 "A backport patch may have several guards, one for each version of the kernel " | |
15639 "to which it applies. For example, a patch that backports a piece of code to " | |
15640 "2.6.9 will have a <literal>2.6.9</literal> guard." | |
15641 msgstr "" | |
15642 | |
15643 #. type: Content of: <book><chapter><sect1><para> | |
15644 #: ../en/ch13-mq-collab.xml:374 | |
15645 msgid "" | |
15646 "This variety of guards gives me considerable flexibility in determining what " | |
15647 "kind of source tree I want to end up with. For most situations, the " | |
15648 "selection of appropriate guards is automated during the build process, but I " | |
15649 "can manually tune the guards to use for less common circumstances." | |
15650 msgstr "" | |
15651 | |
15652 #. type: Content of: <book><chapter><sect1><sect2><title> | |
15653 #: ../en/ch13-mq-collab.xml:381 | |
15654 msgid "The art of writing backport patches" | |
15655 msgstr "" | |
15656 | |
15657 #. type: Content of: <book><chapter><sect1><sect2><para> | |
15658 #: ../en/ch13-mq-collab.xml:383 | |
15659 msgid "" | |
15660 "Using MQ, writing a backport patch is a simple process. All such a patch has " | |
15661 "to do is modify a piece of code that uses a kernel feature not present in the " | |
15662 "older version of the kernel, so that the driver continues to work correctly " | |
15663 "under that older version." | |
15664 msgstr "" | |
15665 | |
15666 #. type: Content of: <book><chapter><sect1><sect2><para> | |
15667 #: ../en/ch13-mq-collab.xml:389 | |
15668 msgid "" | |
15669 "A useful goal when writing a good backport patch is to make your code look as " | |
15670 "if it was written for the older version of the kernel you're targeting. The " | |
15671 "less obtrusive the patch, the easier it will be to understand and maintain. " | |
15672 "If you're writing a collection of backport patches to avoid the <quote>rat's " | |
15673 "nest</quote> effect of lots of <literal>#ifdef</literal>s (hunks of source " | |
15674 "code that are only used conditionally) in your code, don't introduce version-" | |
15675 "dependent <literal>#ifdef</literal>s into the patches. Instead, write " | |
15676 "several patches, each of which makes unconditional changes, and control their " | |
15677 "application using guards." | |
15678 msgstr "" | |
15679 | |
15680 #. type: Content of: <book><chapter><sect1><sect2><para> | |
15681 #: ../en/ch13-mq-collab.xml:402 | |
15682 msgid "" | |
15683 "There are two reasons to divide backport patches into a distinct group, away " | |
15684 "from the <quote>regular</quote> patches whose effects they modify. The first " | |
15685 "is that intermingling the two makes it more difficult to use a tool like the " | |
15686 "<literal role=\"hg-ext\">patchbomb</literal> extension to automate the " | |
15687 "process of submitting the patches to an upstream maintainer. The second is " | |
15688 "that a backport patch could perturb the context in which a subsequent regular " | |
15689 "patch is applied, making it impossible to apply the regular patch cleanly " | |
15690 "<emphasis>without</emphasis> the earlier backport patch already being applied." | |
15691 msgstr "" | |
15692 | |
15693 #. type: Content of: <book><chapter><sect1><title> | |
15694 #: ../en/ch13-mq-collab.xml:417 | |
15695 msgid "Useful tips for developing with MQ" | |
15696 msgstr "" | |
15697 | |
15698 #. type: Content of: <book><chapter><sect1><sect2><title> | |
15699 #: ../en/ch13-mq-collab.xml:420 | |
15700 msgid "Organising patches in directories" | |
15701 msgstr "" | |
15702 | |
15703 #. type: Content of: <book><chapter><sect1><sect2><para> | |
15704 #: ../en/ch13-mq-collab.xml:422 | |
15705 msgid "" | |
15706 "If you're working on a substantial project with MQ, it's not difficult to " | |
15707 "accumulate a large number of patches. For example, I have one patch " | |
15708 "repository that contains over 250 patches." | |
15709 msgstr "" | |
15710 | |
15711 #. type: Content of: <book><chapter><sect1><sect2><para> | |
15712 #: ../en/ch13-mq-collab.xml:427 | |
15713 msgid "" | |
15714 "If you can group these patches into separate logical categories, you can if " | |
15715 "you like store them in different directories; MQ has no problems with patch " | |
15716 "names that contain path separators." | |
15717 msgstr "" | |
15718 | |
15719 #. type: Content of: <book><chapter><sect1><sect2><title> | |
15720 #: ../en/ch13-mq-collab.xml:434 | |
15721 msgid "Viewing the history of a patch" | |
15722 msgstr "" | |
15723 | |
15724 #. type: Content of: <book><chapter><sect1><sect2><para> | |
15725 #: ../en/ch13-mq-collab.xml:436 | |
15726 msgid "" | |
15727 "If you're developing a set of patches over a long time, it's a good idea to " | |
15728 "maintain them in a repository, as discussed in section <xref linkend=\"sec.mq." | |
15729 "repo\"/>. If you do so, you'll quickly discover that using the <command role=" | |
15730 "\"hg-cmd\">hg diff</command> command to look at the history of changes to a " | |
15731 "patch is unworkable. This is in part because you're looking at the second " | |
15732 "derivative of the real code (a diff of a diff), but also because MQ adds " | |
15733 "noise to the process by modifying time stamps and directory names when it " | |
15734 "updates a patch." | |
15735 msgstr "" | |
15736 | |
15737 #. type: Content of: <book><chapter><sect1><sect2><para> | |
15738 #: ../en/ch13-mq-collab.xml:448 | |
15739 msgid "" | |
15740 "However, you can use the <literal role=\"hg-ext\">extdiff</literal> " | |
15741 "extension, which is bundled with Mercurial, to turn a diff of two versions of " | |
15742 "a patch into something readable. To do this, you will need a third-party " | |
15743 "package called <literal role=\"package\">patchutils</literal> <citation>web:" | |
15744 "patchutils</citation>. This provides a command named <command>interdiff</" | |
15745 "command>, which shows the differences between two diffs as a diff. Used on " | |
15746 "two versions of the same diff, it generates a diff that represents the diff " | |
15747 "from the first to the second version." | |
15748 msgstr "" | |
15749 | |
15750 #. type: Content of: <book><chapter><sect1><sect2><para> | |
15751 #: ../en/ch13-mq-collab.xml:459 | |
15752 msgid "" | |
15753 "You can enable the <literal role=\"hg-ext\">extdiff</literal> extension in " | |
15754 "the usual way, by adding a line to the <literal role=\"rc-extensions" | |
15755 "\">extensions</literal> section of your <filename role=\"special\"> /.hgrc</" | |
15756 "filename>." | |
15757 msgstr "" | |
15758 | |
15759 # | |
15760 #. &example.hg-interdiff; | |
15761 #. type: Content of: <book><chapter><sect1><sect2><para> | |
15762 #: ../en/ch13-mq-collab.xml:465 | |
15763 msgid "" | |
15764 "The <command>interdiff</command> command expects to be passed the names of " | |
15765 "two files, but the <literal role=\"hg-ext\">extdiff</literal> extension " | |
15766 "passes the program it runs a pair of directories, each of which can contain " | |
15767 "an arbitrary number of files. We thus need a small program that will run " | |
15768 "<command>interdiff</command> on each pair of files in these two directories. " | |
15769 "This program is available as <filename role=\"special\">hg-interdiff</" | |
15770 "filename> in the <filename class=\"directory\">examples</filename> directory " | |
15771 "of the source code repository that accompanies this book." | |
15772 msgstr "" | |
15773 | |
15774 #. type: Content of: <book><chapter><sect1><sect2><para> | |
15775 #: ../en/ch13-mq-collab.xml:477 | |
15776 msgid "" | |
15777 "With the <filename role=\"special\">hg-interdiff</filename> program in your " | |
15778 "shell's search path, you can run it as follows, from inside an MQ patch " | |
15779 "directory:" | |
15780 msgstr "" | |
15781 | |
15782 #. type: Content of: <book><chapter><sect1><sect2><para> | |
15783 #: ../en/ch13-mq-collab.xml:482 | |
15784 msgid "" | |
15785 "Since you'll probably want to use this long-winded command a lot, you can get " | |
15786 "<literal role=\"hg-ext\">hgext</literal> to make it available as a normal " | |
15787 "Mercurial command, again by editing your <filename role=\"special\"> /.hgrc</" | |
15788 "filename>." | |
15789 msgstr "" | |
15790 | |
15791 #. type: Content of: <book><chapter><sect1><sect2><para> | |
15792 #: ../en/ch13-mq-collab.xml:489 | |
15793 msgid "" | |
15794 "This directs <literal role=\"hg-ext\">hgext</literal> to make an " | |
15795 "<literal>interdiff</literal> command available, so you can now shorten the " | |
15796 "previous invocation of <command role=\"hg-ext-extdiff\">extdiff</command> to " | |
15797 "something a little more wieldy." | |
15798 msgstr "" | |
15799 | |
15800 #. type: Content of: <book><chapter><sect1><sect2><note><para> | |
15801 #: ../en/ch13-mq-collab.xml:498 | |
15802 msgid "" | |
15803 "The <command>interdiff</command> command works well only if the underlying " | |
15804 "files against which versions of a patch are generated remain the same. If " | |
15805 "you create a patch, modify the underlying files, and then regenerate the " | |
15806 "patch, <command>interdiff</command> may not produce useful output." | |
15807 msgstr "" | |
15808 | |
15809 #. type: Content of: <book><chapter><sect1><sect2><para> | |
15810 #: ../en/ch13-mq-collab.xml:506 | |
15811 msgid "" | |
15812 "The <literal role=\"hg-ext\">extdiff</literal> extension is useful for more " | |
15813 "than merely improving the presentation of MQ patches. To read more about it, " | |
15814 "go to section <xref linkend=\"sec.hgext.extdiff\"/>." | |
15815 msgstr "" | |
15816 | |
15817 #. type: Content of: <book><chapter><title> | |
15818 #: ../en/ch14-hgext.xml:5 | |
15819 msgid "Adding functionality with extensions" | |
15820 msgstr "使用扩展增加功能" | |
15821 | |
15822 #. type: Content of: <book><chapter><para> | |
15823 #: ../en/ch14-hgext.xml:7 | |
15824 msgid "" | |
15825 "While the core of Mercurial is quite complete from a functionality " | |
15826 "standpoint, it's deliberately shorn of fancy features. This approach of " | |
15827 "preserving simplicity keeps the software easy to deal with for both " | |
15828 "maintainers and users." | |
15829 msgstr "" | |
15830 | |
15831 #. type: Content of: <book><chapter><para> | |
15832 #: ../en/ch14-hgext.xml:12 | |
15833 msgid "" | |
15834 "However, Mercurial doesn't box you in with an inflexible command set: you can " | |
15835 "add features to it as <emphasis>extensions</emphasis> (sometimes known as " | |
15836 "<emphasis>plugins</emphasis>). We've already discussed a few of these " | |
15837 "extensions in earlier chapters." | |
15838 msgstr "" | |
15839 | |
15840 #. type: Content of: <book><chapter><itemizedlist><listitem><para> | |
15841 #: ../en/ch14-hgext.xml:18 | |
15842 msgid "" | |
15843 "Section <xref linkend=\"sec.tour-merge.fetch\"/> covers the <literal role=" | |
15844 "\"hg-ext\">fetch</literal> extension; this combines pulling new changes and " | |
15845 "merging them with local changes into a single command, <command role=\"hg-ext-" | |
15846 "fetch\">fetch</command>." | |
15847 msgstr "" | |
15848 | |
15849 #. type: Content of: <book><chapter><itemizedlist><listitem><para> | |
15850 #: ../en/ch14-hgext.xml:24 | |
15851 msgid "" | |
15852 "In chapter <xref linkend=\"chap.hook\"/>, we covered several extensions that " | |
15853 "are useful for hook-related functionality: <literal role=\"hg-ext\">acl</" | |
15854 "literal> adds access control lists; <literal role=\"hg-ext\">bugzilla</" | |
15855 "literal> adds integration with the Bugzilla bug tracking system; and <literal " | |
15856 "role=\"hg-ext\">notify</literal> sends notification emails on new changes." | |
15857 msgstr "" | |
15858 | |
15859 #. type: Content of: <book><chapter><itemizedlist><listitem><para> | |
15860 #: ../en/ch14-hgext.xml:33 | |
15861 msgid "" | |
15862 "The Mercurial Queues patch management extension is so invaluable that it " | |
15863 "merits two chapters and an appendix all to itself. Chapter <xref linkend=" | |
15864 "\"chap.mq\"/> covers the basics; chapter <xref linkend=\"chap.mq-collab\"/> " | |
15865 "discusses advanced topics; and appendix <xref linkend=\"chap.mqref\"/> goes " | |
15866 "into detail on each command." | |
15867 msgstr "" | |
15868 | |
15869 #. type: Content of: <book><chapter><para> | |
15870 #: ../en/ch14-hgext.xml:43 | |
15871 msgid "" | |
15872 "In this chapter, we'll cover some of the other extensions that are available " | |
15873 "for Mercurial, and briefly touch on some of the machinery you'll need to know " | |
15874 "about if you want to write an extension of your own." | |
15875 msgstr "" | |
15876 | |
15877 #. type: Content of: <book><chapter><itemizedlist><listitem><para> | |
15878 #: ../en/ch14-hgext.xml:48 | |
15879 msgid "" | |
15880 "In section <xref linkend=\"sec.hgext.inotify\"/>, we'll discuss the " | |
15881 "possibility of <emphasis>huge</emphasis> performance improvements using the " | |
15882 "<literal role=\"hg-ext\">inotify</literal> extension." | |
15883 msgstr "" | |
15884 | |
15885 #. type: Content of: <book><chapter><sect1><title> | |
15886 #: ../en/ch14-hgext.xml:55 | |
15887 msgid "" | |
15888 "Improve performance with the <literal role=\"hg-ext\">inotify</literal> " | |
15889 "extension" | |
15890 msgstr "" | |
15891 | |
15892 #. type: Content of: <book><chapter><sect1><para> | |
15893 #: ../en/ch14-hgext.xml:58 | |
15894 msgid "" | |
15895 "Are you interested in having some of the most common Mercurial operations run " | |
15896 "as much as a hundred times faster? Read on!" | |
15897 msgstr "" | |
15898 | |
15899 #. type: Content of: <book><chapter><sect1><para> | |
15900 #: ../en/ch14-hgext.xml:62 | |
15901 msgid "" | |
15902 "Mercurial has great performance under normal circumstances. For example, " | |
15903 "when you run the <command role=\"hg-cmd\">hg status</command> command, " | |
15904 "Mercurial has to scan almost every directory and file in your repository so " | |
15905 "that it can display file status. Many other Mercurial commands need to do " | |
15906 "the same work behind the scenes; for example, the <command role=\"hg-cmd\">hg " | |
15907 "diff</command> command uses the status machinery to avoid doing an expensive " | |
15908 "comparison operation on files that obviously haven't changed." | |
15909 msgstr "" | |
15910 | |
15911 #. type: Content of: <book><chapter><sect1><para> | |
15912 #: ../en/ch14-hgext.xml:72 | |
15913 msgid "" | |
15914 "Because obtaining file status is crucial to good performance, the authors of " | |
15915 "Mercurial have optimised this code to within an inch of its life. However, " | |
15916 "there's no avoiding the fact that when you run <command role=\"hg-cmd\">hg " | |
15917 "status</command>, Mercurial is going to have to perform at least one " | |
15918 "expensive system call for each managed file to determine whether it's changed " | |
15919 "since the last time Mercurial checked. For a sufficiently large repository, " | |
15920 "this can take a long time." | |
15921 msgstr "" | |
15922 | |
15923 #. type: Content of: <book><chapter><sect1><para> | |
15924 #: ../en/ch14-hgext.xml:82 | |
15925 msgid "" | |
15926 "To put a number on the magnitude of this effect, I created a repository " | |
15927 "containing 150,000 managed files. I timed <command role=\"hg-cmd\">hg " | |
15928 "status</command> as taking ten seconds to run, even when <emphasis>none</" | |
15929 "emphasis> of those files had been modified." | |
15930 msgstr "" | |
15931 | |
15932 #. type: Content of: <book><chapter><sect1><para> | |
15933 #: ../en/ch14-hgext.xml:88 | |
15934 msgid "" | |
15935 "Many modern operating systems contain a file notification facility. If a " | |
15936 "program signs up to an appropriate service, the operating system will notify " | |
15937 "it every time a file of interest is created, modified, or deleted. On Linux " | |
15938 "systems, the kernel component that does this is called <literal>inotify</" | |
15939 "literal>." | |
15940 msgstr "" | |
15941 | |
15942 #. type: Content of: <book><chapter><sect1><para> | |
15943 #: ../en/ch14-hgext.xml:95 | |
15944 msgid "" | |
15945 "Mercurial's <literal role=\"hg-ext\">inotify</literal> extension talks to the " | |
15946 "kernel's <literal>inotify</literal> component to optimise <command role=\"hg-" | |
15947 "cmd\">hg status</command> commands. The extension has two components. A " | |
15948 "daemon sits in the background and receives notifications from the " | |
15949 "<literal>inotify</literal> subsystem. It also listens for connections from a " | |
15950 "regular Mercurial command. The extension modifies Mercurial's behaviour so " | |
15951 "that instead of scanning the filesystem, it queries the daemon. Since the " | |
15952 "daemon has perfect information about the state of the repository, it can " | |
15953 "respond with a result instantaneously, avoiding the need to scan every " | |
15954 "directory and file in the repository." | |
15955 msgstr "" | |
15956 | |
15957 #. type: Content of: <book><chapter><sect1><para> | |
15958 #: ../en/ch14-hgext.xml:108 | |
15959 msgid "" | |
15960 "Recall the ten seconds that I measured plain Mercurial as taking to run " | |
15961 "<command role=\"hg-cmd\">hg status</command> on a 150,000 file repository. " | |
15962 "With the <literal role=\"hg-ext\">inotify</literal> extension enabled, the " | |
15963 "time dropped to 0.1 seconds, a factor of <emphasis>one hundred</emphasis> " | |
15964 "faster." | |
15965 msgstr "" | |
15966 | |
15967 #. type: Content of: <book><chapter><sect1><para> | |
15968 #: ../en/ch14-hgext.xml:115 | |
15969 msgid "Before we continue, please pay attention to some caveats." | |
15970 msgstr "" | |
15971 | |
15972 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
15973 #: ../en/ch14-hgext.xml:118 | |
15974 msgid "" | |
15975 "The <literal role=\"hg-ext\">inotify</literal> extension is Linux-specific. " | |
15976 "Because it interfaces directly to the Linux kernel's <literal>inotify</" | |
15977 "literal> subsystem, it does not work on other operating systems." | |
15978 msgstr "" | |
15979 | |
15980 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
15981 #: ../en/ch14-hgext.xml:123 | |
15982 msgid "" | |
15983 "It should work on any Linux distribution that was released after early 2005. " | |
15984 "Older distributions are likely to have a kernel that lacks <literal>inotify</" | |
15985 "literal>, or a version of <literal>glibc</literal> that does not have the " | |
15986 "necessary interfacing support." | |
15987 msgstr "" | |
15988 | |
15989 #. type: Content of: <book><chapter><sect1><itemizedlist><listitem><para> | |
15990 #: ../en/ch14-hgext.xml:130 | |
15991 msgid "" | |
15992 "Not all filesystems are suitable for use with the <literal role=\"hg-ext" | |
15993 "\">inotify</literal> extension. Network filesystems such as NFS are a non-" | |
15994 "starter, for example, particularly if you're running Mercurial on several " | |
15995 "systems, all mounting the same network filesystem. The kernel's " | |
15996 "<literal>inotify</literal> system has no way of knowing about changes made on " | |
15997 "another system. Most local filesystems (e.g. ext3, XFS, ReiserFS) should " | |
15998 "work fine." | |
15999 msgstr "" | |
16000 | |
16001 #. type: Content of: <book><chapter><sect1><para> | |
16002 #: ../en/ch14-hgext.xml:141 | |
16003 msgid "" | |
16004 "The <literal role=\"hg-ext\">inotify</literal> extension is not yet shipped " | |
16005 "with Mercurial as of May 2007, so it's a little more involved to set up than " | |
16006 "other extensions. But the performance improvement is worth it!" | |
16007 msgstr "" | |
16008 | |
16009 #. type: Content of: <book><chapter><sect1><para> | |
16010 #: ../en/ch14-hgext.xml:146 | |
16011 msgid "" | |
16012 "The extension currently comes in two parts: a set of patches to the Mercurial " | |
16013 "source code, and a library of Python bindings to the <literal>inotify</" | |
16014 "literal> subsystem." | |
16015 msgstr "" | |
16016 | |
16017 #. type: Content of: <book><chapter><sect1><note><para> | |
16018 #: ../en/ch14-hgext.xml:150 | |
16019 msgid "" | |
16020 "There are <emphasis>two</emphasis> Python <literal>inotify</literal> binding " | |
16021 "libraries. One of them is called <literal>pyinotify</literal>, and is " | |
16022 "packaged by some Linux distributions as <literal>python-inotify</literal>. " | |
16023 "This is <emphasis>not</emphasis> the one you'll need, as it is too buggy and " | |
16024 "inefficient to be practical." | |
16025 msgstr "" | |
16026 | |
16027 #. type: Content of: <book><chapter><sect1><para> | |
16028 #: ../en/ch14-hgext.xml:157 | |
16029 msgid "" | |
16030 "To get going, it's best to already have a functioning copy of Mercurial " | |
16031 "installed." | |
16032 msgstr "" | |
16033 | |
16034 #. type: Content of: <book><chapter><sect1><note><para> | |
16035 #: ../en/ch14-hgext.xml:160 | |
16036 msgid "" | |
16037 "If you follow the instructions below, you'll be <emphasis>replacing</" | |
16038 "emphasis> and overwriting any existing installation of Mercurial that you " | |
16039 "might already have, using the latest <quote>bleeding edge</quote> Mercurial " | |
16040 "code. Don't say you weren't warned!" | |
16041 msgstr "" | |
16042 | |
16043 #. type: Content of: <book><chapter><sect1><orderedlist><listitem><para> | |
16044 #: ../en/ch14-hgext.xml:167 | |
16045 msgid "" | |
16046 "Clone the Python <literal>inotify</literal> binding repository. Build and " | |
16047 "install it." | |
16048 msgstr "" | |
16049 | |
16050 #. type: Content of: <book><chapter><sect1><orderedlist><listitem><para> | |
16051 #: ../en/ch14-hgext.xml:175 | |
16052 msgid "" | |
16053 "Clone the <filename class=\"directory\">crew</filename> Mercurial " | |
16054 "repository. Clone the <literal role=\"hg-ext\">inotify</literal> patch " | |
16055 "repository so that Mercurial Queues will be able to apply patches to your " | |
16056 "cope of the <filename class=\"directory\">crew</filename> repository." | |
16057 msgstr "" | |
16058 | |
16059 #. type: Content of: <book><chapter><sect1><orderedlist><listitem><para> | |
16060 #: ../en/ch14-hgext.xml:188 | |
16061 msgid "" | |
16062 "Make sure that you have the Mercurial Queues extension, <literal role=\"hg-ext" | |
16063 "\">mq</literal>, enabled. If you've never used MQ, read section <xref " | |
16064 "linkend=\"sec.mq.start\"/> to get started quickly." | |
16065 msgstr "" | |
16066 | |
16067 #. type: Content of: <book><chapter><sect1><orderedlist><listitem><para> | |
16068 #: ../en/ch14-hgext.xml:194 | |
16069 msgid "" | |
16070 "Go into the <filename class=\"directory\">inotify</filename> repo, and apply " | |
16071 "all of the <literal role=\"hg-ext\">inotify</literal> patches using the " | |
16072 "<option role=\"hg-ext-mq-cmd-qpush-opt\">hg -a</option> option to the " | |
16073 "<command role=\"hg-ext-mq\">qpush</command> command." | |
16074 msgstr "" | |
16075 | |
16076 #. type: Content of: <book><chapter><sect1><orderedlist><listitem><para> | |
16077 #: ../en/ch14-hgext.xml:204 | |
16078 msgid "" | |
16079 "If you get an error message from <command role=\"hg-ext-mq\">qpush</command>, " | |
16080 "you should not continue. Instead, ask for help." | |
16081 msgstr "" | |
16082 | |
16083 #. type: Content of: <book><chapter><sect1><orderedlist><listitem><para> | |
16084 #: ../en/ch14-hgext.xml:208 | |
16085 msgid "Build and install the patched version of Mercurial." | |
16086 msgstr "" | |
16087 | |
16088 #. type: Content of: <book><chapter><sect1><para> | |
16089 #: ../en/ch14-hgext.xml:216 | |
16090 msgid "" | |
16091 "Once you've build a suitably patched version of Mercurial, all you need to do " | |
16092 "to enable the <literal role=\"hg-ext\">inotify</literal> extension is add an " | |
16093 "entry to your <filename role=\"special\"> /.hgrc</filename>." | |
16094 msgstr "" | |
16095 | |
16096 #. type: Content of: <book><chapter><sect1><para> | |
16097 #: ../en/ch14-hgext.xml:221 | |
16098 msgid "" | |
16099 "When the <literal role=\"hg-ext\">inotify</literal> extension is enabled, " | |
16100 "Mercurial will automatically and transparently start the status daemon the " | |
16101 "first time you run a command that needs status in a repository. It runs one " | |
16102 "status daemon per repository." | |
16103 msgstr "" | |
16104 | |
16105 #. type: Content of: <book><chapter><sect1><para> | |
16106 #: ../en/ch14-hgext.xml:227 | |
16107 msgid "" | |
16108 "The status daemon is started silently, and runs in the background. If you " | |
16109 "look at a list of running processes after you've enabled the <literal role=" | |
16110 "\"hg-ext\">inotify</literal> extension and run a few commands in different " | |
16111 "repositories, you'll thus see a few <literal>hg</literal> processes sitting " | |
16112 "around, waiting for updates from the kernel and queries from Mercurial." | |
16113 msgstr "" | |
16114 | |
16115 #. type: Content of: <book><chapter><sect1><para> | |
16116 #: ../en/ch14-hgext.xml:235 | |
16117 msgid "" | |
16118 "The first time you run a Mercurial command in a repository when you have the " | |
16119 "<literal role=\"hg-ext\">inotify</literal> extension enabled, it will run " | |
16120 "with about the same performance as a normal Mercurial command. This is " | |
16121 "because the status daemon needs to perform a normal status scan so that it " | |
16122 "has a baseline against which to apply later updates from the kernel. " | |
16123 "However, <emphasis>every</emphasis> subsequent command that does any kind of " | |
16124 "status check should be noticeably faster on repositories of even fairly " | |
16125 "modest size. Better yet, the bigger your repository is, the greater a " | |
16126 "performance advantage you'll see. The <literal role=\"hg-ext\">inotify</" | |
16127 "literal> daemon makes status operations almost instantaneous on repositories " | |
16128 "of all sizes!" | |
16129 msgstr "" | |
16130 | |
16131 #. type: Content of: <book><chapter><sect1><para> | |
16132 #: ../en/ch14-hgext.xml:249 | |
16133 msgid "" | |
16134 "If you like, you can manually start a status daemon using the <command role=" | |
16135 "\"hg-ext-inotify\">inserve</command> command. This gives you slightly finer " | |
16136 "control over how the daemon ought to run. This command will of course only " | |
16137 "be available when the <literal role=\"hg-ext\">inotify</literal> extension is " | |
16138 "enabled." | |
16139 msgstr "" | |
16140 | |
16141 #. type: Content of: <book><chapter><sect1><para> | |
16142 #: ../en/ch14-hgext.xml:256 | |
16143 msgid "" | |
16144 "When you're using the <literal role=\"hg-ext\">inotify</literal> extension, " | |
16145 "you should notice <emphasis>no difference at all</emphasis> in Mercurial's " | |
16146 "behaviour, with the sole exception of status-related commands running a whole " | |
16147 "lot faster than they used to. You should specifically expect that commands " | |
16148 "will not print different output; neither should they give different results. " | |
16149 "If either of these situations occurs, please report a bug." | |
16150 msgstr "" | |
16151 | |
16152 #. type: Content of: <book><chapter><sect1><title> | |
16153 #: ../en/ch14-hgext.xml:267 | |
16154 msgid "" | |
16155 "Flexible diff support with the <literal role=\"hg-ext\">extdiff</literal> " | |
16156 "extension" | |
16157 msgstr "" | |
16158 | |
16159 #. type: Content of: <book><chapter><sect1><para> | |
16160 #: ../en/ch14-hgext.xml:270 | |
16161 msgid "" | |
16162 "Mercurial's built-in <command role=\"hg-cmd\">hg diff</command> command " | |
16163 "outputs plaintext unified diffs." | |
16164 msgstr "" | |
16165 "Mercurial 内置命令 <command role=\"hg-cmd\">hg diff</command> 的输出与统一差异" | |
16166 "不同。" | |
16167 | |
16168 #. type: Content of: <book><chapter><sect1><para> | |
16169 #: ../en/ch14-hgext.xml:275 | |
16170 msgid "" | |
16171 "If you would like to use an external tool to display modifications, you'll " | |
16172 "want to use the <literal role=\"hg-ext\">extdiff</literal> extension. This " | |
16173 "will let you use, for example, a graphical diff tool." | |
16174 msgstr "" | |
16175 | |
16176 #. type: Content of: <book><chapter><sect1><para> | |
16177 #: ../en/ch14-hgext.xml:280 | |
16178 msgid "" | |
16179 "The <literal role=\"hg-ext\">extdiff</literal> extension is bundled with " | |
16180 "Mercurial, so it's easy to set up. In the <literal role=\"rc-extensions" | |
16181 "\">extensions</literal> section of your <filename role=\"special\"> /.hgrc</" | |
16182 "filename>, simply add a one-line entry to enable the extension." | |
16183 msgstr "" | |
16184 | |
16185 #. type: Content of: <book><chapter><sect1><para> | |
16186 #: ../en/ch14-hgext.xml:286 | |
16187 msgid "" | |
16188 "This introduces a command named <command role=\"hg-ext-extdiff\">extdiff</" | |
16189 "command>, which by default uses your system's <command>diff</command> command " | |
16190 "to generate a unified diff in the same form as the built-in <command role=" | |
16191 "\"hg-cmd\">hg diff</command> command." | |
16192 msgstr "" | |
16193 | |
16194 #. type: Content of: <book><chapter><sect1><para> | |
16195 #: ../en/ch14-hgext.xml:294 | |
16196 msgid "" | |
16197 "The result won't be exactly the same as with the built-in <command role=\"hg-" | |
16198 "cmd\">hg diff</command> variations, because the output of <command>diff</" | |
16199 "command> varies from one system to another, even when passed the same options." | |
16200 msgstr "" | |
16201 | |
16202 #. type: Content of: <book><chapter><sect1><para> | |
16203 #: ../en/ch14-hgext.xml:299 | |
16204 msgid "" | |
16205 "As the <quote><literal>making snapshot</literal></quote> lines of output " | |
16206 "above imply, the <command role=\"hg-ext-extdiff\">extdiff</command> command " | |
16207 "works by creating two snapshots of your source tree. The first snapshot is " | |
16208 "of the source revision; the second, of the target revision or working " | |
16209 "directory. The <command role=\"hg-ext-extdiff\">extdiff</command> command " | |
16210 "generates these snapshots in a temporary directory, passes the name of each " | |
16211 "directory to an external diff viewer, then deletes the temporary directory. " | |
16212 "For efficiency, it only snapshots the directories and files that have changed " | |
16213 "between the two revisions." | |
16214 msgstr "" | |
16215 | |
16216 #. type: Content of: <book><chapter><sect1><para> | |
16217 #: ../en/ch14-hgext.xml:312 | |
16218 msgid "" | |
16219 "Snapshot directory names have the same base name as your repository. If your " | |
16220 "repository path is <filename class=\"directory\">/quux/bar/foo</filename>, " | |
16221 "then <filename class=\"directory\">foo</filename> will be the name of each " | |
16222 "snapshot directory. Each snapshot directory name has its changeset ID " | |
16223 "appended, if appropriate. If a snapshot is of revision " | |
16224 "<literal>a631aca1083f</literal>, the directory will be named <filename class=" | |
16225 "\"directory\">foo.a631aca1083f</filename>. A snapshot of the working " | |
16226 "directory won't have a changeset ID appended, so it would just be <filename " | |
16227 "class=\"directory\">foo</filename> in this example. To see what this looks " | |
16228 "like in practice, look again at the <command role=\"hg-ext-extdiff\">extdiff</" | |
16229 "command> example above. Notice that the diff has the snapshot directory " | |
16230 "names embedded in its header." | |
16231 msgstr "" | |
16232 | |
16233 #. type: Content of: <book><chapter><sect1><para> | |
16234 #: ../en/ch14-hgext.xml:328 | |
16235 msgid "" | |
16236 "The <command role=\"hg-ext-extdiff\">extdiff</command> command accepts two " | |
16237 "important options. The <option role=\"hg-ext-extdiff-cmd-extdiff-opt\">hg -p</" | |
16238 "option> option lets you choose a program to view differences with, instead of " | |
16239 "<command>diff</command>. With the <option role=\"hg-ext-extdiff-cmd-extdiff-" | |
16240 "opt\">hg -o</option> option, you can change the options that <command role=" | |
16241 "\"hg-ext-extdiff\">extdiff</command> passes to the program (by default, these " | |
16242 "options are <quote><literal>-Npru</literal></quote>, which only make sense if " | |
16243 "you're running <command>diff</command>). In other respects, the <command " | |
16244 "role=\"hg-ext-extdiff\">extdiff</command> command acts similarly to the built-" | |
16245 "in <command role=\"hg-cmd\">hg diff</command> command: you use the same " | |
16246 "option names, syntax, and arguments to specify the revisions you want, the " | |
16247 "files you want, and so on." | |
16248 msgstr "" | |
16249 | |
16250 # | |
16251 #. type: Content of: <book><chapter><sect1><para> | |
16252 #: ../en/ch14-hgext.xml:345 | |
16253 msgid "" | |
16254 "As an example, here's how to run the normal system <command>diff</command> " | |
16255 "command, getting it to generate context diffs (using the <option role=\"cmd-" | |
16256 "opt-diff\">-c</option> option) instead of unified diffs, and five lines of " | |
16257 "context instead of the default three (passing <literal>5</literal> as the " | |
16258 "argument to the <option role=\"cmd-opt-diff\">-C</option> option)." | |
16259 msgstr "" | |
16260 | |
16261 #. type: Content of: <book><chapter><sect1><para> | |
16262 #: ../en/ch14-hgext.xml:354 | |
16263 msgid "" | |
16264 "Launching a visual diff tool is just as easy. Here's how to launch the " | |
16265 "<command>kdiff3</command> viewer." | |
16266 msgstr "" | |
16267 | |
16268 #. type: Content of: <book><chapter><sect1><para> | |
16269 #: ../en/ch14-hgext.xml:358 | |
16270 msgid "" | |
16271 "If your diff viewing command can't deal with directories, you can easily work " | |
16272 "around this with a little scripting. For an example of such scripting in " | |
16273 "action with the <literal role=\"hg-ext\">mq</literal> extension and the " | |
16274 "<command>interdiff</command> command, see section <xref linkend=\"mq-collab." | |
16275 "tips.interdiff\"/>." | |
16276 msgstr "" | |
16277 | |
16278 #. type: Content of: <book><chapter><sect1><sect2><title> | |
16279 #: ../en/ch14-hgext.xml:366 | |
16280 msgid "Defining command aliases" | |
16281 msgstr "" | |
16282 | |
16283 #. type: Content of: <book><chapter><sect1><sect2><para> | |
16284 #: ../en/ch14-hgext.xml:368 | |
16285 msgid "" | |
16286 "It can be cumbersome to remember the options to both the <command role=\"hg-" | |
16287 "ext-extdiff\">extdiff</command> command and the diff viewer you want to use, " | |
16288 "so the <literal role=\"hg-ext\">extdiff</literal> extension lets you define " | |
16289 "<emphasis>new</emphasis> commands that will invoke your diff viewer with " | |
16290 "exactly the right options." | |
16291 msgstr "" | |
16292 | |
16293 #. type: Content of: <book><chapter><sect1><sect2><para> | |
16294 #: ../en/ch14-hgext.xml:375 | |
16295 msgid "" | |
16296 "All you need to do is edit your <filename role=\"special\"> /.hgrc</" | |
16297 "filename>, and add a section named <literal role=\"rc-extdiff\">extdiff</" | |
16298 "literal>. Inside this section, you can define multiple commands. Here's how " | |
16299 "to add a <literal>kdiff3</literal> command. Once you've defined this, you " | |
16300 "can type <quote><literal>hg kdiff3</literal></quote> and the <literal role=" | |
16301 "\"hg-ext\">extdiff</literal> extension will run <command>kdiff3</command> for " | |
16302 "you." | |
16303 msgstr "" | |
16304 | |
16305 #. type: Content of: <book><chapter><sect1><sect2><para> | |
16306 #: ../en/ch14-hgext.xml:384 | |
16307 msgid "" | |
16308 "If you leave the right hand side of the definition empty, as above, the " | |
16309 "<literal role=\"hg-ext\">extdiff</literal> extension uses the name of the " | |
16310 "command you defined as the name of the external program to run. But these " | |
16311 "names don't have to be the same. Here, we define a command named " | |
16312 "<quote><literal>hg wibble</literal></quote>, which runs <command>kdiff3</" | |
16313 "command>." | |
16314 msgstr "" | |
16315 | |
16316 #. type: Content of: <book><chapter><sect1><sect2><para> | |
16317 #: ../en/ch14-hgext.xml:393 | |
16318 msgid "" | |
16319 "You can also specify the default options that you want to invoke your diff " | |
16320 "viewing program with. The prefix to use is <quote><literal>opts.</literal></" | |
16321 "quote>, followed by the name of the command to which the options apply. This " | |
16322 "example defines a <quote><literal>hg vimdiff</literal></quote> command that " | |
16323 "runs the <command>vim</command> editor's <literal>DirDiff</literal> extension." | |
16324 msgstr "" | |
16325 | |
16326 #. type: Content of: <book><chapter><sect1><title> | |
16327 #: ../en/ch14-hgext.xml:406 | |
16328 msgid "" | |
16329 "Cherrypicking changes with the <literal role=\"hg-ext\">transplant</literal> " | |
16330 "extension" | |
16331 msgstr "" | |
16332 | |
16333 #. type: Content of: <book><chapter><sect1><para> | |
16334 #: ../en/ch14-hgext.xml:409 | |
16335 msgid "Need to have a long chat with Brendan about this." | |
16336 msgstr "" | |
16337 | |
16338 #. type: Content of: <book><chapter><sect1><title> | |
16339 #: ../en/ch14-hgext.xml:413 | |
16340 msgid "" | |
16341 "Send changes via email with the <literal role=\"hg-ext\">patchbomb</literal> " | |
16342 "extension" | |
16343 msgstr "" | |
16344 | |
16345 #. type: Content of: <book><chapter><sect1><para> | |
16346 #: ../en/ch14-hgext.xml:416 | |
16347 msgid "" | |
16348 "Many projects have a culture of <quote>change review</quote>, in which people " | |
16349 "send their modifications to a mailing list for others to read and comment on " | |
16350 "before they commit the final version to a shared repository. Some projects " | |
16351 "have people who act as gatekeepers; they apply changes from other people to a " | |
16352 "repository to which those others don't have access." | |
16353 msgstr "" | |
16354 | |
16355 #. type: Content of: <book><chapter><sect1><para> | |
16356 #: ../en/ch14-hgext.xml:424 | |
16357 msgid "" | |
16358 "Mercurial makes it easy to send changes over email for review or application, " | |
16359 "via its <literal role=\"hg-ext\">patchbomb</literal> extension. The " | |
16360 "extension is so named because changes are formatted as patches, and it's " | |
16361 "usual to send one changeset per email message. Sending a long series of " | |
16362 "changes by email is thus much like <quote>bombing</quote> the recipient's " | |
16363 "inbox, hence <quote>patchbomb</quote>." | |
16364 msgstr "" | |
16365 | |
16366 #. type: Content of: <book><chapter><sect1><para> | |
16367 #: ../en/ch14-hgext.xml:432 | |
16368 msgid "" | |
16369 "As usual, the basic configuration of the <literal role=\"hg-ext\">patchbomb</" | |
16370 "literal> extension takes just one or two lines in your <filename role=" | |
16371 "\"special\"> /.hgrc</filename>." | |
16372 msgstr "" | |
16373 | |
16374 #. type: Content of: <book><chapter><sect1><para> | |
16375 #: ../en/ch14-hgext.xml:437 | |
16376 msgid "" | |
16377 "Once you've enabled the extension, you will have a new command available, " | |
16378 "named <command role=\"hg-ext-patchbomb\">email</command>." | |
16379 msgstr "" | |
16380 | |
16381 #. type: Content of: <book><chapter><sect1><para> | |
16382 #: ../en/ch14-hgext.xml:441 | |
16383 msgid "" | |
16384 "The safest and best way to invoke the <command role=\"hg-ext-patchbomb" | |
16385 "\">email</command> command is to <emphasis>always</emphasis> run it first " | |
16386 "with the <option role=\"hg-ext-patchbomb-cmd-email-opt\">hg -n</option> " | |
16387 "option. This will show you what the command <emphasis>would</emphasis> send, " | |
16388 "without actually sending anything. Once you've had a quick glance over the " | |
16389 "changes and verified that you are sending the right ones, you can rerun the " | |
16390 "same command, with the <option role=\"hg-ext-patchbomb-cmd-email-opt\">hg -n</" | |
16391 "option> option removed." | |
16392 msgstr "" | |
16393 | |
16394 #. type: Content of: <book><chapter><sect1><para> | |
16395 #: ../en/ch14-hgext.xml:452 | |
16396 msgid "" | |
16397 "The <command role=\"hg-ext-patchbomb\">email</command> command accepts the " | |
16398 "same kind of revision syntax as every other Mercurial command. For example, " | |
16399 "this command will send every revision between 7 and <literal>tip</literal>, " | |
16400 "inclusive." | |
16401 msgstr "" | |
16402 | |
16403 #. type: Content of: <book><chapter><sect1><para> | |
16404 #: ../en/ch14-hgext.xml:457 | |
16405 msgid "" | |
16406 "You can also specify a <emphasis>repository</emphasis> to compare with. If " | |
16407 "you provide a repository but no revisions, the <command role=\"hg-ext-" | |
16408 "patchbomb\">email</command> command will send all revisions in the local " | |
16409 "repository that are not present in the remote repository. If you " | |
16410 "additionally specify revisions or a branch name (the latter using the <option " | |
16411 "role=\"hg-ext-patchbomb-cmd-email-opt\">hg -b</option> option), this will " | |
16412 "constrain the revisions sent." | |
16413 msgstr "" | |
16414 | |
16415 #. type: Content of: <book><chapter><sect1><para> | |
16416 #: ../en/ch14-hgext.xml:466 | |
16417 msgid "" | |
16418 "It's perfectly safe to run the <command role=\"hg-ext-patchbomb\">email</" | |
16419 "command> command without the names of the people you want to send to: if you " | |
16420 "do this, it will just prompt you for those values interactively. (If you're " | |
16421 "using a Linux or Unix-like system, you should have enhanced " | |
16422 "<literal>readline</literal>-style editing capabilities when entering those " | |
16423 "headers, too, which is useful.)" | |
16424 msgstr "" | |
16425 | |
16426 #. type: Content of: <book><chapter><sect1><para> | |
16427 #: ../en/ch14-hgext.xml:474 | |
16428 msgid "" | |
16429 "When you are sending just one revision, the <command role=\"hg-ext-patchbomb" | |
16430 "\">email</command> command will by default use the first line of the " | |
16431 "changeset description as the subject of the single email message it sends." | |
16432 msgstr "" | |
16433 | |
16434 #. type: Content of: <book><chapter><sect1><para> | |
16435 #: ../en/ch14-hgext.xml:479 | |
16436 msgid "" | |
16437 "If you send multiple revisions, the <command role=\"hg-ext-patchbomb\">email</" | |
16438 "command> command will usually send one message per changeset. It will " | |
16439 "preface the series with an introductory message, in which you should describe " | |
16440 "the purpose of the series of changes you're sending." | |
16441 msgstr "" | |
16442 | |
16443 #. type: Content of: <book><chapter><sect1><sect2><title> | |
16444 #: ../en/ch14-hgext.xml:486 | |
16445 msgid "Changing the behaviour of patchbombs" | |
16446 msgstr "" | |
16447 | |
16448 #. type: Content of: <book><chapter><sect1><sect2><para> | |
16449 #: ../en/ch14-hgext.xml:488 | |
16450 msgid "" | |
16451 "Not every project has exactly the same conventions for sending changes in " | |
16452 "email; the <literal role=\"hg-ext\">patchbomb</literal> extension tries to " | |
16453 "accommodate a number of variations through command line options." | |
16454 msgstr "" | |
16455 | |
16456 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
16457 #: ../en/ch14-hgext.xml:494 | |
16458 msgid "" | |
16459 "You can write a subject for the introductory message on the command line " | |
16460 "using the <option role=\"hg-ext-patchbomb-cmd-email-opt\">hg -s</option> " | |
16461 "option. This takes one argument, the text of the subject to use." | |
16462 msgstr "" | |
16463 | |
16464 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
16465 #: ../en/ch14-hgext.xml:500 | |
16466 msgid "" | |
16467 "To change the email address from which the messages originate, use the " | |
16468 "<option role=\"hg-ext-patchbomb-cmd-email-opt\">hg -f</option> option. This " | |
16469 "takes one argument, the email address to use." | |
16470 msgstr "" | |
16471 | |
16472 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
16473 #: ../en/ch14-hgext.xml:506 | |
16474 msgid "" | |
16475 "The default behaviour is to send unified diffs (see section <xref linkend=" | |
16476 "\"sec.mq.patch\"/> for a description of the format), one per message. You " | |
16477 "can send a binary bundle instead with the <option role=\"hg-ext-patchbomb-cmd-" | |
16478 "email-opt\">hg -b</option> option." | |
16479 msgstr "" | |
16480 | |
16481 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
16482 #: ../en/ch14-hgext.xml:514 | |
16483 msgid "" | |
16484 "Unified diffs are normally prefaced with a metadata header. You can omit " | |
16485 "this, and send unadorned diffs, with the <option role=\"hg-ext-patchbomb-cmd-" | |
16486 "email-opt\">hg --plain</option> option." | |
16487 msgstr "" | |
16488 | |
16489 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
16490 #: ../en/ch14-hgext.xml:520 | |
16491 msgid "" | |
16492 "Diffs are normally sent <quote>inline</quote>, in the same body part as the " | |
16493 "description of a patch. This makes it easiest for the largest number of " | |
16494 "readers to quote and respond to parts of a diff, as some mail clients will " | |
16495 "only quote the first MIME body part in a message. If you'd prefer to send the " | |
16496 "description and the diff in separate body parts, use the <option role=\"hg-" | |
16497 "ext-patchbomb-cmd-email-opt\">hg -a</option> option." | |
16498 msgstr "" | |
16499 | |
16500 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
16501 #: ../en/ch14-hgext.xml:530 | |
16502 msgid "" | |
16503 "Instead of sending mail messages, you can write them to an <literal>mbox</" | |
16504 "literal>-format mail folder using the <option role=\"hg-ext-patchbomb-cmd-" | |
16505 "email-opt\">hg -m</option> option. That option takes one argument, the name " | |
16506 "of the file to write to." | |
16507 msgstr "" | |
16508 | |
16509 #. type: Content of: <book><chapter><sect1><sect2><itemizedlist><listitem><para> | |
16510 #: ../en/ch14-hgext.xml:537 | |
16511 msgid "" | |
16512 "If you would like to add a <command>diffstat</command>-format summary to each " | |
16513 "patch, and one to the introductory message, use the <option role=\"hg-ext-" | |
16514 "patchbomb-cmd-email-opt\">hg -d</option> option. The <command>diffstat</" | |
16515 "command> command displays a table containing the name of each file patched, " | |
16516 "the number of lines affected, and a histogram showing how much each file is " | |
16517 "modified. This gives readers a qualitative glance at how complex a patch is." | |
16518 msgstr "" |