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