Mercurial > hgbook
annotate ja/concepts.tex @ 802:de4142983445
Propagate 3b640272a966
Progres on resolve
author | Yoshiki Yazawa <yaz@honeyplanet.jp> |
---|---|
date | Sun, 21 Jun 2009 09:20:47 +0900 |
parents | 1a30d2627512 |
children | 8a3041e6f3cb |
rev | line source |
---|---|
781 | 1 %\chapter{Behind the scenes} |
2 \chapter{$BIqBfN"(B} | |
56
b8539d91c84d
Begining of concepts chapter
Josef "Jeff" Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
3 \label{chap:concepts} |
b8539d91c84d
Begining of concepts chapter
Josef "Jeff" Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
4 |
800 | 5 %Unlike many revision control systems, the concepts upon which Mercurial |
6 %is built are simple enough that it's easy to understand how the software | |
7 %really works. Knowing these details certainly isn't necessary, so it is | |
8 %certainly safe to skip this chapter. However, I think you will get more | |
9 %out of the software with a ``mental model'' of what's going on. | |
781 | 10 |
11 $BB?$/$N%j%S%8%g%s%3%s%H%m!<%k%7%9%F%`$H0c$C$F!$(B Mercurial$B$NF0:n$N4pK\$H$J$C(B | |
800 | 12 $B$F$$$k35G0$rM}2r$9$k$3$H$OMF0W$$!%$3$l$i$N>\:Y$rM}2r$9$k$3$H$OI,$:$7$bI,(B |
13 $BMW$G$O$J$/!$$3$N>O$rHt$P$7$F$b:9$7;Y$($J$$!%$7$+$7I.<T$O!$%=%U%H%&%'%"$r(B | |
14 $B$h$j$h$/;H$&>e$G2?$,5/$-$F$$$k$N$+$K$D$$$F%b%G%k$r0U<1$7$F$$$k$3$H$OM-MQ(B | |
15 $B$G$"$k$H9M$($F$$$k!%(B | |
781 | 16 |
800 | 17 %Being able to understand what's going on behind the scenes gives me |
18 %confidence that Mercurial has been carefully designed to be both | |
19 %\emph{safe} and \emph{efficient}. And just as importantly, if it's easy | |
20 %for me to retain a good idea of what the software is doing when I | |
21 %perform a revision control task, I'm less likely to be surprised by its | |
22 %behaviour. | |
56
b8539d91c84d
Begining of concepts chapter
Josef "Jeff" Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
23 |
800 | 24 $BIqBfN"$G2?$,5/$3$C$F$$$k$N$+M}2r$G$-$k$H!$I.<T$O(BMercurial$B$,(B\emph{$B0BA4(B}$B$H(B |
25 \emph{$B8zN((B}$B$r<B8=$9$k$h$&$KCm0U?<$/@_7W$5$l$F$$$k$H3N?.$9$k$3$H$,$G$-$?!%(B | |
781 | 26 $B$^$?!$=EMW$JE@$H$7$F!$%j%S%8%g%s%3%s%H%m!<%k$NA`:n$r9T$&:]$K%=%U%H%&%'%"(B |
27 $B$,2?$r$9$k$N$+$r5-21$KN1$a$F$*$/$3$H$K$h$C$F!$IT0U$N5sF0$G6C$/$3$H$,>/$J(B | |
28 $B$/$J$C$?!%(B | |
109
1b67dc96f27a
Snapshot of concepts chapter.
Bryan O'Sullivan <bos@serpentine.com>
parents:
108
diff
changeset
|
29 |
781 | 30 %In this chapter, we'll initially cover the core concepts behind |
31 %Mercurial's design, then continue to discuss some of the interesting | |
32 %details of its implementation. | |
112 | 33 |
781 | 34 $B$3$N>O$G$O$^$:(BMercurial$B$N@_7W$N%3%"%3%s%;%W%H$r%+%P!<$9$k!%$=$7$F<BAu>e$N(B |
35 $B$$$/$D$+$N6=L#?<$$E@$N>\:Y$K$D$$$F5DO@$9$k!%(B | |
36 | |
37 %\section{Mercurial's historical record} | |
38 \section{Mercurial$B$NMzNr5-O?(B} | |
109
1b67dc96f27a
Snapshot of concepts chapter.
Bryan O'Sullivan <bos@serpentine.com>
parents:
108
diff
changeset
|
39 |
781 | 40 %\subsection{Tracking the history of a single file} |
41 \subsection{$B%U%!%$%kMzNr$NDI@W(B} | |
42 | |
43 %When Mercurial tracks modifications to a file, it stores the history | |
44 %of that file in a metadata object called a \emph{filelog}. Each entry | |
45 %in the filelog contains enough information to reconstruct one revision | |
46 %of the file that is being tracked. Filelogs are stored as files in | |
47 %the \sdirname{.hg/store/data} directory. A filelog contains two kinds | |
48 %of information: revision data, and an index to help Mercurial to find | |
49 %a revision efficiently. | |
56
b8539d91c84d
Begining of concepts chapter
Josef "Jeff" Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
50 |
781 | 51 Mercurial$B$O%U%!%$%k$X$NJQ99$rDI@W$9$k;~!$%U%!%$%k$NMzNr$r(B\emph{filelog}$B$H(B |
52 $B8F$P$l$k%a%?%G!<%?%*%V%8%'%/%H$K3JG<$9$k!%%U%!%$%k%m%0Fb$N3F!9$N%(%s%H%j(B | |
53 $B$O!$DI@WBP>]$N%U%!%$%k$N%j%S%8%g%s$r:F7z$9$k$N$K==J,$J>pJs$r;}$D!%%U%!%$(B | |
54 $B%k%m%0$O(B\sdirname{.hg/store/data}$B%G%#%l%/%H%j$K%U%!%$%k$H$7$FJ]B8$5$l$k!%(B | |
55 $B%U%!%$%k%m%0$O%j%S%8%g%s%G!<%?$H(BMercurial$B$,%j%S%8%g%s$r8zN(E*$K8+$D$1$i$l(B | |
56 $B$k$h$&$K$9$k$?$a$N%$%s%G%C%/%9$N(B2$B<oN`$N>pJs$r;}$D!%(B | |
56
b8539d91c84d
Begining of concepts chapter
Josef "Jeff" Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
57 |
781 | 58 %A file that is large, or has a lot of history, has its filelog stored |
59 %in separate data (``\texttt{.d}'' suffix) and index (``\texttt{.i}'' | |
60 %suffix) files. For small files without much history, the revision | |
61 %data and index are combined in a single ``\texttt{.i}'' file. The | |
62 %correspondence between a file in the working directory and the filelog | |
63 %that tracks its history in the repository is illustrated in | |
64 %figure~\ref{fig:concepts:filelog}. | |
65 | |
66 $B%5%$%:$NBg$-$J%U%!%$%k$d!$KDBg$JMzNr$r;}$D%U%!%$%k$O!$%G!<%?$,(B | |
67 (``\texttt{.d}'' suffix) $B$*$h$S%$%s%G%C%/%9(B (``\texttt{.i}'' suffix)$B$N%U%!(B | |
68 $B%$%k$KJ,3d$5$l$?(Bfilelog$B$r;}$D!%%5%$%:$,>.$5$/!$MzNr$NBg$-$/$J$$%U%!%$%k$O(B | |
69 $B%j%S%8%g%s%G!<%?$H%$%s%G%C%/%9$,(B1$B$D$N(B``\texttt{.i}''$B%U%!%$%k$K7k9g$5$l$F(B | |
70 $B$$$k!%%o!<%-%s%0%G%#%l%/%H%jFb$N%U%!%$%k$H%j%]%8%H%jFb$NMzNr$rDI@W$9$k(B | |
71 filelog$B$H$NBP1~$r?^(B~\ref{fig:concepts:filelog}$B$K<($9!%(B | |
56
b8539d91c84d
Begining of concepts chapter
Josef "Jeff" Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
72 |
b8539d91c84d
Begining of concepts chapter
Josef "Jeff" Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
73 \begin{figure}[ht] |
108
e0b961975c5e
First bit of concepts chapter.
Bryan O'Sullivan <bos@serpentine.com>
parents:
56
diff
changeset
|
74 \centering |
294 | 75 % \grafix{filelog} |
76 \includegraphics{filelog} | |
781 | 77 % \caption{Relationships between files in working directory and |
78 % filelogs in repository} | |
79 \caption{$B%o!<%-%s%0%G%#%l%/%H%jFb$N%U%!%$%k$H%j%]%8%H%j$N%U%!%$%k%m%0(B | |
80 $B$N4X78(B} | |
108
e0b961975c5e
First bit of concepts chapter.
Bryan O'Sullivan <bos@serpentine.com>
parents:
56
diff
changeset
|
81 \label{fig:concepts:filelog} |
56
b8539d91c84d
Begining of concepts chapter
Josef "Jeff" Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
82 \end{figure} |
b8539d91c84d
Begining of concepts chapter
Josef "Jeff" Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
83 |
781 | 84 %\subsection{Managing tracked files} |
85 \subsection{$BDI@W$5$l$F$$$k%U%!%$%k$N4IM}(B} | |
86 | |
87 %Mercurial uses a structure called a \emph{manifest} to collect | |
88 %together information about the files that it tracks. Each entry in | |
89 %the manifest contains information about the files present in a single | |
90 %changeset. An entry records which files are present in the changeset, | |
91 %the revision of each file, and a few other pieces of file metadata. | |
109
1b67dc96f27a
Snapshot of concepts chapter.
Bryan O'Sullivan <bos@serpentine.com>
parents:
108
diff
changeset
|
92 |
781 | 93 Mercurial$B$O(B\emph{$B%^%K%U%'%9%H(B}$B$H8F$P$l$k9=B$$rMQ$$$F!$DI@W$9$Y$-%U%!%$%k(B |
94 $B$N>pJs$r=8$a$F$$$k!%%^%K%U%'%9%HFb$N3F!9$N%(%s%H%j$O!$C10l$N%A%'%s%8%;%C(B | |
95 $B%HFb$KB8:_$9$k%U%!%$%k$N>pJs$r;}$C$F$$$k!%%(%s%H%j$O$I$N%U%!%$%k$,%A%'%s(B | |
96 $B%8%;%C%H$KB8:_$7$F$$$k$+!$$=$l$i$N%j%S%8%g%s$,2?$G$"$k$N$+$H$$$&>pJs$H!$(B | |
97 $B$$$/$D$+$NB>$N%U%!%$%k%a%?%G!<%?$r5-O?$7$F$$$k!%(B | |
98 | |
99 %\subsection{Recording changeset information} | |
100 \subsection{$B%A%'%s%8%;%C%H>pJs$N5-O?(B} | |
109
1b67dc96f27a
Snapshot of concepts chapter.
Bryan O'Sullivan <bos@serpentine.com>
parents:
108
diff
changeset
|
101 |
781 | 102 %The \emph{changelog} contains information about each changeset. Each |
103 %revision records who committed a change, the changeset comment, other | |
104 %pieces of changeset-related information, and the revision of the | |
105 %manifest to use. | |
109
1b67dc96f27a
Snapshot of concepts chapter.
Bryan O'Sullivan <bos@serpentine.com>
parents:
108
diff
changeset
|
106 |
781 | 107 \emph{changelog}$B$O3F!9$N%A%'%s%8%;%C%H$N>pJs$r;}$D!%3F!9$N%j%S%8%g%s5-O?(B |
108 $B$O!$C/$,JQ99$r%3%_%C%H$7$?$N$+!$%A%'%s%8%;%C%H$N%3%a%s%H!$JQ99$K4XO"$7$?(B | |
109 $BB>$N>pJs!$;HMQ$5$l$k%^%K%U%'%9%H$N%j%S%8%g%s$r;}$D!%(B | |
109
1b67dc96f27a
Snapshot of concepts chapter.
Bryan O'Sullivan <bos@serpentine.com>
parents:
108
diff
changeset
|
110 |
781 | 111 %\subsection{Relationships between revisions} |
112 \subsection{$B%j%S%8%g%s4V$N4X78(B} | |
113 | |
114 %Within a changelog, a manifest, or a filelog, each revision stores a | |
115 %pointer to its immediate parent (or to its two parents, if it's a | |
116 %merge revision). As I mentioned above, there are also relationships | |
117 %between revisions \emph{across} these structures, and they are | |
118 %hierarchical in nature. | |
109
1b67dc96f27a
Snapshot of concepts chapter.
Bryan O'Sullivan <bos@serpentine.com>
parents:
108
diff
changeset
|
119 |
781 | 120 $B%A%'%s%8%m%0!$%^%K%U%'%9%H!$%U%!%$%k%m%0Fb$G!$3F!9$N%j%S%8%g%s$OD>@\$N?F(B |
121 $B!J$"$k$$$O%^!<%8$N>l9g$O$=$NN>?F!K$X$N%]%$%s%?$r;}$D!%(B | |
122 $B$9$G$K=R$Y$?$h$&$K!$$3$N9=B$$K8=$l$k%j%S%8%g%s$N4V$K$O4X78$,$"$j!$K\<A(B | |
123 $BE*$K3,AXE*$G$"$k!%(B | |
109
1b67dc96f27a
Snapshot of concepts chapter.
Bryan O'Sullivan <bos@serpentine.com>
parents:
108
diff
changeset
|
124 |
781 | 125 %For every changeset in a repository, there is exactly one revision |
126 %stored in the changelog. Each revision of the changelog contains a | |
127 %pointer to a single revision of the manifest. A revision of the | |
128 %manifest stores a pointer to a single revision of each filelog tracked | |
129 %when that changeset was created. These relationships are illustrated | |
130 %in figure~\ref{fig:concepts:metadata}. | |
131 | |
132 $B%j%]%8%H%j$K$"$k$9$Y$F$N%A%'%s%8%;%C%H$O!$%A%'%s%8%m%0Fb$G@53N$K(B1$B$D$N%j%S(B | |
133 $B%8%g%s$r;}$D!%%A%'%s%8%m%0$N3F!9$N%j%S%8%g%s$O!$%^%K%U%'%9%H$NC10l$N%P!<(B | |
134 $B%8%g%s$X$N%]%$%s%?$r;}$D!%%^%K%U%'%9%H$N3F!9$N%j%S%8%g%s$O!$%A%'%s%8%;%C(B | |
135 $B%H$,@8@.$5$l$?;~$N%U%!%$%k%m%0$N3F!9$NC10l%j%S%8%g%s$X$N%]%$%s%?$r;}$D!%(B | |
136 $B$3$N4X78$r?^(B~\ref{fig:concepts:metadata}$B$K<($9!%(B | |
109
1b67dc96f27a
Snapshot of concepts chapter.
Bryan O'Sullivan <bos@serpentine.com>
parents:
108
diff
changeset
|
137 |
1b67dc96f27a
Snapshot of concepts chapter.
Bryan O'Sullivan <bos@serpentine.com>
parents:
108
diff
changeset
|
138 \begin{figure}[ht] |
1b67dc96f27a
Snapshot of concepts chapter.
Bryan O'Sullivan <bos@serpentine.com>
parents:
108
diff
changeset
|
139 \centering |
294 | 140 \includegraphics{metadata} |
781 | 141 % \caption{Metadata relationships} |
142 \caption{$B%a%?%G!<%?$N4X78(B} | |
109
1b67dc96f27a
Snapshot of concepts chapter.
Bryan O'Sullivan <bos@serpentine.com>
parents:
108
diff
changeset
|
143 \label{fig:concepts:metadata} |
1b67dc96f27a
Snapshot of concepts chapter.
Bryan O'Sullivan <bos@serpentine.com>
parents:
108
diff
changeset
|
144 \end{figure} |
1b67dc96f27a
Snapshot of concepts chapter.
Bryan O'Sullivan <bos@serpentine.com>
parents:
108
diff
changeset
|
145 |
781 | 146 %As the illustration shows, there is \emph{not} a ``one to one'' |
147 %relationship between revisions in the changelog, manifest, or filelog. | |
148 %If the manifest hasn't changed between two changesets, the changelog | |
149 %entries for those changesets will point to the same revision of the | |
150 %manifest. If a file that Mercurial tracks hasn't changed between two | |
151 %changesets, the entry for that file in the two revisions of the | |
152 %manifest will point to the same revision of its filelog. | |
109
1b67dc96f27a
Snapshot of concepts chapter.
Bryan O'Sullivan <bos@serpentine.com>
parents:
108
diff
changeset
|
153 |
781 | 154 $B%$%i%9%H$G<($5$l$F$$$k$h$&$K!$%j%S%8%g%s$H%A%'%s%8%m%0!$%^%K%U%'%9%H$^$?(B |
155 $B$O%U%!%$%k%m%0$N4V$K$O(B1$BBP#1$N4X78$O$J$$!%%^%K%U%'%9%H$,(B2$B$D$N%A%'%s%8%;%C(B | |
156 $B%H$N4V$GJQ2=$7$J$+$C$?>l9g$O!$%A%'%s%8%m%0Fb$G$3$l$i$N%A%'%s%8%;%C%H$rI=(B | |
157 $B$9%(%s%H%j$OF1$8%P!<%8%g%s$N%^%K%U%'%9%H$r<($9!%(BMercurial$B$,DI@W$9$k%U%!%$(B | |
158 $B%k$,!$(B2$B$D$N%A%'%s%8%;%C%H4V$GJQ2=$7$J$+$C$?>l9g$O!$(B 2$B$D$N%^%K%U%'%9%H$N%j(B | |
159 $B%S%8%g%s$G!$$=$N%U%!%$%k$r<($9%(%s%H%j$O%U%!%$%k%m%0$NF1$8%j%S%8%g%s$r<((B | |
160 $B$9!%(B | |
109
1b67dc96f27a
Snapshot of concepts chapter.
Bryan O'Sullivan <bos@serpentine.com>
parents:
108
diff
changeset
|
161 |
781 | 162 %\section{Safe, efficient storage} |
163 \section{$B0BA4$+$D8zN(E*$J%9%H%l!<%8(B} | |
164 | |
165 %The underpinnings of changelogs, manifests, and filelogs are provided | |
166 %by a single structure called the \emph{revlog}. | |
109
1b67dc96f27a
Snapshot of concepts chapter.
Bryan O'Sullivan <bos@serpentine.com>
parents:
108
diff
changeset
|
167 |
782 | 168 $B%A%'%s%8%m%0!$%^%K%U%'%9%H$*$h$S%U%!%$%k%m%0$NEZBf$K;H$o$l$F$$$k$O6&DL$N(B |
781 | 169 \emph{revlog}$B$H$$$&9=B$BN$G$"$k!%(B |
170 | |
171 %\subsection{Efficient storage} | |
172 \subsection{$B8zN(E*$J%9%H%l!<%8(B} | |
109
1b67dc96f27a
Snapshot of concepts chapter.
Bryan O'Sullivan <bos@serpentine.com>
parents:
108
diff
changeset
|
173 |
781 | 174 %The revlog provides efficient storage of revisions using a |
175 %\emph{delta} mechanism. Instead of storing a complete copy of a file | |
176 %for each revision, it stores the changes needed to transform an older | |
177 %revision into the new revision. For many kinds of file data, these | |
178 %deltas are typically a fraction of a percent of the size of a full | |
179 %copy of a file. | |
180 | |
181 revlog$B$O(B\emph{delta}$B5!9=$r;H$C$F%j%S%8%g%s$N8zN(E*$J5-21$rDs6!$9$k!%%U%!(B | |
182 $B%$%k$N3F!9$N%P!<%8%g%s$N40A4$J%3%T!<$rJ]B8$9$k$N$G$O$J$/!$8E$$%j%S%8%g%s(B | |
183 $B$r?7$7$$%P!<%8%g%s$XJQ49$9$k$N$KI,MW$JJQ99$rJ]B8$9$k!%B?$/$N%U%!%$%k%G!<(B | |
184 $B%?$KBP$7$F!$(B delta$B$OE57?E*$K$O%U%!%$%k$N%U%k%3%T!<$N(B1$B%Q!<%;%s%HL$K~$G$"$"(B | |
185 $B$k!%(B | |
109
1b67dc96f27a
Snapshot of concepts chapter.
Bryan O'Sullivan <bos@serpentine.com>
parents:
108
diff
changeset
|
186 |
781 | 187 %Some obsolete revision control systems can only work with deltas of |
188 %text files. They must either store binary files as complete snapshots | |
189 %or encoded into a text representation, both of which are wasteful | |
190 %approaches. Mercurial can efficiently handle deltas of files with | |
191 %arbitrary binary contents; it doesn't need to treat text as special. | |
109
1b67dc96f27a
Snapshot of concepts chapter.
Bryan O'Sullivan <bos@serpentine.com>
parents:
108
diff
changeset
|
192 |
781 | 193 $B8E$$%j%S%8%g%s%3%s%H%m!<%k%7%9%F%`$N$$$/$D$+$O%F%-%9%H%U%!%$%k$N(Bdelta$B$KBP(B |
194 $B$7$F$7$+5!G=$7$J$$!%$=$l$i$N%7%9%F%`$G$O%P%$%J%j%U%!%$%k$O40A4$J%9%J%C%W(B | |
195 $B%7%g%C%H$+!$%F%-%9%HI=8=$K%(%s%3!<%I$5$l$?7A<0$G$"$kI,MW$,$"$k!%$3$l$i$O(B | |
196 $B6&$KL5BL$NB?$$%"%W%m!<%A$G$"$k!%(B Mercurial$B$OG$0U$N%P%$%J%j%U%!%$%k$K$D$$(B | |
197 $B$F!$(Bdelta$B$r8zN(E*$K07$&$3$H$,$G$-!$%F%-%9%H$rFCJL07$$$9$kI,MW$,$J$$!%(B | |
198 | |
199 %\subsection{Safe operation} | |
200 \subsection{$B0BA4$JF0:n(B} | |
121
9094c9fda8ec
Start chapter on error recovery.
Bryan O'Sullivan <bos@serpentine.com>
parents:
116
diff
changeset
|
201 \label{sec:concepts:txn} |
109
1b67dc96f27a
Snapshot of concepts chapter.
Bryan O'Sullivan <bos@serpentine.com>
parents:
108
diff
changeset
|
202 |
781 | 203 %Mercurial only ever \emph{appends} data to the end of a revlog file. |
204 %It never modifies a section of a file after it has written it. This | |
205 %is both more robust and efficient than schemes that need to modify or | |
206 %rewrite data. | |
207 | |
208 Mercurial$B$O(Brevlog$B%U%!%$%k$NKvHx$K%G!<%?$N(B\emph{$BDI2C(B}$B$N$_$r9T$&!%0lEY=q$-(B | |
209 $B9~$^$l$?ItJ,$O8e$K$J$C$FJQ99$5$l$k$3$H$O$J$$!%$3$l$O%G!<%?$NJQ99$d:F=q$-(B | |
210 $B9~$_$r9T$&J}K!$h$j$b4h6/$+$D8zN(E*$G$"$k!%(B | |
109
1b67dc96f27a
Snapshot of concepts chapter.
Bryan O'Sullivan <bos@serpentine.com>
parents:
108
diff
changeset
|
211 |
781 | 212 %In addition, Mercurial treats every write as part of a |
213 %\emph{transaction} that can span a number of files. A transaction is | |
214 %\emph{atomic}: either the entire transaction succeeds and its effects | |
215 %are all visible to readers in one go, or the whole thing is undone. | |
216 %This guarantee of atomicity means that if you're running two copies of | |
217 %Mercurial, where one is reading data and one is writing it, the reader | |
218 %will never see a partially written result that might confuse it. | |
219 | |
220 $B2C$($F!$(BMercurial$B$O$"$i$f$k=q$-9~$_$rJ#?t$N%U%!%$%k$X$N(B\emph{$B%H%i%s%6%/%7%g(B | |
221 $B%s(B}$B$N0lIt$H8+$J$9!%%H%i%s%6%/%7%g%sA4BN$,@.8y$7!$FI$_=P$7B&$K0lEY$K7k2L$,(B | |
222 $B8+$($k>l9g$b!$$=$&$G$J$$>l9g$b%H%i%s%6%/%7%g%s$O(B\emph{$B%"%H%_%C%/(B}$B$G$"$k!%(B | |
223 $B$3$N%"%H%_%C%/@-$NJ]>Z$O!$(B 2$B$D$N(BMercurial$B$r!$JRJ}$O%G!<%?$NFI$_=P$7!$$b$&(B | |
224 $B0lJ}$O=q$-9~$_$G<B9T$7$F$$$k>l9g!$FI$_=P$7B&$K$O:.Mp$N860x$H$J$kItJ,E*$J(B | |
225 $B=q$-9~$_7k2L$O8+$($J$$$3$H$r0UL#$9$k!%(B | |
109
1b67dc96f27a
Snapshot of concepts chapter.
Bryan O'Sullivan <bos@serpentine.com>
parents:
108
diff
changeset
|
226 |
781 | 227 %The fact that Mercurial only appends to files makes it easier to |
228 %provide this transactional guarantee. The easier it is to do stuff | |
229 %like this, the more confident you should be that it's done correctly. | |
109
1b67dc96f27a
Snapshot of concepts chapter.
Bryan O'Sullivan <bos@serpentine.com>
parents:
108
diff
changeset
|
230 |
781 | 231 Mercurial$B$O%U%!%$%k$KDI5-$N$_$r$9$k$3$H$G!$%H%i%s%6%/%7%g%s$NJ]>Z$rMF0W$K(B |
232 $B$7$F$$$k!%J*;v$rC1=c2=$9$k$3$H$K$h$C$F!$=hM}$N@5$7$5$r3N<B$K$9$k$h$&$K$7(B | |
233 $B$F$$$k!%(B | |
234 | |
235 %\subsection{Fast retrieval} | |
236 \subsection{$B9bB.$J<hF@(B} | |
109
1b67dc96f27a
Snapshot of concepts chapter.
Bryan O'Sullivan <bos@serpentine.com>
parents:
108
diff
changeset
|
237 |
781 | 238 %Mercurial cleverly avoids a pitfall common to all earlier |
239 %revision control systems: the problem of \emph{inefficient retrieval}. | |
240 %Most revision control systems store the contents of a revision as an | |
241 %incremental series of modifications against a ``snapshot''. To | |
242 %reconstruct a specific revision, you must first read the snapshot, and | |
243 %then every one of the revisions between the snapshot and your target | |
244 %revision. The more history that a file accumulates, the more | |
245 %revisions you must read, hence the longer it takes to reconstruct a | |
246 %particular revision. | |
247 | |
248 Mercurial$B$O$3$l$^$G$N%j%S%8%g%s%3%s%H%m!<%k%7%9%F%`$K6&DL$7$?Mn$H$77j$r(B | |
249 $B8-L@$KHr$1$F$$$k!%LdBj$@$C$?$N$O(B\emph{$BHs8zN(E*$J<hF@(B}$B$G$"$C$?!%(B | |
250 $BBgDq$N%j%S%8%g%s%3%s%H%m!<%k%7%9%F%`$O%j%S%8%g%s$NFbMF$r%9%J%C%W%7%g%C%H(B | |
251 $B$X$N0lO"$NJQ99$NA}J,$H$7$FJ]B8$7$F$$$k!%FCDj$N%j%S%8%g%s$r:F8=$9$k$?$a$K(B | |
252 $B$O$^$:%9%J%C%W%7%g%C%H$rFI$_9~$_!$$7$+$k8e$KL\E*$N%j%S%8%g%s$rFI$`I,MW$,(B | |
253 $B$"$C$?!%%U%!%$%k$X$NMzNr$,A}$($l$PA}$($k$[$IFI$_9~$^$J$1$l$P$J$i$J$$%j%S(B | |
254 $B%8%g%s$,B?$/$J$j!$FCDj$N%j%S%8%g%s$r:F8=$9$k$N$K;~4V$,$+$+$k$h$&$K$J$k!%(B | |
109
1b67dc96f27a
Snapshot of concepts chapter.
Bryan O'Sullivan <bos@serpentine.com>
parents:
108
diff
changeset
|
255 |
110 | 256 \begin{figure}[ht] |
257 \centering | |
294 | 258 \includegraphics{snapshot} |
781 | 259 % \caption{Snapshot of a revlog, with incremental deltas} |
260 \caption{$B:9J,$rMQ$$$?(Brevlog$B$N%9%J%C%W%7%g%C%H(B} | |
110 | 261 \label{fig:concepts:snapshot} |
262 \end{figure} | |
263 | |
781 | 264 %The innovation that Mercurial applies to this problem is simple but |
265 %effective. Once the cumulative amount of delta information stored | |
266 %since the last snapshot exceeds a fixed threshold, it stores a new | |
267 %snapshot (compressed, of course), instead of another delta. This | |
268 %makes it possible to reconstruct \emph{any} revision of a file | |
269 %quickly. This approach works so well that it has since been copied by | |
270 %several other revision control systems. | |
110 | 271 |
781 | 272 Mercurial$B$G$O$3$NLdBj$rC1=c$@$,8z2LE*$JJ}K!$G2r7h$7$F$$$k!%A02s$K%9%J%C%W(B |
273 $B%7%g%C%H$r:n@.$7$?;~E@$+$i$NN_@QE*$JA}J,$,0lDj$NogCM$r1[$($k$H!$?7$?$JA}(B | |
274 $BJ,$G$O$J$/!$?7$?$J%9%J%C%W%7%g%C%H$,J]B8$5$l$k!J$3$N%9%J%C%W%7%g%C%H$OL^(B | |
275 $BO@05=L$5$l$F$$$k!K!%$3$l$K$h$C$F(B\emph{$B$$$+$J$k(B}$B%j%S%8%g%s$b?WB.$K:F8=$5$l(B | |
276 $B$k!%$3$N%"%W%m!<%A$O0J8eB>$N%j%S%8%g%s%3%s%H%m!<%k%7%9%F%`$K%3%T!<$5$l$k(B | |
277 $B$[$I$&$^$/5!G=$7$F$$$k!%(B | |
109
1b67dc96f27a
Snapshot of concepts chapter.
Bryan O'Sullivan <bos@serpentine.com>
parents:
108
diff
changeset
|
278 |
781 | 279 %Figure~\ref{fig:concepts:snapshot} illustrates the idea. In an entry |
280 %in a revlog's index file, Mercurial stores the range of entries from | |
281 %the data file that it must read to reconstruct a particular revision. | |
109
1b67dc96f27a
Snapshot of concepts chapter.
Bryan O'Sullivan <bos@serpentine.com>
parents:
108
diff
changeset
|
282 |
781 | 283 $B?^(B~\ref{fig:concepts:snapshot}$B$K35G0$r<($9!%(BMercurial$B$O(Brevlog$B$N%$%s%G%C%/(B |
284 $B%9%U%!%$%k$N%(%s%H%j$KFCDj$N%j%S%8%g%s$r:F8=$9$k$N$KI,MW$J%G!<%?%U%!%$%k(B | |
285 $BFb$N$"$kHO0O$N%(%s%H%j$rJ]B8$9$k!%(B | |
286 | |
287 %\subsubsection{Aside: the influence of video compression} | |
288 \subsubsection{$B$=$NB>(B: $B%S%G%*05=L$N1F6A(B} | |
109
1b67dc96f27a
Snapshot of concepts chapter.
Bryan O'Sullivan <bos@serpentine.com>
parents:
108
diff
changeset
|
289 |
781 | 290 %If you're familiar with video compression or have ever watched a TV |
291 %feed through a digital cable or satellite service, you may know that | |
292 %most video compression schemes store each frame of video as a delta | |
293 %against its predecessor frame. In addition, these schemes use | |
294 %``lossy'' compression techniques to increase the compression ratio, so | |
295 %visual errors accumulate over the course of a number of inter-frame | |
296 %deltas. | |
112 | 297 |
782 | 298 $B%S%G%*05=L$K47$l$F$$$?$j!$%G%8%?%k$K$h$k%1!<%V%k$^$?$O1R@1J|Aw$K47$l$F$$(B |
299 $B$k$N$J$i!$BgItJ,$N%S%G%*05=L$N;EAH$_$G$O!$%S%G%*$N3F%U%l!<%`$,!$A0$N%U%l!<(B | |
300 $B%`$H$N:9J,$H$7$FJ]B8$5$l$F$$$k$3$H$rCN$C$F$$$k$@$m$&!%2C$($F!$$3$l$i$N;E(B | |
301 $BAH$_$O05=LN($r2T$0$?$a$KIT2D5U$J05=L5;=Q$r;H$C$F$*$j!$1GA|$N%(%i!<$O%U%l!<(B | |
302 $B%`4V$N:9J,$,A}$($k$K=>$C$FC_@Q$7$F$$$/!%(B | |
303 | |
781 | 304 %Because it's possible for a video stream to ``drop out'' occasionally |
305 %due to signal glitches, and to limit the accumulation of artefacts | |
306 %introduced by the lossy compression process, video encoders | |
307 %periodically insert a complete frame (called a ``key frame'') into the | |
308 %video stream; the next delta is generated against that frame. This | |
309 %means that if the video signal gets interrupted, it will resume once | |
310 %the next key frame is received. Also, the accumulation of encoding | |
311 %errors restarts anew with each key frame. | |
312 | |
782 | 313 $B%S%G%*%9%H%j!<%`$G$O!$?.9f$NIT6q9g$K$h$C$F;~@^%I%m%C%W%"%&%H$,=P$k$3$H$,(B |
314 $B$"$j!$$^$?IT2D5U05=L$K$h$k1F6A$NC_@Q$rM^$($k$?$a!$%S%G%*%(%s%3!<%@$ODj4|(B | |
315 $BE*$K!J%-!<%U%l!<%`$H8F$P$l$k!K40A4$J%U%l!<%`$r%9%H%j!<%`$KA^F~$9$k!%<!$N(B | |
316 $B:9J,$O$3$N%U%l!<%`$KBP$7$F<h$i$l$k!%$3$l$K$h$C$F!$%S%G%*?.9f$,ES@d$($F$b(B | |
317 $B<!$N%-!<%U%l!<%`$r<u?.$9$l$P@5>o$KLa$k$3$H$,$G$-$k!%$^$?%(%s%3!<%I%(%i!<(B | |
318 $B$NC_@Q$O%-!<%U%l!<%`$4$H$K=|5n$5$l$k!%(B | |
319 | |
781 | 320 %\subsection{Identification and strong integrity} |
321 \subsection{$B<1JL$H6/$$0l4S@-(B} | |
110 | 322 |
781 | 323 %Along with delta or snapshot information, a revlog entry contains a |
324 %cryptographic hash of the data that it represents. This makes it | |
325 %difficult to forge the contents of a revision, and easy to detect | |
326 %accidental corruption. | |
110 | 327 |
782 | 328 $B:9J,$d%9%J%C%W%7%g%C%H>pJs$H6&$K!$(Brevlog$B%(%s%H%j$O%G!<%?$N0E9f%O%C%7%e(B |
329 $B$r;}$D!%%O%C%7%e$K$h$j!$%j%S%8%g%s$NFbMF$r56$k$3$H$,:$Fq$K$J$j!$$^$?(B | |
330 $B;v8N$K$h$C$FFbMF$,GKB;$7$?>l9g!$H/8+$,MF0W$K$J$k!%(B | |
331 | |
781 | 332 %Hashes provide more than a mere check against corruption; they are |
333 %used as the identifiers for revisions. The changeset identification | |
334 %hashes that you see as an end user are from revisions of the | |
335 %changelog. Although filelogs and the manifest also use hashes, | |
336 %Mercurial only uses these behind the scenes. | |
337 | |
782 | 338 $B%O%C%7%e$OC1$KGKB;$r%A%'%C%/$9$k0J>e$N$3$H$r9T$&!%$3$l$i$O%j%S%8%g%s$N<1(B |
339 $BJL$K$bMQ$$$i$l$k!%%A%'%s%8%;%C%H$N<1JL%O%C%7%e$O!$%(%s%I%f!<%6$+$i$O%A%'(B | |
340 $B%s%8%m%0$G%f!<%6L>$H6&$K8=$l$k?t;z$H$7$FL\$K$9$k$3$H$,B?$$$@$m$&!%(B | |
341 $B%U%!%$%k%m%0$H%^%K%U%'%9%H$G$b%O%C%7%e$O;H$o$l$F$$$k$,!$(BMercurial$B$O$3$l(B | |
342 $B$i$rGX8e$G$N$_MQ$$$k!%(B | |
343 | |
781 | 344 %Mercurial verifies that hashes are correct when it retrieves file |
345 %revisions and when it pulls changes from another repository. If it | |
346 %encounters an integrity problem, it will complain and stop whatever | |
347 %it's doing. | |
110 | 348 |
782 | 349 Mercurial$B$O%U%!%$%k$N%j%S%8%g%s<hF@;~$HJQ99$rJL$N%j%]%8%H%j$+$i(Bpull$B$9$k;~(B |
350 $B$K%O%C%7%e$,@5$7$$$3$H$r3NG'$9$k!%0l4S@-$KLdBj$,$"$k$H!$%(%i!<%a%C%;!<%8(B | |
351 $B$r=PNO$7!$F0:n$rDd;_$9$k!%(B | |
352 | |
781 | 353 %In addition to the effect it has on retrieval efficiency, Mercurial's |
354 %use of periodic snapshots makes it more robust against partial data | |
355 %corruption. If a revlog becomes partly corrupted due to a hardware | |
356 %error or system bug, it's often possible to reconstruct some or most | |
357 %revisions from the uncorrupted sections of the revlog, both before and | |
358 %after the corrupted section. This would not be possible with a | |
359 %delta-only storage model. | |
115
b74102b56df5
Wow! Lots more work detailing the working directory, merging, etc.
Bryan O'Sullivan <bos@serpentine.com>
parents:
113
diff
changeset
|
360 |
782 | 361 $B<hF@$N8zN($K2C$($F!$(BMercurial$B$O<~4|E*$K%9%J%C%W%7%g%C%H$r;H$&$3$H$G!$ItJ,(B |
362 $BE*$J%G!<%?$NGKB;$KBP$7$F4h6/$K$J$C$F$$$k!%%O!<%I%&%'%"$NLdBj$d%7%9%F%`$N(B | |
363 $B%P%0$G(Brevlog$B$,ItJ,E*$KGKB;$7$?>l9g$G$b!$B?$/$N>l9g!$(Brevlog$B$NGKB;$7$F$$$J(B | |
364 $B$$ItJ,$+$iGKB;$7$?ItJ,$NA08e$G$$$/$D$+$N%j%S%8%g%s$dBgH>$N%j%S%8%g%s$r:F(B | |
365 $B7z$9$k$3$H$,$G$-$k!%:9J,$N$_$r5-O?$9$k%7%9%F%`$G$O$3$l$r<B8=$9$k$3$H$O$G(B | |
366 $B$-$J$$!%(B | |
367 | |
781 | 368 %\section{Revision history, branching, and merging} |
369 \section{$B%j%S%8%g%sMzNr!$%V%i%s%A!$%^!<%8(B} | |
115
b74102b56df5
Wow! Lots more work detailing the working directory, merging, etc.
Bryan O'Sullivan <bos@serpentine.com>
parents:
113
diff
changeset
|
370 |
781 | 371 %Every entry in a Mercurial revlog knows the identity of its immediate |
372 %ancestor revision, usually referred to as its \emph{parent}. In fact, | |
373 %a revision contains room for not one parent, but two. Mercurial uses | |
374 %a special hash, called the ``null ID'', to represent the idea ``there | |
375 %is no parent here''. This hash is simply a string of zeroes. | |
115
b74102b56df5
Wow! Lots more work detailing the working directory, merging, etc.
Bryan O'Sullivan <bos@serpentine.com>
parents:
113
diff
changeset
|
376 |
782 | 377 Mercurial revlog$B$N$9$Y$F$N%(%s%H%j$O!$DL>o(B\emph{parent}$B$H$7$F;2>H$5$l$kD>(B |
378 $B@\$NAD@h$N%j%S%8%g%s$rCN$C$F$$$k!%<B:]$K$O!$%j%S%8%g%s$O(B1$B$D$@$1$G$J$/(B2$B$D(B | |
379 $B$N?F$r5-O?$9$k$3$H$,$G$-$k!%(BMercurial$B$O(B``null ID''$B$H$$$&FCJL$J%O%C%7%e$r(B | |
380 $B;H$C$F(B``$B$3$3$K$O?F$K$J$k%j%S%8%g%s$,$J$$(B''$B$H$$$&$3$H$rI=8=$9$k!%$3$N%O%C(B | |
381 $B%7%e$OC1$K%<%m$rJB$Y$?J8;zNs$G$"$k!%(B | |
382 | |
781 | 383 %In figure~\ref{fig:concepts:revlog}, you can see an example of the |
384 %conceptual structure of a revlog. Filelogs, manifests, and changelogs | |
385 %all have this same structure; they differ only in the kind of data | |
386 %stored in each delta or snapshot. | |
387 | |
782 | 388 revlog$B$N35G0E*$J9=B$$N0lNc$r?^(B~\ref{fig:concepts:revlog}$B$K<($9!%%U%!%$%k(B |
389 $B%m%0!$%^%K%U%'%9%H$*$h$S%A%'%s%8%m%0$O$9$Y$FF1$89=B$$r;}$D!%$3$l$i$N0c$$(B | |
390 $B$O!$3F!9$N:9J,$d%9%J%C%W%7%g%C%H$K3JG<$9$k%G!<%?$N0c$$$@$1$G$"$k!%(B | |
391 | |
781 | 392 %The first revision in a revlog (at the bottom of the image) has the |
393 %null ID in both of its parent slots. For a ``normal'' revision, its | |
394 %first parent slot contains the ID of its parent revision, and its | |
395 %second contains the null ID, indicating that the revision has only one | |
396 %real parent. Any two revisions that have the same parent ID are | |
397 %branches. A revision that represents a merge between branches has two | |
398 %normal revision IDs in its parent slots. | |
115
b74102b56df5
Wow! Lots more work detailing the working directory, merging, etc.
Bryan O'Sullivan <bos@serpentine.com>
parents:
113
diff
changeset
|
399 |
782 | 400 revlog$B$G$N:G=i$N%j%S%8%g%s!J?^$N0lHV2<!K$O(Bnull ID$B$rN>?F$r<($9%9%m%C%H$N(B |
401 $BN>J}$K;}$A!$$3$N%j%S%8%g%s$,<B:]$K$O$?$@0l$D$N?F$7$+;}$?$J$$$3$H$rI=$7$F(B | |
402 $B$$$k!%F1$8?F$N(BID$B$r;}$DG$0U$N(B2$B$D$N%j%S%8%g%s$O%V%i%s%A$G$"$k!%(B | |
403 $B%V%i%s%A4V$N%^!<%8$rI=$9%j%S%8%g%s$O!$(B2$B$D$N%N!<%^%k%j%S%8%g%s(BID$B$rN>?F$N(B | |
404 $B%9%m%C%H$K;}$D!%(B | |
405 | |
115
b74102b56df5
Wow! Lots more work detailing the working directory, merging, etc.
Bryan O'Sullivan <bos@serpentine.com>
parents:
113
diff
changeset
|
406 \begin{figure}[ht] |
b74102b56df5
Wow! Lots more work detailing the working directory, merging, etc.
Bryan O'Sullivan <bos@serpentine.com>
parents:
113
diff
changeset
|
407 \centering |
294 | 408 \includegraphics{revlog} |
115
b74102b56df5
Wow! Lots more work detailing the working directory, merging, etc.
Bryan O'Sullivan <bos@serpentine.com>
parents:
113
diff
changeset
|
409 \caption{} |
b74102b56df5
Wow! Lots more work detailing the working directory, merging, etc.
Bryan O'Sullivan <bos@serpentine.com>
parents:
113
diff
changeset
|
410 \label{fig:concepts:revlog} |
b74102b56df5
Wow! Lots more work detailing the working directory, merging, etc.
Bryan O'Sullivan <bos@serpentine.com>
parents:
113
diff
changeset
|
411 \end{figure} |
b74102b56df5
Wow! Lots more work detailing the working directory, merging, etc.
Bryan O'Sullivan <bos@serpentine.com>
parents:
113
diff
changeset
|
412 |
781 | 413 %\section{The working directory} |
414 \section{$B%o!<%-%s%0%G%#%l%/%H%j(B} | |
110 | 415 |
781 | 416 %In the working directory, Mercurial stores a snapshot of the files |
417 %from the repository as of a particular changeset. | |
113
a0f57b3e677e
More concepts, this time working directory stuff.
Bryan O'Sullivan <bos@serpentine.com>
parents:
112
diff
changeset
|
418 |
782 | 419 Mercurial$B$O%j%]%8%H%j$N$"$kFCDj$N%A%'%s%8%;%C%H$N%U%!%$%k%9%J%C%W%7%g%C%H(B |
420 $B$r%o!<%-%s%0%G%#%l%/%H%jFb$K;}$D!%(B | |
421 | |
781 | 422 %The working directory ``knows'' which changeset it contains. When you |
423 %update the working directory to contain a particular changeset, | |
424 %Mercurial looks up the appropriate revision of the manifest to find | |
425 %out which files it was tracking at the time that changeset was | |
426 %committed, and which revision of each file was then current. It then | |
427 %recreates a copy of each of those files, with the same contents it had | |
428 %when the changeset was committed. | |
113
a0f57b3e677e
More concepts, this time working directory stuff.
Bryan O'Sullivan <bos@serpentine.com>
parents:
112
diff
changeset
|
429 |
782 | 430 $B%o!<%-%s%0%G%#%l%/%H%j$,$I$N%A%'%s%8%;%C%H$K99?7$5$l$F$$$k$,$"$k$N$+$O4{(B |
431 $BCN$G$"$k!%%o!<%-%s%0%G%#%l%/%H%j$,FCDj$N%A%'%s%8%;%C%H$K$J$k$h$&$K99?7$9(B | |
432 $B$k:]!$(B Mercurial$B$OE,@Z$J%j%S%8%g%s$N%^%K%U%'%9%H$r8!:w$7!$$=$N%A%'%s%8%;%C(B | |
433 $B%H$,%3%_%C%H$5$l$?;~E@$G$I$N%U%!%$%k$,DI@W$5$l$F$$$k$+$rD4$Y!$3F!9$N%U%!(B | |
434 $B%$%k$N%j%S%8%g%s$rFCDj$9$k!%$=$7$F%A%'%s%8%;%C%H$,%3%_%C%H$5$l$?;~E@$NFb(B | |
435 $BMF$r$b$D%U%!%$%k$N%3%T!<$r:n@.$9$k!%(B | |
436 | |
781 | 437 %The \emph{dirstate} contains Mercurial's knowledge of the working |
438 %directory. This details which changeset the working directory is | |
439 %updated to, and all of the files that Mercurial is tracking in the | |
440 %working directory. | |
113
a0f57b3e677e
More concepts, this time working directory stuff.
Bryan O'Sullivan <bos@serpentine.com>
parents:
112
diff
changeset
|
441 |
782 | 442 \emph{dirstate}$B$K$O%o!<%-%s%0%G%#%l%/%H%j$K$D$$$F(BMercurial$B$,GD0.$7$F$$$k(B |
443 $B>pJs$,3JG<$5$l$F$$$k!%$=$NFbMF$O%o!<%-%s%0%G%#%l%/%H%j$,%"%C%W%G!<%H$5$l(B | |
444 $B$F$$$k%A%'%s%8%;%C%H$*$h$S%o!<%-%s%0%G%#%l%/%H%jFb$G(BMercurial$B$,DI@W$7$F$$(B | |
445 $B$kA4$F$N%U%!%$%k$K$D$$$F$N>\:Y$G$"$k!%(B | |
446 | |
781 | 447 %Just as a revision of a revlog has room for two parents, so that it |
448 %can represent either a normal revision (with one parent) or a merge of | |
449 %two earlier revisions, the dirstate has slots for two parents. When | |
450 %you use the \hgcmd{update} command, the changeset that you update to | |
451 %is stored in the ``first parent'' slot, and the null ID in the second. | |
452 %When you \hgcmd{merge} with another changeset, the first parent | |
453 %remains unchanged, and the second parent is filled in with the | |
454 %changeset you're merging with. The \hgcmd{parents} command tells you | |
455 %what the parents of the dirstate are. | |
113
a0f57b3e677e
More concepts, this time working directory stuff.
Bryan O'Sullivan <bos@serpentine.com>
parents:
112
diff
changeset
|
456 |
782 | 457 revlog$B$K$*$1$k%j%S%8%g%s$,(B2$B$D$N?F$N>pJs$r3JG<$9$kNN0h$r;}$A!$DL>o$N%j%S%8%g(B |
458 $B%s!J?F$O(B1$B$D!K$^$?$O(B2$B$D$N?F$N%^!<%8$rI=8=$G$-$k$N$HF1MM$K(Bdirstate$B$b(B2$B$D$N?F(B | |
459 $B$N$?$a$N%9%m%C%H$r;}$C$F$$$k!%(B\hgcmd{update}$B%3%^%s%I$r<B9T$9$k$H!$%"%C%W(B | |
460 $B%G!<%H@h$N%A%'%s%8%;%C%H$,(B1$B$DL\$N?F$N%9%m%C%H$K5-O?$5$l!$(Bnull ID$B$,(B2$B$DL\$N(B | |
461 $B?F$N%9%m%C%H$K5-O?$5$l$k!%B>$N%A%'%s%8%;%C%H$H(B\hgcmd{merge}$B$r9T$&$H!$:G=i(B | |
462 $B$N?F$O$=$N$^$^$K!$(B2$BHVL\$N?F$O%^!<%8$9$k%A%'%s%8%;%C%H$H$J(B | |
463 $B$k!%(B\hgcmd{parents}$B%3%^%s%I$G(Bdirstate$B$NN>?F$rCN$k$3$H$,$G$-$k!%(B | |
464 | |
781 | 465 %\subsection{What happens when you commit} |
466 \subsection{$B%3%_%C%H;~$K2?$,5/$-$k$N$+(B} | |
113
a0f57b3e677e
More concepts, this time working directory stuff.
Bryan O'Sullivan <bos@serpentine.com>
parents:
112
diff
changeset
|
467 |
781 | 468 %The dirstate stores parent information for more than just book-keeping |
469 %purposes. Mercurial uses the parents of the dirstate as \emph{the | |
470 % parents of a new changeset} when you perform a commit. | |
113
a0f57b3e677e
More concepts, this time working directory stuff.
Bryan O'Sullivan <bos@serpentine.com>
parents:
112
diff
changeset
|
471 |
782 | 472 dirstate$B$O4IM}L\E*0U30$N>pJs$bJ]B8$7$F$$$k!%(B Mercurial$B$O!$%3%_%C%H$N:]$K(B |
473 dirstate$B$NN>?F$r(B\emph{$B?7$?$J%A%'%s%8%;%C%H$NN>?F(B}$B$H$7$FMQ$$$k!%(B | |
474 | |
113
a0f57b3e677e
More concepts, this time working directory stuff.
Bryan O'Sullivan <bos@serpentine.com>
parents:
112
diff
changeset
|
475 \begin{figure}[ht] |
a0f57b3e677e
More concepts, this time working directory stuff.
Bryan O'Sullivan <bos@serpentine.com>
parents:
112
diff
changeset
|
476 \centering |
294 | 477 \includegraphics{wdir} |
781 | 478 % \caption{The working directory can have two parents} |
479 \caption{$B%o!<%-%s%0%G%#%l%/%H%j$O(B2$B$D$N?F$r;}$AF@$k(B} | |
113
a0f57b3e677e
More concepts, this time working directory stuff.
Bryan O'Sullivan <bos@serpentine.com>
parents:
112
diff
changeset
|
480 \label{fig:concepts:wdir} |
a0f57b3e677e
More concepts, this time working directory stuff.
Bryan O'Sullivan <bos@serpentine.com>
parents:
112
diff
changeset
|
481 \end{figure} |
a0f57b3e677e
More concepts, this time working directory stuff.
Bryan O'Sullivan <bos@serpentine.com>
parents:
112
diff
changeset
|
482 |
781 | 483 %Figure~\ref{fig:concepts:wdir} shows the normal state of the working |
484 %directory, where it has a single changeset as parent. That changeset | |
485 %is the \emph{tip}, the newest changeset in the repository that has no | |
486 %children. | |
113
a0f57b3e677e
More concepts, this time working directory stuff.
Bryan O'Sullivan <bos@serpentine.com>
parents:
112
diff
changeset
|
487 |
782 | 488 $B?^(B~\ref{fig:concepts:wdir}$B$K%o!<%-%s%0%G%#%l%/%H%j$NDL>o>uBV$r<($9!%(B |
489 $B%j%]%8%H%j$N:G?7$N%A%'%s%8%;%C%H$O(B\emph{tip}$B$G!$;R$r0l@Z;}$?$J$$!%(B | |
490 | |
113
a0f57b3e677e
More concepts, this time working directory stuff.
Bryan O'Sullivan <bos@serpentine.com>
parents:
112
diff
changeset
|
491 \begin{figure}[ht] |
a0f57b3e677e
More concepts, this time working directory stuff.
Bryan O'Sullivan <bos@serpentine.com>
parents:
112
diff
changeset
|
492 \centering |
294 | 493 \includegraphics{wdir-after-commit} |
781 | 494 % \caption{The working directory gains new parents after a commit} |
495 \caption{$B%3%_%C%H8e!$%o!<%-%s%0%G%#%l%/%H%j$O?7$?$JN>?F$r;}$D(B} | |
113
a0f57b3e677e
More concepts, this time working directory stuff.
Bryan O'Sullivan <bos@serpentine.com>
parents:
112
diff
changeset
|
496 \label{fig:concepts:wdir-after-commit} |
a0f57b3e677e
More concepts, this time working directory stuff.
Bryan O'Sullivan <bos@serpentine.com>
parents:
112
diff
changeset
|
497 \end{figure} |
a0f57b3e677e
More concepts, this time working directory stuff.
Bryan O'Sullivan <bos@serpentine.com>
parents:
112
diff
changeset
|
498 |
781 | 499 %It's useful to think of the working directory as ``the changeset I'm |
500 %about to commit''. Any files that you tell Mercurial that you've | |
501 %added, removed, renamed, or copied will be reflected in that | |
502 %changeset, as will modifications to any files that Mercurial is | |
503 %already tracking; the new changeset will have the parents of the | |
504 %working directory as its parents. | |
113
a0f57b3e677e
More concepts, this time working directory stuff.
Bryan O'Sullivan <bos@serpentine.com>
parents:
112
diff
changeset
|
505 |
782 | 506 $B%o!<%-%s%0%G%#%l%/%H%j$,(B``$B%3%_%C%H$7$h$&$H$7$F$$$k%A%'%s%8%;%C%H(B''$B$G$"$k(B |
507 $B$H8+$J$9$3$H$OLr$KN)$D!%DI2C!$:o=|!$%j%M!<%`$^$?$O%3%T!<$7$?%U%!%$%k$r(B | |
508 Mercurial$B$KG'<1$5$;$k$H!$$9$G$K(BMercurial$B$,DI@W$7$F$$$kG$0U$N%U%!%$%k$X$N(B | |
509 $BJQ99$HF1MM!$$9$Y$F%A%'%s%8%;%C%H$KH?1G$5$l$k!%?7$?$J%A%'%s%8%;%C%H$O%o!<(B | |
510 $B%-%s%0%G%#%l%/%H%j$NN>?F$rN>?F$H$7$F;}$D!%(B | |
511 | |
781 | 512 %After a commit, Mercurial will update the parents of the working |
513 %directory, so that the first parent is the ID of the new changeset, | |
514 %and the second is the null ID. This is shown in | |
515 %figure~\ref{fig:concepts:wdir-after-commit}. Mercurial doesn't touch | |
516 %any of the files in the working directory when you commit; it just | |
517 %modifies the dirstate to note its new parents. | |
110 | 518 |
782 | 519 $B%3%_%C%H8e!$(BMercurial$B$O%o!<%-%s%0%G%#%l%/%H%j$NN>?F$r99?7$7!$(B1$B$DL\$N?F$,(B |
520 $B?7$?$J%A%'%s%8%;%C%H$N(BID$B!$(B2$BHVL\$r(Bnull ID$B$K$9$k!%$3$l$r(B | |
521 $B?^(B~\ref{fig:concepts:wdir-after-commit}$B$K<($9!%(BMercurial$B$O%3%_%C%H;~$K%o!<(B | |
522 $B%-%s%0%G%#%l%/%H%jFb$N%U%!%$%k$K$O0l@Z?($l$:!$(Bdirstate$B$K?7$?$JN>?F$r5-O?(B | |
523 $B$9$k!%(B | |
524 | |
781 | 525 %\subsection{Creating a new head} |
526 \subsection{$B?7$?$J%X%C%I$r:n$k(B} | |
113
a0f57b3e677e
More concepts, this time working directory stuff.
Bryan O'Sullivan <bos@serpentine.com>
parents:
112
diff
changeset
|
527 |
781 | 528 %It's perfectly normal to update the working directory to a changeset |
529 %other than the current tip. For example, you might want to know what | |
530 %your project looked like last Tuesday, or you could be looking through | |
531 %changesets to see which one introduced a bug. In cases like this, the | |
532 %natural thing to do is update the working directory to the changeset | |
533 %you're interested in, and then examine the files in the working | |
782 | 534 %directory directly to see their contents as they were when you |
781 | 535 %committed that changeset. The effect of this is shown in |
536 %figure~\ref{fig:concepts:wdir-pre-branch}. | |
112 | 537 |
782 | 538 $B%o!<%-%s%0%G%#%l%/%H%j$r8=:_$N(Btip$B0J30$N%A%'%s%8%;%C%H$K99?7$9$k$3$H$O$$$5(B |
539 $B$5$+$b$*$+$7$J$3$H$G$O$J$$!%Nc$($P!$$3$NA0$N2PMKF|$K%W%m%8%'%/%H$,$I$N$h(B | |
540 $B$&$J>uBV$G$"$C$?$+CN$j$?$$$H;W$&$+$b$7$l$J$$$7!$%A%'%s%8%;%C%H$N$&$A$N$I(B | |
541 $B$l$,%P%0$r:.F~$5$;$?$+FM$-;_$a$?$$$H9M$($k$3$H$,$"$k$+$b$7$l$J$$!%$3$N$h(B | |
542 $B$&$J>l9g!$%o!<%-%s%0%G%#%l%/%H%j$r6=L#$N$"$k%A%'%s%8%;%C%H$K99?7$7!$%A%'(B | |
543 $B%s%8%;%C%H$r%3%_%C%H$7$?;~$K$=$l$i$,$I$N$h$&$G$"$C$?$+$r8+$k$?$a$K%o!<%-(B | |
544 $B%s%0%G%#%l%/%H%jFb$N%U%!%$%k$rD4$Y$k$N$,<+A3$G$"$k!%$3$N1F6A$O(B | |
545 $B?^(B~\ref{fig:concepts:wdir-pre-branch}$B$K<($9!%(B | |
546 | |
115
b74102b56df5
Wow! Lots more work detailing the working directory, merging, etc.
Bryan O'Sullivan <bos@serpentine.com>
parents:
113
diff
changeset
|
547 \begin{figure}[ht] |
b74102b56df5
Wow! Lots more work detailing the working directory, merging, etc.
Bryan O'Sullivan <bos@serpentine.com>
parents:
113
diff
changeset
|
548 \centering |
294 | 549 \includegraphics{wdir-pre-branch} |
781 | 550 % \caption{The working directory, updated to an older changeset} |
551 \caption{$B8E$$%A%'%s%8%;%C%H$X$H99?7$5$l$?%o!<%-%s%0%G%#%l%/%H%j(B} | |
115
b74102b56df5
Wow! Lots more work detailing the working directory, merging, etc.
Bryan O'Sullivan <bos@serpentine.com>
parents:
113
diff
changeset
|
552 \label{fig:concepts:wdir-pre-branch} |
b74102b56df5
Wow! Lots more work detailing the working directory, merging, etc.
Bryan O'Sullivan <bos@serpentine.com>
parents:
113
diff
changeset
|
553 \end{figure} |
112 | 554 |
781 | 555 %Having updated the working directory to an older changeset, what |
556 %happens if you make some changes, and then commit? Mercurial behaves | |
557 %in the same way as I outlined above. The parents of the working | |
558 %directory become the parents of the new changeset. This new changeset | |
559 %has no children, so it becomes the new tip. And the repository now | |
560 %contains two changesets that have no children; we call these | |
561 %\emph{heads}. You can see the structure that this creates in | |
562 %figure~\ref{fig:concepts:wdir-branch}. | |
112 | 563 |
782 | 564 $B%o!<%-%s%0%G%#%l%/%H%j$r8E$$%A%'%s%8%;%C%H$K99?7$7!$JQ99$r9T$C$F%3%_%C%H(B |
565 $B$9$k$H2?$,5/$3$k$@$m$&$+!)(B Mercurial$B$OA0=R$N$h$&$K?6Iq$&!%%o!<%-%s%0%G%#(B | |
566 $B%l%/%H%j$NN>?F$O?7$?$J%A%'%s%8%;%C%H$NN>?F$H$J$k!%?7$?$J%A%'%s%8%;%C%H$O(B | |
567 $B;R$r;}$?$:!$=>$C$F?7$?$J(Btip$B$H$J$k!%%j%]%8%H%j$K$O(B\emph{heads}$B$H8F$P$l$k(B2 | |
568 $B$D$N%A%'%s%8%;%C%H$,$G$-$k!%$3$N;~$N9=B$$r(B | |
569 $B?^(B~\ref{fig:concepts:wdir-branch}$B$K<($9!%(B | |
570 | |
112 | 571 \begin{figure}[ht] |
572 \centering | |
294 | 573 \includegraphics{wdir-branch} |
781 | 574 % \caption{After a commit made while synced to an older changeset} |
575 \caption{$B8E$$%A%'%s%8%;%C%H$KF14|Cf$K%3%_%C%H$,9T$o$l$?>l9g(B} | |
115
b74102b56df5
Wow! Lots more work detailing the working directory, merging, etc.
Bryan O'Sullivan <bos@serpentine.com>
parents:
113
diff
changeset
|
576 \label{fig:concepts:wdir-branch} |
b74102b56df5
Wow! Lots more work detailing the working directory, merging, etc.
Bryan O'Sullivan <bos@serpentine.com>
parents:
113
diff
changeset
|
577 \end{figure} |
b74102b56df5
Wow! Lots more work detailing the working directory, merging, etc.
Bryan O'Sullivan <bos@serpentine.com>
parents:
113
diff
changeset
|
578 |
781 | 579 %\begin{note} |
580 % If you're new to Mercurial, you should keep in mind a common | |
581 % ``error'', which is to use the \hgcmd{pull} command without any | |
582 % options. By default, the \hgcmd{pull} command \emph{does not} | |
583 % update the working directory, so you'll bring new changesets into | |
584 % your repository, but the working directory will stay synced at the | |
585 % same changeset as before the pull. If you make some changes and | |
586 % commit afterwards, you'll thus create a new head, because your | |
587 % working directory isn't synced to whatever the current tip is. | |
588 % | |
800 | 589 % I put the word ``error'' in quotes because all that you need to do to |
590 % rectify this situation is \hgcmd{merge}, then \hgcmd{commit}. In other | |
591 % words, this almost never has negative consequences; it's just something | |
592 % of a surprise for newcomers. I'll discuss other ways to avoid this | |
593 % behaviour, and why Mercurial behaves in this initially surprising way, | |
594 % later on. | |
595 | |
781 | 596 %\end{note} |
115
b74102b56df5
Wow! Lots more work detailing the working directory, merging, etc.
Bryan O'Sullivan <bos@serpentine.com>
parents:
113
diff
changeset
|
597 |
782 | 598 \begin{note} |
599 Mercurial$B$r;H$$;O$a$?$P$+$j$G$"$l$P!$$h$/$"$k(B``$B%(%i!<(B''$B$r3P$($F$*$/$H$h(B | |
600 $B$$!%$=$l$O(B\hgcmd{pull}$B%3%^%s%I$r%*%W%7%g%s$J$7$G<B9T$9$k$3$H$G$"$k!%%G%U%)(B | |
601 $B%k%H$G$O(B\hgcmd{pull}$B$O%o!<%-%s%0%G%#%l%/%H%j$N99?7$r(B\emph{$B9T$o$J$$(B}$B!%$=$N(B | |
602 $B$?$a!$%j%]%8%H%j$K$O?7$7$$%A%'%s%8%;%C%H$,E~Ce$7$F$$$k$N$K%o!<%-%s%0%G%#(B | |
800 | 603 $B%l%/%H%j$OA02s(Bpull$B$7$?%A%'%s%8%;%C%H$N$^$^$G$"$k!%$3$3$G2?$i$+$NJQ99$r9T$C(B |
604 $B$F%3%_%C%H$7$h$&$H$9$k$H!$%o!<%-%s%0%G%#%l%/%H%j$,8=:_$N(Btip$B$KF14|$7$F$$$J(B | |
605 $B$$$?$a!$?7$?$J%X%C%I$r:n$k$3$H$K$J$C$F$7$^$&!%(B | |
782 | 606 |
607 ``$B%(%i!<(B''$B$H$$$&8@MU$r0zMQId$G3g$C$?$N$O!$$3$N>uBV$O(B\hgcmd{merge}$B$H(B | |
608 \hgcmd{commit}$B$@$1$G2r>C$G$-$k$+$i$@!%8@$$BX$($k$H!$$3$N>uBV$O$[$H$s$I$N(B | |
800 | 609 $B>l9g32$r$J$9$b$N$G$O$J$J$/!$C1$K=i?4<T$r6C$+$9DxEY$N$b$N$G$"$k!%$3$N?6Iq(B |
782 | 610 $B$rHr$1$kJL$NJ}K!$d!$$J$<(BMercurial$B$,$3$N$h$&$K6C$+$;$k$h$&$JJ}K!$GF0:n$9$k(B |
611 $B$N$+$K$D$$$F$O8e$[$I5DO@$9$k!%(B | |
612 \end{note} | |
613 | |
800 | 614 %\subsection{Merging changes |
615 \subsection{$BJQ99$N%^!<%8(B} | |
115
b74102b56df5
Wow! Lots more work detailing the working directory, merging, etc.
Bryan O'Sullivan <bos@serpentine.com>
parents:
113
diff
changeset
|
616 |
781 | 617 %When you run the \hgcmd{merge} command, Mercurial leaves the first |
618 %parent of the working directory unchanged, and sets the second parent | |
619 %to the changeset you're merging with, as shown in | |
620 %figure~\ref{fig:concepts:wdir-merge}. | |
115
b74102b56df5
Wow! Lots more work detailing the working directory, merging, etc.
Bryan O'Sullivan <bos@serpentine.com>
parents:
113
diff
changeset
|
621 |
782 | 622 \hgcmd{merge}$B%3%^%s%I$r<B9T$7$?;~!$(BMercurial$B$O%o!<%-%s%0%G%#%l%/%H%j$N:G(B |
623 $B=i$N?F$rJQ99$;$:;D$7!$(B2$BHVL\$N?F$r?^(B~\ref{fig:concepts:wdir-merge}$B$N$h$&(B | |
624 $B$K%^!<%8@h$N%A%'%s%8%;%C%H$H$9$k!%(B | |
625 | |
115
b74102b56df5
Wow! Lots more work detailing the working directory, merging, etc.
Bryan O'Sullivan <bos@serpentine.com>
parents:
113
diff
changeset
|
626 \begin{figure}[ht] |
b74102b56df5
Wow! Lots more work detailing the working directory, merging, etc.
Bryan O'Sullivan <bos@serpentine.com>
parents:
113
diff
changeset
|
627 \centering |
294 | 628 \includegraphics{wdir-merge} |
781 | 629 % \caption{Merging two heads} |
630 \caption{2$B$D$N%X%C%I$N%^!<%8(B} | |
115
b74102b56df5
Wow! Lots more work detailing the working directory, merging, etc.
Bryan O'Sullivan <bos@serpentine.com>
parents:
113
diff
changeset
|
631 \label{fig:concepts:wdir-merge} |
112 | 632 \end{figure} |
633 | |
782 | 634 %Mercurial also has to modify the working directory, to merge the files |
635 %managed in the two changesets. Simplified a little, the merging | |
636 %process goes like this, for every file in the manifests of both | |
637 %changesets. | |
638 | |
639 Mercurial$B$O(B2$B$D$N%A%'%s%8%;%C%HFb$G4IM}$5$l$F$$$k%U%!%$%k$r%^!<%8$9$k$?$a(B | |
640 $B$K%o!<%-%s%0%G%#%l%/%H%j$rJQ99$9$kI,MW$,$"$k!%>/$7C1=c2=$9$k$H!$%^!<%8%W(B | |
641 $B%m%;%9$OAPJ}$N%A%'%s%8%;%C%H$N%^%K%U%'%9%HFb$K$"$kA4$F$N%U%!%$%k$KBP$7$F(B | |
642 $B<!$N$h$&$K9T$o$l$k!%(B | |
643 | |
115
b74102b56df5
Wow! Lots more work detailing the working directory, merging, etc.
Bryan O'Sullivan <bos@serpentine.com>
parents:
113
diff
changeset
|
644 \begin{itemize} |
782 | 645 %\item If neither changeset has modified a file, do nothing with that |
646 % file. | |
647 \item $B$I$A$i$N%A%'%s%8%;%C%H$G$bJQ99$5$l$F$$$J$$%U%!%$%k$KBP$7$F$O2?$b(B | |
648 $B9T$o$J$$!%(B | |
649 %\item If one changeset has modified a file, and the other hasn't, | |
650 % create the modified copy of the file in the working directory. | |
651 \item $BJQ99$5$l$?%U%!%$%k$,JRJ}$N%A%'%s%8%;%C%H$K4^$^$l!$$b$&0lJ}$K$O4^(B | |
652 $B$^$l$J$$>l9g!$%o!<%-%s%0%G%#%l%/%H%j$KJQ99$5$l$?%3%T!<$,:n@.$5$l(B | |
653 $B$k!%(B | |
654 %\item If one changeset has removed a file, and the other hasn't (or | |
655 % has also deleted it), delete the file from the working directory. | |
656 \item $B0lJ}$N%A%'%s%8%;%C%H$G:o=|$5$l$?%U%!%$%k$,$"$j!$$b$&0lJ}$,$=$N%U%!(B | |
657 $B%$%k$r4^$^$J$$$+!$F1MM$K:o=|$5$l$F$$$k>l9g$O%o!<%-%s%0%G%#%l%/%H(B | |
658 $B%j$+$i$=$N%U%!%$%k$r:o=|$9$k!%(B | |
659 %\item If one changeset has removed a file, but the other has modified | |
660 % the file, ask the user what to do: keep the modified file, or remove | |
661 % it? | |
662 \item $B0lJ}$N%A%'%s%8%;%C%H$G%U%!%$%k$,:o=|$5$l$F$*$j!$$b$&0lJ}$G$O$=$N(B | |
663 $B%U%!%$%k$,JQ99$5$l$F$$$k>l9g$O!$JQ99$5$l$?%U%!%$%k$r0];}$9$k$+%U%!(B | |
664 $B%$%k$r>C5n$9$k$+$+%f!<%6$K?R$M$k!%(B | |
665 %\item If both changesets have modified a file, invoke an external | |
666 % merge program to choose the new contents for the merged file. This | |
667 % may require input from the user. | |
668 \item $BN>J}$N%A%'%s%8%;%C%H$G%U%!%$%k$,JQ99$5$l$F$$$k>l9g!$%^!<%88e$N%U%!(B | |
669 $B%$%k$NFbMF$rA*Br$9$k$?$a$K30It$N%^!<%8%W%m%0%i%`$r5/F0$9$k!%$3$l(B | |
670 $B$r9T$&$?$a$K$O%f!<%6$NF~NO$,I,MW$G$"$k!%(B | |
671 %\item If one changeset has modified a file, and the other has renamed | |
672 % or copied the file, make sure that the changes follow the new name | |
673 % of the file. | |
674 \item $B0lJ}$N%A%'%s%8%;%C%H$G%U%!%$%k$,JQ99$5$l$F$*$j!$$b$&0lJ}$G$O%U%!(B | |
675 $B%$%k$,%j%M!<%`$^$?$O%3%T!<$5$l$F$$$k>l9g!$JQ99$O?7$7$$L>A0$N%U%!(B | |
676 $B%$%k$K<h$j9~$^$l$k!%(B | |
115
b74102b56df5
Wow! Lots more work detailing the working directory, merging, etc.
Bryan O'Sullivan <bos@serpentine.com>
parents:
113
diff
changeset
|
677 \end{itemize} |
782 | 678 |
679 %There are more details---merging has plenty of corner cases---but | |
680 %these are the most common choices that are involved in a merge. As | |
681 %you can see, most cases are completely automatic, and indeed most | |
682 %merges finish automatically, without requiring your input to resolve | |
683 %any conflicts. | |
684 | |
685 $B>\$7$/=R$Y$l$P%^!<%8$K$O$$$m$$$m$JFC<lNc$,$"$k!%$7$+$7$3$3$G$O:G$bIaDL$N(B | |
686 $BA*Br$K$D$$$F@bL@$9$k!%$3$l$^$G8+$F$-$?$h$&$K!$BgH>$N%1!<%9$O40A4$K<+F0$G(B | |
687 $B$"$j!$<B:]$KBgH>$N%^!<%8$O>WFM$r2r7h$9$k$?$a$KF~NO$r5a$a$k$3$H$J$/<+F0E*(B | |
688 $B$K40N;$9$k!%(B | |
689 | |
690 %When you're thinking about what happens when you commit after a merge, | |
691 %once again the working directory is ``the changeset I'm about to | |
692 %commit''. After the \hgcmd{merge} command completes, the working | |
693 %directory has two parents; these will become the parents of the new | |
694 %changeset. | |
115
b74102b56df5
Wow! Lots more work detailing the working directory, merging, etc.
Bryan O'Sullivan <bos@serpentine.com>
parents:
113
diff
changeset
|
695 |
782 | 696 $B%^!<%88e$K%3%_%C%H$r9T$&$H$-2?$,5/$3$k$+$r9M$($k>l9g$O$d$O$j%o!<%-%s%0%G%#(B |
697 $B%l%/%H%j$r(B``$B$3$l$+$i%3%_%C%H$7$h$&$H$9$k%A%'%s%8%;%C%H(B''$B$H9M$($k$H$h$$!%(B | |
698 \hgcmd{merge}$B%3%^%s%I$,40N;$7$?8e!$%o!<%-%s%0%G%#%l%/%H%j$O(B2$B$D$N?F$r;}(B | |
699 $B$A!$$3$l$i$O?7$?$J%A%'%s%8%;%C%H$NN>?F$H$J$k!%(B | |
115
b74102b56df5
Wow! Lots more work detailing the working directory, merging, etc.
Bryan O'Sullivan <bos@serpentine.com>
parents:
113
diff
changeset
|
700 |
782 | 701 %Mercurial lets you perform multiple merges, but you must commit the |
702 %results of each individual merge as you go. This is necessary because | |
703 %Mercurial only tracks two parents for both revisions and the working | |
704 %directory. While it would be technically possible to merge multiple | |
705 %changesets at once, the prospect of user confusion and making a | |
706 %terrible mess of a merge immediately becomes overwhelming. | |
707 | |
708 Mercurial$B$OJ#?t2s$N%^!<%8$rB%$9!%$3$3$G$=$l$>$l$N%^!<%8$N7k2L$r<+J,<+?H$G(B | |
709 $B%3%_%C%H$7$J$1$l$P$J$i$J$$!%$3$l$O(BMercurial$B$,%j%S%8%g%s$H%o!<%-%s%0%G%#%l(B | |
710 $B%/%H%j$NAPJ}$K$D$$$F(B2$B$D$N?F$N$_$rDI@W$9$k$3$H$K$h$k!%J#?t$N%A%'%s%8%;%C%H(B | |
711 $B$r0lEY$K%^!<%8$9$k$3$H$O5;=QE*$K$O2DG=$@$,!$%^!<%8$K$h$k:.Mp$r0z$-5/$3(B | |
712 $B$7!$<}=&$,$D$+$J$/$J$k8+9~$_$,Bg$-$$!%(B | |
115
b74102b56df5
Wow! Lots more work detailing the working directory, merging, etc.
Bryan O'Sullivan <bos@serpentine.com>
parents:
113
diff
changeset
|
713 |
800 | 714 \subsection{$B%^!<%8$H%j%M!<%`(B} |
715 %A surprising number of revision control systems pay little or no | |
716 %attention to a file's \emph{name} over time. For instance, it used to | |
717 %be common that if a file got renamed on one side of a merge, the changes | |
718 %from the other side would be silently dropped. | |
719 | |
720 $B6C$/$[$IB?$/$N%j%S%8%g%s%3%s%H%m!<%k%7%9%F%`$,(B\emph{$B%U%!%$%kL>(B}$B$NJQ2=$KCm(B | |
721 $B0U$rJ'$C$F$$$J$$!%Nc$($P%^!<%8$N:]!$0lJ}$G%U%!%$%k$,%j%M!<%`$5$l$F$$$?>l(B | |
722 $B9g!$$b$&0lJ}$NJQ99$O2?$N7Y9p$bL5$7$KGK4~$5$l$F$7$^$&!%(B | |
723 | |
724 %Mercurial records metadata when you tell it to perform a rename or | |
725 %copy. It uses this metadata during a merge to do the right thing in the | |
726 %case of a merge. For instance, if I rename a file, and you edit it | |
727 %without renaming it, when we merge our work the file will be renamed and | |
728 %have your edits applied. | |
729 | |
730 Mercurial$B$O%j%M!<%`$d%3%T!<$r9T$&;~$K%a%?%G!<%?$r5-O?$7!$%^!<%8$r@5$7$/9T(B | |
731 $B$&$?$a$KMxMQ$9$k!%Nc$($P$"$k%f!<%6$,%U%!%$%k$r%j%M!<%`$7!$JL$N%f!<%6$,%j(B | |
732 $B%M!<%`$;$:$KF1$8%U%!%$%k$rJT=8$7$?$H$9$k$H!$%^!<%8$N:]$K%U%!%$%k$O%j%M!<(B | |
733 $B%`$5$l!$$J$*$+$DJT=8FbMF$b<h$j9~$`!%(B | |
734 | |
781 | 735 %\section{Other interesting design features} |
736 \section{$B@_7W$NB>$N6=L#?<$$E@(B} | |
110 | 737 |
782 | 738 %In the sections above, I've tried to highlight some of the most |
739 %important aspects of Mercurial's design, to illustrate that it pays | |
740 %careful attention to reliability and performance. However, the | |
741 %attention to detail doesn't stop there. There are a number of other | |
742 %aspects of Mercurial's construction that I personally find | |
743 %interesting. I'll detail a few of them here, separate from the ``big | |
744 %ticket'' items above, so that if you're interested, you can gain a | |
745 %better idea of the amount of thinking that goes into a well-designed | |
746 %system. | |
747 | |
748 $BA0@a$G(BMercurial$B$N@_7W$N:G$b=EMW$JLL$K$D$$$F<h$j>e$2!$?.Mj@-$H@-G=$K:Y?4$N(B | |
749 $BCm0U$rJ'$C$F$$$k$3$H$r6/D4$7$?!%$7$+$7:YIt$X$NCm0U$O$=$l$@$1$KN1$^$i$J$$!%(B | |
750 Mercurial$B$N9=B$$K$O!$8D?ME*$K6=L#?<$/46$8$?E@$,B?!9$"$k!%9*L/$K@_7W$5$l$?(B | |
751 $B%7%9%F%`$NGX8e$K$"$k%"%$%G%#%"$K$D$$$FFI<T$,6=L#$r;}$D$J$i$P!$$h$j?<$$M}(B | |
752 $B2r$,=PMh$k$h$&!$A0=R$7$?Bg$-$J3g$j$H$OJL$K$=$N(B2,3$B$K$D$$$F<h$j>e$2$F$_$h$&(B | |
753 $B$H;W$&!%(B | |
110 | 754 |
781 | 755 %\subsection{Clever compression} |
756 \subsection{$B8-$$05=L(B} | |
109
1b67dc96f27a
Snapshot of concepts chapter.
Bryan O'Sullivan <bos@serpentine.com>
parents:
108
diff
changeset
|
757 |
782 | 758 %When appropriate, Mercurial will store both snapshots and deltas in |
759 %compressed form. It does this by always \emph{trying to} compress a | |
760 %snapshot or delta, but only storing the compressed version if it's | |
761 %smaller than the uncompressed version. | |
762 | |
763 $BE,@Z$J>l9g!$(BMercurial$B$O%9%J%C%W%7%g%C%H$H:9J,$r05=L$5$l$?7A<0$GJ]B8$9$k!%(B | |
764 Mercurial$B$O>o$K%9%J%C%W%7%g%C%H$d:9J,$N05=L$r(B\emph{$B;n$_$k(B}$B$,!$$=$l$rJ]B8(B | |
765 $B$9$k$N$O05=L$5$l$?%P!<%8%g%s$,85$N%P!<%8%g%s$h$j$b>.$5$$;~$N$_$G$"$k!%(B | |
766 | |
767 %This means that Mercurial does ``the right thing'' when storing a file | |
768 %whose native form is compressed, such as a \texttt{zip} archive or a | |
769 %JPEG image. When these types of files are compressed a second time, | |
770 %the resulting file is usually bigger than the once-compressed form, | |
771 %and so Mercurial will store the plain \texttt{zip} or JPEG. | |
109
1b67dc96f27a
Snapshot of concepts chapter.
Bryan O'Sullivan <bos@serpentine.com>
parents:
108
diff
changeset
|
772 |
782 | 773 $B$D$^$j!$(BMercurial$B$O(B\texttt{zip}$B%"!<%+%$%V$d(BJPEG$B2hA|$J$I$N$h$&$K85!905=L$5(B |
774 $B$l$F$$$k%U%!%$%k$NJ]B8$r(B``$B@5$7$$$d$jJ}(B''$B$G9T$&!%$3$l$i$N%U%!%$%k$G$O!$:9(B | |
775 $BJ,<h$C$F05=L$r9T$C$F$b7k2L$H$7$FF@$i$l$k%U%!%$%k$ODL>o!$85$N%U%!%$%k$h$j(B | |
776 $B$bBg$-$/$J$k!%$=$3$G(BMercurial$B$O(B\texttt{zip}$B$d(BJPEG$B$r$=$N$^$^J]B8$9$k!%(B | |
109
1b67dc96f27a
Snapshot of concepts chapter.
Bryan O'Sullivan <bos@serpentine.com>
parents:
108
diff
changeset
|
777 |
782 | 778 %Deltas between revisions of a compressed file are usually larger than |
779 %snapshots of the file, and Mercurial again does ``the right thing'' in | |
780 %these cases. It finds that such a delta exceeds the threshold at | |
781 %which it should store a complete snapshot of the file, so it stores | |
782 %the snapshot, again saving space compared to a naive delta-only | |
783 %approach. | |
784 | |
785 $BDL>o!$05=L$5$l$?%U%!%$%k$N%j%S%8%g%s4V$N:9J,$O%U%!%$%k$N%9%J%C%W%7%g%C%H(B | |
786 $B$h$jBg$-$$!%$3$3$G$b(BMercurial$B$O(B``$B@5$7$$$d$jJ}(B''$B$rMQ$$$F$$$k!%$3$N$h$&$J(B | |
787 $B>u67$G!$:9J,$N%5%$%:$,%U%!%$%k$N40A4$J%9%J%C%W%7%g%C%H$H$7$FJ]B8$7$?J}$,(B | |
788 $BM-Mx$H$J$kogCM$r1[$($k$H!$:9J,$G$O$J$/%9%J%C%W%7%g%C%H$rJ]B8$9$k!%$3$N$h(B | |
789 $B$&$K$7$FC1=c$K:9J,$N$_$r5-O?$9$k%"%W%m!<%A$h$j$b5-21NN0h$r@aLs$7$F$$$k!%(B | |
109
1b67dc96f27a
Snapshot of concepts chapter.
Bryan O'Sullivan <bos@serpentine.com>
parents:
108
diff
changeset
|
790 |
781 | 791 %\subsubsection{Network recompression} |
792 \subsubsection{$B%M%C%H%o!<%/:F05=L(B} | |
109
1b67dc96f27a
Snapshot of concepts chapter.
Bryan O'Sullivan <bos@serpentine.com>
parents:
108
diff
changeset
|
793 |
781 | 794 %When storing revisions on disk, Mercurial uses the ``deflate'' |
795 %compression algorithm (the same one used by the popular \texttt{zip} | |
796 %archive format), which balances good speed with a respectable | |
797 %compression ratio. However, when transmitting revision data over a | |
798 %network connection, Mercurial uncompresses the compressed revision | |
799 %data. | |
800 | |
782 | 801 $B%G%#%9%/$K%j%S%8%g%s$rJ]B8$9$k:]!$(BMercurial$B$O(B``deflate''$B05=L%"%k%4%j%:%`(B |
802 $B$rMQ$$$k!%!J$3$l$O?M5$$N9b$$(B\texttt{zip}$B%"!<%+%$%V%U%)!<%^%C%H$HF1$8%"%k(B | |
803 $B%4%j%:%`$G$"$k!%!K$3$N%"%k%4%j%:%`$O9b$$05=LN($H9bB.@-$r%P%i%s%9$5$;$F$$(B | |
804 $B$k!%$7$+$7%j%S%8%g%s%G!<%?$r%M%C%H%o!<%/$GEAAw$9$k:]$K$O(BMercurial$B$O05=L$5(B | |
805 $B$l$F$$$k%j%S%8%g%s%G!<%?$r?-D9$9$k!%(B | |
806 | |
781 | 807 %If the connection is over HTTP, Mercurial recompresses the entire |
808 %stream of data using a compression algorithm that gives a better | |
809 %compression ratio (the Burrows-Wheeler algorithm from the widely used | |
810 %\texttt{bzip2} compression package). This combination of algorithm | |
811 %and compression of the entire stream (instead of a revision at a time) | |
812 %substantially reduces the number of bytes to be transferred, yielding | |
813 %better network performance over almost all kinds of network. | |
109
1b67dc96f27a
Snapshot of concepts chapter.
Bryan O'Sullivan <bos@serpentine.com>
parents:
108
diff
changeset
|
814 |
782 | 815 HTTP$B$K$h$k@\B3$N>l9g!$(BMercurial$B$O%G!<%?%9%H%j!<%`A4BN$r$h$j05=LN($N9b$$%"(B |
816 $B%k%4%j%:%`!J9-$/MQ$$$i$l$F$$$k05=L%Q%C%1!<%8$G$"$k(B\texttt{bzip2}$B$G;H$o$l(B | |
817 $B$F$$$k(BBurrows-Wheeler$B%"%k%4%j%:%`!K$G:F05=L$9$k!%$3$N%"%k%4%j%:%`$H!$!J%j(B | |
818 $B%S%8%g%sKh$G$J$/!K%9%H%j!<%`A4BN$r05=L$9$k$3$H$K$h$j!$Aw?.$5$l$k%P%$%H?t(B | |
819 $B$OBg$-$/Dc8:$5$l!$$"$i$f$k%M%C%H%o!<%/$G$h$$@-G=$r$($k$3$H$,$G$-$k!%(B | |
820 | |
781 | 821 %(If the connection is over \command{ssh}, Mercurial \emph{doesn't} |
822 %recompress the stream, because \command{ssh} can already do this | |
823 %itself.) | |
824 | |
782 | 825 $B!J(B\command{ssh}$B$K$h$k@\B3$N>l9g!$(BMercurial$B$O%9%H%j!<%`$N:F05=L$O9T$o$J(B |
826 $B$$!%(B\command{ssh}$B%3%^%s%I<+BN$,05=L$r9T$&$?$a$G$"$k!%!K(B | |
827 | |
781 | 828 %\subsection{Read/write ordering and atomicity} |
829 \subsection{$BFI$_=q$-$N=g=x$H%"%H%_%C%/@-(B} | |
109
1b67dc96f27a
Snapshot of concepts chapter.
Bryan O'Sullivan <bos@serpentine.com>
parents:
108
diff
changeset
|
830 |
781 | 831 %Appending to files isn't the whole story when it comes to guaranteeing |
832 %that a reader won't see a partial write. If you recall | |
833 %figure~\ref{fig:concepts:metadata}, revisions in the changelog point to | |
834 %revisions in the manifest, and revisions in the manifest point to | |
835 %revisions in filelogs. This hierarchy is deliberate. | |
109
1b67dc96f27a
Snapshot of concepts chapter.
Bryan O'Sullivan <bos@serpentine.com>
parents:
108
diff
changeset
|
836 |
782 | 837 $B%U%!%$%k$X$NDI5-$OFI$_<j$,ItJ,%U%!%$%k$rFI$^$J$$$3$H$NJ]>Z$H$7$F$O==J,$G(B |
838 $B$O$J$$!%(B $B?^(B~\ref{fig:concepts:metadata}$B$r;W$$5/$3$9$H!$%A%'%s%8%m%0Fb$N%j(B | |
839 $B%S%8%g%s$O%^%K%U%'%9%HFb$N%j%S%8%g%s$r;X$7<($7$F$*$j!$%^%K%U%'%9%HFb$N%j(B | |
840 $B%S%8%g%s$O%U%!%$%k%m%0Fb$N%j%S%8%g%s$r;X$7<($7$F$$$?!%$3$N3,AX9=B$$O=EMW(B | |
841 $B$J0UL#$r;}$C$F$$$k!%(B | |
842 | |
781 | 843 %A writer starts a transaction by writing filelog and manifest data, |
844 %and doesn't write any changelog data until those are finished. A | |
845 %reader starts by reading changelog data, then manifest data, followed | |
846 %by filelog data. | |
109
1b67dc96f27a
Snapshot of concepts chapter.
Bryan O'Sullivan <bos@serpentine.com>
parents:
108
diff
changeset
|
847 |
782 | 848 $B=q$-<j$O%U%!%$%k%m%0$H%^%K%U%'%9%H$r=q$-9~$`$3$H$G%H%i%s%6%/%7%g%s$r(B |
849 $B3+;O$9$k$,!$$3$l$i$,40N;$9$k$^$G%A%'%s%8%m%0%G!<%?$N=q$-9~$_$O9T$o$J$$!%(B | |
850 $B0lJ}!$FI$_<j$O%A%'%s%8%m%0%G!<%?!$%^%K%U%'%9%H%G!<%?!$%U%!%$%k%m%0%G!<%?(B | |
851 $B$N=g$KFI$_=P$7$r9T$&!%(B | |
852 | |
781 | 853 %Since the writer has always finished writing filelog and manifest data |
854 %before it writes to the changelog, a reader will never read a pointer | |
855 %to a partially written manifest revision from the changelog, and it will | |
856 %never read a pointer to a partially written filelog revision from the | |
857 %manifest. | |
109
1b67dc96f27a
Snapshot of concepts chapter.
Bryan O'Sullivan <bos@serpentine.com>
parents:
108
diff
changeset
|
858 |
782 | 859 $B=q$-<j$O>o$K%U%!%$%k%m%0$H%^%K%U%'%9%H%G!<%?$r%A%'%s%8%m%0$NA0$K=q$-9~$_(B |
860 $B=*N;$7$F$$$k$?$a!$FI$_<j$OItJ,E*$K=q$+$l$?%^%K%U%'%9%H%j%S%8%g%s$X$N%]%$(B | |
861 $B%s%?$r$r%A%'%s%8%m%0$+$iFI$_=P$9$3$H$O$J$$!%$^$?ItJ,E*$K=q$+$l$?%U%!%$%k(B | |
862 $B%m%0%j%S%8%g%s$X$N%]%$%s%?$r%^%K%U%'%9%H$+$iFI$_=P$9$3$H$b$J$$!%(B | |
863 | |
781 | 864 %\subsection{Concurrent access} |
865 \subsection{$BF1;~%"%/%;%9(B} | |
109
1b67dc96f27a
Snapshot of concepts chapter.
Bryan O'Sullivan <bos@serpentine.com>
parents:
108
diff
changeset
|
866 |
781 | 867 %The read/write ordering and atomicity guarantees mean that Mercurial |
868 %never needs to \emph{lock} a repository when it's reading data, even | |
869 %if the repository is being written to while the read is occurring. | |
870 %This has a big effect on scalability; you can have an arbitrary number | |
871 %of Mercurial processes safely reading data from a repository safely | |
872 %all at once, no matter whether it's being written to or not. | |
109
1b67dc96f27a
Snapshot of concepts chapter.
Bryan O'Sullivan <bos@serpentine.com>
parents:
108
diff
changeset
|
873 |
782 | 874 $BFI$_=q$-$N=g=x$H%"%H%_%C%/@-$NJ]>Z$K$h$j!$(BMercurial$B$G$O%G!<%?$NFI$_=P$7;~(B |
875 $B$K%j%]%8%H%j$N(B\emph{$B%m%C%/(B}$B$,ITMW$K$J$C$F$$$k!%FI$_=P$7Cf$K=q$-9~$_$,H/@8(B | |
876 $B$7$?$H$7$F$bF1MM$G$"$k!%$3$N$3$H$O%9%1!<%i%S%j%F%#$KBg$-$J8z2L$r$b$?$i(B | |
877 $B$9!%B??t$N(BMercurial$B%W%m%;%9$,$"$C$F$b!$%j%]%8%H%j$X$N=q$-9~$_$NM-L5$K4X$o(B | |
878 $B$i$:!$%j%]%8%H%j$+$i0lEY$K0BA4$K%G!<%?$rFI$_=P$9$3$H$,$G$-$k!%(B | |
879 | |
781 | 880 %The lockless nature of reading means that if you're sharing a |
881 %repository on a multi-user system, you don't need to grant other local | |
782 | 882 %users permission to \emph{write} to your repositoryin order for them |
781 | 883 %to be able to clone it or pull changes from it; they only need |
884 %\emph{read} permission. (This is \emph{not} a common feature among | |
885 %revision control systems, so don't take it for granted! Most require | |
886 %readers to be able to lock a repository to access it safely, and this | |
887 %requires write permission on at least one directory, which of course | |
888 %makes for all kinds of nasty and annoying security and administrative | |
889 %problems.) | |
109
1b67dc96f27a
Snapshot of concepts chapter.
Bryan O'Sullivan <bos@serpentine.com>
parents:
108
diff
changeset
|
890 |
782 | 891 Mercurial$B$G$O!$%m%C%/L5$7$GFI$_=P$7$r9T$&$?$a!$%^%k%A%f!<%6%7%9%F%`>e$G%j(B |
892 $B%]%8%H%j$r6&M-$7$F$$$k>l9g$G$b(Bclone$B$d(Bpull$B$r9T$*$&$H$9$kB>$N%m!<%+%k%f!<%6(B | |
893 $B$K%j%]%8%H%j$X$N(B\emph{$B=q$-9~$_(B}$B5v2D$rM?$($kI,MW$O$J$$!%H`$i$K$O(B\emph{$BFI$_(B | |
894 $B=P$7(B}$B5v2D$,$"$l$P$h$$!%!JB>$N%j%S%8%g%s%3%s%H%m!<%k%7%9%F%`$G$O$3$&$O$$$+(B | |
895 $B$:!$BgH>$N%7%9%F%`$G$OFI$_<j$,0BA4$K%j%]%8%H%j$K%"%/%;%9$9$k$?$a$K%m%C%/(B | |
896 $B$r<hF@$9$k$3$H$rI,MW$H$9$k!%$3$l$O$9$J$o$AFI$_<j$,>/$J$/$H$b(B1$B$D$N%G%#%l%/(B | |
897 $B%H%j$KBP$7$F=q$-9~$_5v2D$r;}$C$F$$$J$1$l$P$J$i$J$$$3$H$r0UL#$9$k!%$3$N$?(B | |
898 $B$a$K%;%-%e%j%F%#$d4IM}>e$NLq2p$JLdBj$,H/@8$7F@$k!%!K(B | |
899 | |
781 | 900 %Mercurial uses locks to ensure that only one process can write to a |
901 %repository at a time (the locking mechanism is safe even over | |
902 %filesystems that are notoriously hostile to locking, such as NFS). If | |
903 %a repository is locked, a writer will wait for a while to retry if the | |
904 %repository becomes unlocked, but if the repository remains locked for | |
905 %too long, the process attempting to write will time out after a while. | |
906 %This means that your daily automated scripts won't get stuck forever | |
907 %and pile up if a system crashes unnoticed, for example. (Yes, the | |
908 %timeout is configurable, from zero to infinity.) | |
909 | |
782 | 910 Mercurial$B$O0lEY$K(B1$B%W%m%;%9$@$1$,%j%]%8%H%j$K=q$-9~$`$3$H$rJ]>Z$9$k$?$a$K(B |
911 $B%m%C%/$r;H$C$F$$$k!%!J(BMercurial$B$NMQ$$$k%m%C%/%a%+%K%:%`$O(BNFS$B$N$h$&$K%m%C(B | |
912 $B%/$HAj@-$N0-$$$3$H$GM-L>$J%U%!%$%k%7%9%F%`>e$G$b0BA4$G$"$k!%!K%j%]%8%H%j(B | |
913 $B$,%m%C%/$5$l$k$H!$=q$-9~$_%W%m%;%9$O%j%]%8%H%j$,%"%s%m%C%/$5$l$k$^$G$7$P(B | |
914 $B$i$/BT$D!%$7$+$7%j%]%8%H%j$,D9;~4V$K$o$?$C$F%m%C%/$5$lB3$1$k>l9g$O!$=q$-(B | |
915 $B9~$_$7$h$&$H$9$k%W%m%;%9$O%?%$%`%"%&%H$9$k!%$3$l$O!$Nc$($P!$F|>oMQ$$$k<+(B | |
916 $BF0%9%/%j%W%H$O1J1s$K%9%?%C%/$9$k$o$1$G$O$J$$$3$H$r0UL#$9$k!%!J$b$A$m$s%?(B | |
917 $B%$%`%"%&%H$^$G$N;~4V$O%<%m$+$iL58B$N4V$G@_Dj$+$N$&$G$"$k!K(B | |
918 | |
781 | 919 %\subsubsection{Safe dirstate access} |
920 \subsubsection{$B0BA4$J(Bdirstate$B%"%/%;%9(B} | |
109
1b67dc96f27a
Snapshot of concepts chapter.
Bryan O'Sullivan <bos@serpentine.com>
parents:
108
diff
changeset
|
921 |
781 | 922 %As with revision data, Mercurial doesn't take a lock to read the |
923 %dirstate file; it does acquire a lock to write it. To avoid the | |
924 %possibility of reading a partially written copy of the dirstate file, | |
925 %Mercurial writes to a file with a unique name in the same directory as | |
926 %the dirstate file, then renames the temporary file atomically to | |
927 %\filename{dirstate}. The file named \filename{dirstate} is thus | |
928 %guaranteed to be complete, not partially written. | |
110 | 929 |
782 | 930 $B%j%S%8%g%s%G!<%?$N;~$HF1MM$K!$(BMercurial$B$O(Bdirstate$B%U%!%$%k$rFI$_=P$9:]$K$O(B |
931 $B%m%C%/$r9T$o$J$$!%%m%C%/$r9T$&$N$O=q$-9~$_$N;~$N$_$G$"$k!%0lIt$N$_$,=q$-(B | |
932 $B9~$^$l$?(Bdirstate$B%U%!%$%k$rFI$_9~$^$J$$$h$&$K$9$k$?$a!$(B Mercurial$B$OF1$8%G%#(B | |
933 $B%l%/%H%jFb$K%f%K!<%/$JL>A0$G(Bdirstate$B%U%!%$%k$r=q$-!$$3$N0l;~%U%!%$%k$r%"(B | |
934 $B%H%_%C%/$K(B\filename{dirstate}$B$K%j%M!<%`$9$k!%$3$l$K$h(B | |
935 $B$j!$(B\filename{dirstate}$B%U%!%$%k$O>o$K40A4$G$"$k$3$H$,J]>Z$5$l$k!%(B | |
936 | |
781 | 937 %\subsection{Avoiding seeks} |
938 \subsection{$B%7!<%/$N2sHr(B} | |
939 | |
940 %Critical to Mercurial's performance is the avoidance of seeks of the | |
941 %disk head, since any seek is far more expensive than even a | |
942 %comparatively large read operation. | |
110 | 943 |
781 | 944 Mercurial$B$N@-G=$K$O!$%G%#%9%/%X%C%I$N%7!<%/$rHr$1$k$3$H$,IT2D7g$G$"$k!%(B |
945 $B%7!<%/$OBg5,LO$JFI$_=P$7A`:n$HHf3S$7$F$bHs>o$K9b$/$D$/!%(B | |
946 | |
947 %This is why, for example, the dirstate is stored in a single file. If | |
948 %there were a dirstate file per directory that Mercurial tracked, the | |
949 %disk would seek once per directory. Instead, Mercurial reads the | |
950 %entire single dirstate file in one step. | |
109
1b67dc96f27a
Snapshot of concepts chapter.
Bryan O'Sullivan <bos@serpentine.com>
parents:
108
diff
changeset
|
951 |
781 | 952 $B$=$NM}M3$O!$Nc$($P!$(Bdirstate$B$O(B1$B$D$N%U%!%$%k$KJ]B8$5$l$F$$$k$?$a$G!$(B |
953 Mercurial$B$,DI@W$7$F$$$k(Bdirstate$B%U%!%$%k$,%G%#%l%/%H%jKh$K$"$k(B | |
954 $B$H!$(BMercurial$B$O%G%#%l%/%H%jKh$K%7!<%/$r9T$&$3$H$K$J$k!%<B:]$K$O(BMercurial | |
955 $B$OA4BN$G0l$D$N(Bdirstate$B%U%!%$%k$r%o%s%9%F%C%W$GFI$`!%(B | |
109
1b67dc96f27a
Snapshot of concepts chapter.
Bryan O'Sullivan <bos@serpentine.com>
parents:
108
diff
changeset
|
956 |
781 | 957 %Mercurial also uses a ``copy on write'' scheme when cloning a |
958 %repository on local storage. Instead of copying every revlog file | |
959 %from the old repository into the new repository, it makes a ``hard | |
960 %link'', which is a shorthand way to say ``these two names point to the | |
961 %same file''. When Mercurial is about to write to one of a revlog's | |
962 %files, it checks to see if the number of names pointing at the file is | |
963 %greater than one. If it is, more than one repository is using the | |
964 %file, so Mercurial makes a new copy of the file that is private to | |
965 %this repository. | |
111 | 966 |
781 | 967 Mercurial$B$O%j%]%8%H%j$r%m!<%+%k%9%H%l!<%8$K%/%m!<%s$9$k:]$K(B``$B%3%T!<%*%s%i(B |
782 | 968 $B%$%H(B''$B<jK!$r;H$C$F$$$k!%85$N%j%]%8%H%j$+$i?7$7$$%j%]%8%H%j$XA4$F$N(Brevlog |
969 $B%U%!%$%k$r%3%T!<$9$k$N$G$O$J$/!$%O!<%I%j%s%/$r:n@.$9$k!%%O!<%I%j%s%/$OF1(B | |
970 $B0l$N%U%!%$%k$r;X$7<($9JLL>$r:n$k4JC1$JJ}K!$G$"$k!%(B Mercurial$B$O(Brevlog$B%U%!(B | |
971 $B%$%k$K=q$-9~$_$r9T$&:]$K%U%!%$%k$r<($9L>A0$,(B2$B$D0J>e$"$k2TF/$+$r%A%'%C%/$9(B | |
972 $B$k!%(B 2$B$D0J>e$NL>A0$,$"$k>l9g!$(B2$B$D0J>e$N%j%]%8%H%j$,%U%!%$%k$r;HMQ$7$F$*(B | |
973 $B$j!$(BMercurial$B$O%U%!%$%k$N%j%]%8%H%j$K8GM-$J?7$7$$%3%T!<$r:n@.$9$k!%(B | |
109
1b67dc96f27a
Snapshot of concepts chapter.
Bryan O'Sullivan <bos@serpentine.com>
parents:
108
diff
changeset
|
974 |
781 | 975 %A few revision control developers have pointed out that this idea of |
976 %making a complete private copy of a file is not very efficient in its | |
977 %use of storage. While this is true, storage is cheap, and this method | |
978 %gives the highest performance while deferring most book-keeping to the | |
979 %operating system. An alternative scheme would most likely reduce | |
980 %performance and increase the complexity of the software, each of which | |
981 %is much more important to the ``feel'' of day-to-day use. | |
115
b74102b56df5
Wow! Lots more work detailing the working directory, merging, etc.
Bryan O'Sullivan <bos@serpentine.com>
parents:
113
diff
changeset
|
982 |
782 | 983 $B%j%S%8%g%s%3%s%H%m!<%k%7%9%F%`$N3+H/<T$N4v?M$+$O!$%U%!%$%k$N40A4$J%W%i%$(B |
984 $B%Y!<%H%3%T!<$r:n$k$H$$$&%"%$%G%#%"$O!$%9%H%l!<%8$NMxMQNL$N4QE@$+$i$"$^$j(B | |
985 $B8zN(E*$G$J$$$H;XE&$7$F$$$k!%$3$l$O;v<B$G$"$k$,!$%9%H%l!<%8$O0B2A$G$"$j!$(B | |
986 $B$3$NJ}K!$O(BOS$B>e$G:9J,$r<h$k>l9g:G9b$N@-G=$r$b$?$i$9!%$=$NB>$N<jK!$O@-G=$r(B | |
987 $BB;$J$$!$%=%U%H%&%'%"$,J#;($K$J$k2DG=@-$,9b$$!%$3$l$i$OF|!9$N;HMQ46$h$j$b(B | |
988 $B$:$C$H=EMW$G$"$k!%(B | |
989 | |
781 | 990 %\subsection{Other contents of the dirstate} |
991 \subsection{dirstate$B$NB>$NFbMF(B} | |
115
b74102b56df5
Wow! Lots more work detailing the working directory, merging, etc.
Bryan O'Sullivan <bos@serpentine.com>
parents:
113
diff
changeset
|
992 |
781 | 993 %Because Mercurial doesn't force you to tell it when you're modifying a |
994 %file, it uses the dirstate to store some extra information so it can | |
995 %determine efficiently whether you have modified a file. For each file | |
996 %in the working directory, it stores the time that it last modified the | |
997 %file itself, and the size of the file at that time. | |
115
b74102b56df5
Wow! Lots more work detailing the working directory, merging, etc.
Bryan O'Sullivan <bos@serpentine.com>
parents:
113
diff
changeset
|
998 |
782 | 999 Mercurial$B$O!$%U%!%$%k$rJQ99$7$?>l9g$G$b!$JQ99$N?=9p$r6/@)$7$J$$$?$a!$(B |
1000 dirstate$B$KDI2C$N>pJs$rJ]B8$9$k$3$H$G%U%!%$%k$rJQ99$7$?$+$I$&$+8z2LE*$KH=(B | |
1001 $BJL$9$k!%%o!<%-%s%0%G%#%l%/%H%j$N$9$Y$F$N%U%!%$%k$K$D$$$F!$:G8e$K%U%!%$%k(B | |
1002 $B$,JQ99$5$l$?;~9o$H!$$=$N:]$N%U%!%$%k%5%$%:$r5-O?$7$F$$$k!%(B | |
1003 | |
781 | 1004 %When you explicitly \hgcmd{add}, \hgcmd{remove}, \hgcmd{rename} or |
1005 %\hgcmd{copy} files, Mercurial updates the dirstate so that it knows | |
1006 %what to do with those files when you commit. | |
115
b74102b56df5
Wow! Lots more work detailing the working directory, merging, etc.
Bryan O'Sullivan <bos@serpentine.com>
parents:
113
diff
changeset
|
1007 |
782 | 1008 $BL@<(E*$K%U%!%$%k$r(B\hgcmd{add}, \hgcmd{remove}, \hgcmd{rename} $B$^$?$O(B |
1009 \hgcmd{copy}$B$7$?>l9g!$(BMercurial$B$O(Bdirstate$B$r99?7$7!$%3%_%C%H$N:]$K$=$l$i(B | |
1010 $B$N%U%!%$%k$r$I$&<h$j07$&$+$rH=CG$9$k!%(B | |
1011 | |
781 | 1012 %When Mercurial is checking the states of files in the working |
1013 %directory, it first checks a file's modification time. If that has | |
1014 %not changed, the file must not have been modified. If the file's size | |
1015 %has changed, the file must have been modified. If the modification | |
1016 %time has changed, but the size has not, only then does Mercurial need | |
1017 %to read the actual contents of the file to see if they've changed. | |
1018 %Storing these few extra pieces of information dramatically reduces the | |
1019 %amount of data that Mercurial needs to read, which yields large | |
1020 %performance improvements compared to other revision control systems. | |
1021 | |
782 | 1022 Mercurial$B$,%o!<%-%s%0%G%#%l%/%H%j$N%U%!%$%k$N>uBV$r%A%'%C%/$9$k:]$O!$$^$:(B |
1023 $B%U%!%$%k$N99?7F|;~$rD4$Y$k!%$3$l$,JQ99$5$l$F$$$J$$>l9g$O%U%!%$%k$OJQ99$,(B | |
1024 $B$J$$$H$$$&$3$H$,$o$+$k!%%U%!%$%k%5%$%:$,JQ$o$C$F$$$k>l9g$O!$%U%!%$%k$,JQ(B | |
1025 $B99$5$l$?$3$H$,$o$+$k!%99?7F|;~$,JQ$o$C$F$$$k$,!$%5%$%:$,F1$8>l9g$O(B | |
1026 Mercurial$B$O%U%!%$%k$NFbMF$rD>@\8+$F!$JQ99$5$l$F$$$k$+$I$&$+$rH=CG$9$kI,MW(B | |
1027 $B$,$"$k!%$3$l$i$N$4$/6O$+$N>pJs$rJ]B8$9$k$3$H$K$h$C$F!$(BMercurial$B$O%G!<%?$N(B | |
1028 $BFI$_<h$jNL$r7`E*$K:o8:$7!$B>$N%j%S%8%g%s%3%s%H%m!<%k%7%9%F%`$HHf3S$7$FBg(B | |
1029 $B$-$J@-G=8~>e$rC#@.$7$F$$$k!%(B | |
1030 | |
781 | 1031 %%% Local Variables: |
293
3b1291f24c0d
- replaved latex-mode to yatex-mode
Yoshiki Yazawa <yaz@cc.rim.or.jp>
parents:
290
diff
changeset
|
1032 %%% mode: yatex |
56
b8539d91c84d
Begining of concepts chapter
Josef "Jeff" Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
1033 %%% TeX-master: "00book" |
b8539d91c84d
Begining of concepts chapter
Josef "Jeff" Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
1034 %%% End: |