chiark / gitweb /
git-debrebase: test suite: test --anchor option
[dgit.git] / NOTES.git-debrebase
1 TODO
2    reference docs
3       git-debrebase(5)   data model
4       git-debrebase(1)   command line
5    tutorial
6       dgit-maint-debrebase(7)
7       someone should set branch.<name>.mergeOptions to include --ff-only ?
8
9    clean up remains of NOTES and README
10
11    arrange for dgit to automatically stitch on push
12
13 #    git-ffqrebase start [BASE]
14 #                # records previous HEAD so it can be overwritten
15 #                # records base for future git-ffqrebase
16 #    git-ffqrebase set-base BASE
17 #    git-ffqrebase <git-rebase options>
18 #    git-ffqrebase finish
19 #    git-ffqrebase status [BRANCH]
20 #
21 #  refs/ffq-prev/REF    relates to refs/REF
22 #
23 # git-debrebase without start, if already started, is willing
24 # to strip pseudomerges provided that they overwrite exactly
25 # the previous HEAD
26 #  xxxx is this right ?  what matters is have we pushed
27 #    I think in fact the right answer is:
28 #       git-debrebase always strips out pseudomerges from its branch
29 #       a pseudomerge is put in at the time we want to push
30 #       at that time, we make a pseudomerge of the remote tracking
31 #           branch (if raw git) or the dgit view (if dgit)
32 #       for raw git git-ffqrebase, do want preciseley to record
33 #           value of remote tracking branch or our branch, on start, so we
34 #           overwrite only things we intend to
35 #  the previous pseudomerge    check for tags and remote branches ?
36
37
38 =========
39
40 special commit tags
41 overall format
42   [git-debrebase[ COMMIT-TYPE [ ARGS...]]: PROSE, MORE PROSE]
43
44 [git-debrebase: split mixed commit, debian part]
45 [git-debrebase: split mixed commit, upstream-part]
46 [git-debrebase: convert dgit import, debian changes]
47 [git-debrebase anchor: convert dgit import, upstream changes]
48
49 [git-debrebase upstream-combine . PIECE[ PIECE...]: new upstream]
50 [git-debrebase anchor: new upstream NEW-UPSTREAM-VERSION, merge]
51 [git-debrebase: new upstream NEW-UPSTREAM-VERSION, changelog]
52
53 [git-debrebase convert-from-gbp: drop patches]
54 [git-debrebase anchor: declare upstream]
55 [git-debrebase pseudomerge: stitch]
56
57 [git-debrebase convert-to-gbp: commit patches]
58
59 m{^\[git-debrebase (?:\w*-)?upstream combine \.((?: $extra_orig_namepart_re)+)\]}
60
61 Every anchor commit must be a merge.  In principle, this is not
62 necessary.  After all, we are relying on the
63     [git-debrebase anchor: ...]
64 commit message annotation in "declare" anchor merges (which
65 do not have any upstream changes), to distinguish those anchor
66 merges from ordinary pseudomerges (which we might just try to strip).
67
68 However, the user is going to be doing git-rebase a lot.  We really
69 don't want them to rewrite an anchor commit.  git-rebase
70 trips up on merges, so that is a useful safety catch.
71
72
73 =========
74
75 workflow
76
77   git-debrebase blah [implies start]       strips pseudomerge(s)
78
79   commit / git-debrebase / etc.
80
81   dgit --damp-run push
82       hook: call git-debrebase prep-push   adds new pm ? passes --overwrite ?
83                                            dgit push does not update remote
84
85   commit / git-debrebase / etc.            strips pm(s) including last one
86
87   dgit push
88       hook: call git-debrebase prep-push   adds new pm ? passes --overwrite ?
89                                            dgit push DOES update remote
90
91   commit / git-debrebase / etc.            strips last pm, but arranges
92                                            that remade pm will incorporate it
93
94 Aha!
95
96 When we strip a pm, we need to maybe record it (or something) as the
97 new start point.
98
99 We do this if the pm is contained within the output branch.
100
101 Actually this is not special to PMs.
102
103 We need to record a new to-be-overwritten commit
104    merge-base( our branch tip, relevant remote )
105
106 If this is not a descendant of the relevant remote, then we are going
107 to have a problem when we push so issue a warning or fail.
108
109
110
111 How about
112
113   git-debrebase start or git-debrebase [continue]
114
115     with no recorded will-overwrite
116
117         putative will-overwrite is 
118             one model:
119                 our current tip
120                 obviously it is safe to say we will overwrite this
121                 we do not need to worry about whether this will
122                     overwrite not-included changes in the remote
123                     because either the will-overwrite is not
124                     ff from the remote (in which case later failure,
125                     see below); or the will-overwrite _is_ ff
126                     from the remote ie our tip is later than the
127                     remote and includes all of its changes
128
129                 this model tends to keep ad-hoc commits made on our
130                 tip branch before we did rebase start, in the
131                 `interchange view' and also in the rebase stack.
132
133             other model:
134                 merge-base( current remote, current tip )
135
136                 it is safe to overwrite current tip, by the
137                 argument above
138
139                 it is always safe to rewind will-overwrite: all
140                 that does is overwrite _less_ stuff
141
142                 this is the earliest overwrite we can make that
143                     will be pushable to the remote
144
145                 in practical terms this can only be ff from the
146                 current remote if it is equal to the current remote;
147                 so what we are actually checking below is that our tip
148                 is ff from the remote.  This ought to be true before
149                 the first of our rebases.
150
151                 this model tends to rewind and rebase ad-hoc commits
152                 made on our tip branch before we did rebase start,
153                 this is better
154
155         in any case putative will-overwrite must be ff from remote.
156         Otherwise when we push it will not be ff, even though we have
157         made pseudomerge to overwrite will-overwrite.  So if we spot
158         this, report an error.
159
160     with a recorded will-overwrite
161
162         we may need to advance will-overwrite, to allow us to generate
163         future pseudomerges that will be pushable
164
165         advancing will-overwrite is dangerous, since it might
166         effectively cancel the commits that will-ovewrite is advanced
167         over.
168
169         we advance it to merge-base( current remote, current tip )
170         if possible (see above), - ie to current remote, subject
171         to the condition that that is an ancestor of current tip
172
173 In each case we can strip pseudomerges freely, as needed.  We do not
174 want to record what pseudomerges we strip, because whether we need to
175 keep them depends (only) on whether they have been pushed.
176
177 Is that actually true ?  What if the user actually _wanted_ to keep
178 the pseudomerge despite not having pushed it ?
179
180 In that case we need to advance will-overwrite past it.  We could
181 provide an explicit command to do this: it would advance
182 will-overwrite to the current tip (see rules above, which show that
183 this is OK).  Or maybe to the last pseudomerge on the current tip,
184 so that the overall result will be series of pseudomerges.
185
186 ========================================
187
188 So, pm handling specifics:
189
190 strategy is to avoid making needless pseudomerges
191 pseudomerges that exist will be preserved
192 (by being included in will-overwrite)
193
194 This is good because the presence of a pseudomerge means we know we
195 want to keep it; and that allows explicit control over history detail
196 level.
197
198 It does mean we must avoid making the pseudomerges unnecessarily.
199 They should be made just before (ideally, part of) dgit push.
200
201 1. git-debrebase [-i etc.]
202
203      should:
204         check for will-overwrite
205         if is already a will-overwrite, fine, do no more
206         if not:
207
208         check our origin branch exists and we are ff from it
209         if not fail
210
211         check our other might-be-pushed to branches
212         check we are ff from them
213         if not fail
214
215         set will-overwrite to something which is ff from
216           all above branches
217
218         we use our tip, as discussed above
219         (optionally, can use some other commit which is ff
220          from all of the above, eg one of them)
221
222 N. git-debrebase [--noop-ok] record-ffq-prev
223
224      does what is described above
225
226 2. git-debrebase [--noop-ok] stitch
227
228     makes pseudomerge with will-overwrite
229     deletes will-overwrite
230
231     we will teach dgit to do
232        git-debrebase stitch
233
234 3. git-debrebase push
235
236     like git push only does stitch first
237     ??? command line parsing!
238
239 4. git-debrebase release
240
241     stiches, finalises changelog, signs tags, pushes everything
242     for the future, when there is some automatic builder
243
244 will-overwrite for each ref
245     refs/heads/FOO
246 is
247     refs/ffq-prev/FOO
248
249 ========================================
250
251 import from gbp
252
253 [ all this is done now:
254  inputs:
255    current HEAD (patches-unapplied),
256      this is going to be the base of the old breakwater
257    nominated upstream
258
259  checks:
260    HEAD:<upstream> = upstream:<upstream>
261    upstream..HEAD:<upstream> is empty (overrideable)
262    upstremm:debian is empty (overrideable)
263
264  procedure:
265    construct
266      run gbp pq import to generate pq branch
267      new breakwater is
268        old HEAD
269        commit to remove d/patches
270        anchor merge with upstream
271        "rebase" of pq branch, each commit with d/patches stripped
272 ]
273
274 what about dgit view branch ?
275 ideally, would make pseudomerge over dgit view
276 would need to check that dgit view is actually dgit view of
277   ond of our ancestors
278 failing that first push will need --overwrite
279
280 ========================================
281
282 divergence, merges:
283
284 same problem
285  if merge, look at branches before merge
286  generate new combined branch
287  pseudomerge to overwrite merge
288
289 current avaiable strategies:
290
291  maybe launder foreign branch
292
293  if foreign branch is nmuish, can rebase it onto ours
294
295  could merge breakwaters (use analyse to find them)
296  merge breakwaters (assuming same upstream)
297  manually construct new patch queue by inspection of
298   the other two patch queues
299
300  instead of manually constructing patch queue, could use
301   gbp pq export and git merge the patch queues
302   (ie work with interdiffs)
303
304  if upstreams are different and one is ahead
305   simply treat that as "ours" and
306   do the work to import changes from the other
307
308  if upstreams have diverged, can
309   resolve somehow to make new upstream
310   do new-upstream on each branch separately
311   now reduced to previously "solved" problem
312
313  in future, auto patch queue merge algorithm
314   determine next patch to apply
315   there are three versions o..O, l..L, r..R
316   we have already constructed m (previous patch or merged breakwater)
317   try using vector calculus in the implied cube and compute
318    multiple ways to check consistency ?