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