1 \documentclass[a4paper,leqno]{strayman}
3 \let\numberwithin=\notdef
11 \renewcommand{\ge}{\geqslant}
12 \renewcommand{\le}{\leqslant}
14 \newcommand{\has}{\sqsupseteq}
15 \newcommand{\isin}{\sqsubseteq}
17 \newcommand{\nothaspatch}{\mathrel{\,\not\!\not\relax\haspatch}}
18 \newcommand{\notpatchisin}{\mathrel{\,\not\!\not\relax\patchisin}}
19 \newcommand{\haspatch}{\sqSupset}
20 \newcommand{\patchisin}{\sqSubset}
22 \newif\ifhidehack\hidehackfalse
23 \DeclareRobustCommand\hidefromedef[2]{%
24 \hidehacktrue\ifhidehack#1\else#2\fi\hidehackfalse}
25 \newcommand{\pa}[1]{\hidefromedef{\varmathbb{#1}}{#1}}
27 \newcommand{\set}[1]{\mathbb{#1}}
28 \newcommand{\pay}[1]{\pa{#1}^+}
29 \newcommand{\pan}[1]{\pa{#1}^-}
31 \newcommand{\p}{\pa{P}}
32 \newcommand{\py}{\pay{P}}
33 \newcommand{\pn}{\pan{P}}
35 \newcommand{\pr}{\pa{R}}
36 \newcommand{\pry}{\pay{R}}
37 \newcommand{\prn}{\pan{R}}
39 %\newcommand{\hasparents}{\underaccent{1}{>}}
40 %\newcommand{\hasparents}{{%
41 % \declareslashed{}{_{_1}}{0}{-0.8}{>}\slashed{>}}}
42 \newcommand{\hasparents}{>_{\mkern-7.0mu _1}}
43 \newcommand{\areparents}{<_{\mkern-14.0mu _1\mkern+5.0mu}}
45 \renewcommand{\implies}{\Rightarrow}
46 \renewcommand{\equiv}{\Leftrightarrow}
47 \renewcommand{\land}{\wedge}
48 \renewcommand{\lor}{\vee}
50 \newcommand{\pancs}{{\mathcal A}}
51 \newcommand{\pends}{{\mathcal E}}
52 \newcommand{\merge}{{\mathcal M}}
54 \newcommand{\pancsof}[2]{\pancs ( #1 , #2 ) }
55 \newcommand{\pendsof}[2]{\pends ( #1 , #2 ) }
56 \newcommand{\mergeof}[3]{\merge ( #1 , #2, #3 ) }
58 \newcommand{\patchof}[1]{{\mathcal P} ( #1 ) }
59 \newcommand{\baseof}[1]{{\mathcal B} ( #1 ) }
61 \newcommand{\eqn}[2]{ #2 \tag*{\mbox{\bf #1}} }
62 \newcommand{\corrolary}[1]{ #1 \tag*{\mbox{\it Corrolary.}} }
64 %\newcommand{\bigforall}{\mathop{\hbox{\huge$\forall$}}}
65 \newcommand{\bigforall}{%
67 {\hbox{\huge$\forall$}}%
68 {\hbox{\Large$\forall$}}%
69 {\hbox{\normalsize$\forall$}}%
70 {\hbox{\scriptsize$\forall$}}}%
73 \newcommand{\Largeexists}{\mathop{\hbox{\Large$\exists$}}}
74 \newcommand{\Largenexists}{\mathop{\hbox{\Large$\nexists$}}}
76 \newcommand{\qed}{\square}
77 \newcommand{\proof}[1]{{\it Proof.} #1 $\qed$}
79 \newcommand{\gathbegin}{\begin{gather} \tag*{}}
80 \newcommand{\gathnext}{\\ \tag*{}}
83 \newcommand{\false}{f}
91 \desclabelstyle{\nextlinelabel}
93 \item[ $ C \hasparents \set X $ ]
94 The parents of commit $C$ are exactly the set
98 $C$ is a descendant of $D$ in the git commit
99 graph. This is a partial order, namely the transitive closure of
100 $ D \in \set X $ where $ C \hasparents \set X $.
102 \item[ $ C \has D $ ]
103 Informally, the tree at commit $C$ contains the change
104 made in commit $D$. Does not take account of deliberate reversions by
105 the user or reversion, rebasing or rewinding in
106 non-Topbloke-controlled branches. For merges and Topbloke-generated
107 anticommits or re-commits, the ``change made'' is only to be thought
108 of as any conflict resolution. This is not a partial order because it
111 \item[ $ \p, \py, \pn $ ]
112 A patch $\p$ consists of two sets of commits $\pn$ and $\py$, which
113 are respectively the base and tip git branches. $\p$ may be used
114 where the context requires a set, in which case the statement
115 is to be taken as applying to both $\py$ and $\pn$.
116 All these sets are distinct. Hence:
118 \item[ $ \patchof{ C } $ ]
119 Either $\p$ s.t. $ C \in \p $, or $\bot$.
120 A function from commits to patches' sets $\p$.
122 \item[ $ \pancsof{C}{\set P} $ ]
123 $ \{ A \; | \; A \le C \land A \in \set P \} $
124 i.e. all the ancestors of $C$
125 which are in $\set P$.
127 \item[ $ \pendsof{C}{\set P} $ ]
128 $ \{ E \; | \; E \in \pancsof{C}{\set P}
129 \land \mathop{\not\exists}_{A \in \pancsof{C}{\set P}}
130 E \neq A \land E \le A \} $
131 i.e. all $\le$-maximal commits in $\pancsof{C}{\set P}$.
133 \item[ $ \baseof{C} $ ]
134 $ \pendsof{C}{\pn} = \{ \baseof{C} \} $ where $ C \in \py $.
135 A partial function from commits to commits.
136 See Unique Base, below.
138 \item[ $ C \haspatch \p $ ]
139 $\displaystyle \bigforall_{D \in \py} D \isin C \equiv D \le C $.
140 ~ Informally, $C$ has the contents of $\p$.
142 \item[ $ C \nothaspatch \p $ ]
143 $\displaystyle \bigforall_{D \in \py} D \not\isin C $.
144 ~ Informally, $C$ has none of the contents of $\p$.
146 Non-Topbloke commits are $\nothaspatch \p$ for all $\p$; if a Topbloke
147 patch is applied to a non-Topbloke branch and then bubbles back to
148 the Topbloke patch itself, we hope that git's merge algorithm will
149 DTRT or that the user will no longer care about the Topbloke patch.
151 \item[ $ \mergeof{L}{M}{R} $ ]
152 $\displaystyle \left\{ C \middle|
154 (D \isin L \land D \isin R) \lor D = C : & \true \\
155 (D \not\isin L \land D \not\isin R) \land D \neq C : & \false \\
156 \text{otherwise} : & D \not\isin M
164 We maintain these each time we construct a new commit. \\
166 C \has D \implies C \ge D
168 \[\eqn{Unique Base:}{
169 \bigforall_{C \in \py} \pendsof{C}{\pn} = \{ B \}
171 \[\eqn{Tip Contents:}{
172 \bigforall_{C \in \py} D \isin C \equiv
173 { D \isin \baseof{C} \lor \atop
174 (D \in \py \land D \le C) }
176 \[\eqn{Base Acyclic:}{
177 \bigforall_{B \in \pn} D \isin B \implies D \notin \py
180 \bigforall_{C,\p} C \haspatch \p \lor C \nothaspatch \p
182 \[\eqn{Foreign Inclusion:}{
183 \bigforall_{D \text{ s.t. } \patchof{D} = \bot} D \isin C \equiv D \leq C
186 \section{Some lemmas}
188 \[ \eqn{Exclusive Tip Contents:}{
189 \bigforall_{C \in \py}
190 \neg \Bigl[ D \isin \baseof{C} \land ( D \in \py \land D \le C )
193 Ie, the two limbs of the RHS of Tip Contents are mutually exclusive.
196 Let $B = \baseof{C}$ in $D \isin \baseof{C}$. Now $B \in \pn$.
197 So by Base Acyclic $D \isin B \implies D \notin \py$.
200 \bigforall_{C \in \py} D \isin C \equiv
202 D \in \py : & D \le C \\
203 D \not\in \py : & D \isin \baseof{C}
207 \[ \eqn{Tip Self Inpatch:}{
208 \bigforall_{C \in \py} C \haspatch \p
210 Ie, tip commits contain their own patch.
213 Apply Exclusive Tip Contents to some $D \in \py$:
214 $ \bigforall_{C \in \py}\bigforall_{D \in \py}
215 D \isin C \equiv D \le C $
218 \[ \eqn{Exact Ancestors:}{
219 \bigforall_{ C \hasparents \set{R} }
221 ( \mathop{\hbox{\huge{$\vee$}}}_{R \in \set R} D \le R )
225 \[ \eqn{Transitive Ancestors:}{
226 \left[ \bigforall_{ E \in \pendsof{C}{\set P} } E \le M \right] \equiv
227 \left[ \bigforall_{ A \in \pancsof{C}{\set P} } A \le M \right]
231 The implication from right to left is trivial because
232 $ \pends() \subset \pancs() $.
233 For the implication from left to right:
234 by the definition of $\mathcal E$,
235 for every such $A$, either $A \in \pends()$ which implies
236 $A \le M$ by the LHS directly,
237 or $\exists_{A' \in \pancs()} \; A' \neq A \land A \le A' $
238 in which case we repeat for $A'$. Since there are finitely many
239 commits, this terminates with $A'' \in \pends()$, ie $A'' \le M$
240 by the LHS. And $A \le A''$.
242 \[ \eqn{Calculation Of Ends:}{
243 \bigforall_{C \hasparents \set A}
244 \pendsof{C}{\set P} =
246 \Bigl[ \Largeexists_{A \in \set A}
247 E \in \pendsof{A}{\set P} \Bigr] \land
248 \Bigl[ \Largenexists_{B \in \set A}
249 E \neq B \land E \le B \Bigr]
254 \section{Commit annotation}
256 We annotate each Topbloke commit $C$ with:
260 \baseof{C}, \text{ if } C \in \py
263 \text{ either } C \haspatch \pa{Q} \text{ or } C \nothaspatch \pa{Q}
265 \bigforall_{\pay{Q} \not\ni C} \pendsof{C}{\pay{Q}}
268 We do not annotate $\pendsof{C}{\py}$ for $C \in \py$. Doing so would
269 make it wrong to make plain commits with git because the recorded $\pends$
270 would have to be updated. The annotation is not needed because
271 $\forall_{\py \ni C} \; \pendsof{C}{\py} = \{C\}$.
273 \section{Simple commit}
275 A simple single-parent forward commit $C$ as made by git-commit.
277 \tag*{} C \hasparents \{ A \} \\
278 \tag*{} \patchof{C} = \patchof{A} \\
279 \tag*{} D \isin C \equiv D \isin A \lor D = C
282 \subsection{No Replay}
285 \subsection{Unique Base}
286 If $A, C \in \py$ then $\baseof{C} = \baseof{A}$. $\qed$
288 \subsection{Tip Contents}
289 We need to consider only $A, C \in \py$. From Tip Contents for $A$:
290 \[ D \isin A \equiv D \isin \baseof{A} \lor ( D \in \py \land D \le A ) \]
291 Substitute into the contents of $C$:
292 \[ D \isin C \equiv D \isin \baseof{A} \lor ( D \in \py \land D \le A )
294 Since $D = C \implies D \in \py$,
295 and substituting in $\baseof{C}$, this gives:
296 \[ D \isin C \equiv D \isin \baseof{C} \lor
297 (D \in \py \land D \le A) \lor
298 (D = C \land D \in \py) \]
299 \[ \equiv D \isin \baseof{C} \lor
300 [ D \in \py \land ( D \le A \lor D = C ) ] \]
301 So by Exact Ancestors:
302 \[ D \isin C \equiv D \isin \baseof{C} \lor ( D \in \py \land D \le C
306 \subsection{Base Acyclic}
308 Need to consider only $A, C \in \pn$.
310 For $D = C$: $D \in \pn$ so $D \not\in \py$. OK.
312 For $D \neq C$: $D \isin C \equiv D \isin A$, so by Base Acyclic for
313 $A$, $D \isin C \implies D \not\in \py$. $\qed$
315 \subsection{Coherence and patch inclusion}
317 Need to consider $D \in \py$
319 \subsubsection{For $A \haspatch P, D = C$:}
325 $ D \isin C \equiv \ldots \lor \true \text{ so } D \haspatch C $.
327 \subsubsection{For $A \haspatch P, D \neq C$:}
328 Ancestors: $ D \le C \equiv D \le A $.
330 Contents: $ D \isin C \equiv D \isin A \lor f $
331 so $ D \isin C \equiv D \isin A $.
334 \[ A \haspatch P \implies C \haspatch P \]
336 \subsubsection{For $A \nothaspatch P$:}
338 Firstly, $C \not\in \py$ since if it were, $A \in \py$.
341 Now by contents of $A$, $D \notin A$, so $D \notin C$.
344 \[ A \nothaspatch P \implies C \nothaspatch P \]
347 \subsection{Foreign inclusion:}
349 If $D = C$, trivial. For $D \neq C$:
350 $D \isin C \equiv D \isin A \equiv D \le A \equiv D \le C$. $\qed$
354 Given $L, R^+, R^-$ where
355 $\patchof{R^+} = \pry, \patchof{R^-} = \prn$.
356 Construct $C$ which has $\pr$ removed.
357 Used for removing a branch dependency.
359 C \hasparents \{ L \}
361 \patchof{C} = \patchof{L}
365 R \in \py : & \baseof{R} \ge \baseof{L}
366 \land [\baseof{L} = M \lor \baseof{L} = \baseof{M}] \\
367 R \in \pn : & R \ge \baseof{L}
368 \land M = \baseof{L} \\
369 \text{otherwise} : & \false
373 xxx want to prove $D \isin C \equiv D \not\in pry \land D \isin L$.
377 Merge commits $L$ and $R$ using merge base $M$ ($M < L, M < R$):
379 C \hasparents \{ L, R \}
381 \patchof{C} = \patchof{L}
385 (D \isin L \land D \isin R) \lor D = C : & \true \\
386 (D \not\isin L \land D \not\isin R) \land D \neq C : & \false \\
387 \text{otherwise} : & D \not\isin M
391 \subsection{Conditions}
393 \[ \eqn{ Tip Merge }{
396 R \in \py : & \baseof{R} \ge \baseof{L}
397 \land [\baseof{L} = M \lor \baseof{L} = \baseof{M}] \\
398 R \in \pn : & R \ge \baseof{L}
399 \land M = \baseof{L} \\
400 \text{otherwise} : & \false
404 \subsection{No Replay}
406 \subsubsection{For $D=C$:} $D \isin C, D \le C$. OK.
408 \subsubsection{For $D \isin L \land D \isin R$:}
409 $D \isin C$. And $D \isin L \implies D \le L \implies D \le C$. OK.
411 \subsubsection{For $D \neq C \land D \not\isin L \land D \not\isin R$:}
414 \subsubsection{For $D \neq C \land D \not\isin L \land D \not\isin R$:}
417 \subsubsection{For $D \neq C \land (D \isin L \equiv D \not\isin R)
418 \land D \not\isin M$:}
419 $D \isin C$. Also $D \isin L \lor D \isin R$ so $D \le L \lor D \le
422 \subsubsection{For $D \neq C \land (D \isin L \equiv D \not\isin R)
424 $D \not\isin C$. Also $D \isin L \lor D \isin R$ so $D \le L \lor D \le
429 \subsection{Unique Base}
431 Need to consider only $C \in \py$, ie $L \in \py$,
432 and calculate $\pendsof{C}{\pn}$. So we will consider some
433 putative ancestor $A \in \pn$ and see whether $A \le C$.
435 By Exact Ancestors for C, $A \le C \equiv A \le L \lor A \le R \lor A = C$.
436 But $C \in py$ and $A \in \pn$ so $A \neq C$.
437 Thus $A \le C \equiv A \le L \lor A \le R$.
439 By Unique Base of L and Transitive Ancestors,
440 $A \le L \equiv A \le \baseof{L}$.
442 \subsubsection{For $R \in \py$:}
444 By Unique Base of $R$ and Transitive Ancestors,
445 $A \le R \equiv A \le \baseof{R}$.
447 But by Tip Merge condition on $\baseof{R}$,
448 $A \le \baseof{L} \implies A \le \baseof{R}$, so
449 $A \le \baseof{R} \lor A \le \baseof{L} \equiv A \le \baseof{R}$.
450 Thus $A \le C \equiv A \le \baseof{R}$.
451 That is, $\baseof{C} = \baseof{R}$.
453 \subsubsection{For $R \in \pn$:}
455 By Tip Merge condition on $R$,
456 $A \le \baseof{L} \implies A \le R$, so
457 $A \le R \lor A \le \baseof{L} \equiv A \le R$.
458 Thus $A \le C \equiv A \le R$.
459 That is, $\baseof{C} = R$.