chiark / gitweb /
ac5a72336b0dab1dce5040e7fa8192f00ac21690
[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
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 breakwater: convert dgit import, upstream changes]
48
49 [git-debrebase upstream-combine . PIECE[ PIECE...]: new upstream]
50 [git-debrebase breakwater: new upstream NEW-UPSTREAM-VERSION, merge]
51 [git-debrebase: new upstream NEW-UPSTREAM-VERSION, changelog]
52
53 [git-debrebase: gbp2debrebase, drop patches]
54 [git-debrebase breakwater: declare upstream]
55 [git-debrebase pseudomerge: stitch]
56
57 m{^\[git-debrebase (?:\w*-)?upstream combine \.((?: $extra_orig_namepart_re)+)\]}
58
59 Every breakwater commit must be a merge.  In principle, this is not
60 necessary.  After all, we are relying on the
61     [git-debrebase breakwater: ...]
62 commit message annotation in "declare" breakwater merges (which
63 do not have any upstream changes), to distinguish those breakwater
64 merges from ordinary pseudomerges (which we might just try to strip).
65
66 However, the user is going to be doing git-rebase a lot.  We really
67 don't want them to rewrite a breakwater base commit.  git-rebase
68 trips up on merges, so that is a useful safety catch.
69
70
71 =========
72
73 workflow
74
75   git-debrebase blah [implies start]       strips pseudomerge(s)
76
77   commit / git-debrebase / etc.
78
79   dgit --damp-run push
80       hook: call git-debrebase prep-push   adds new pm ? passes --overwrite ?
81                                            dgit push does not update remote
82
83   commit / git-debrebase / etc.            strips pm(s) including last one
84
85   dgit push
86       hook: call git-debrebase prep-push   adds new pm ? passes --overwrite ?
87                                            dgit push DOES update remote
88
89   commit / git-debrebase / etc.            strips last pm, but arranges
90                                            that remade pm will incorporate it
91
92 Aha!
93
94 When we strip a pm, we need to maybe record it (or something) as the
95 new start point.
96
97 We do this if the pm is contained within the output branch.
98
99 Actually this is not special to PMs.
100
101 We need to record a new to-be-overwritten commit
102    merge-base( our branch tip, relevant remote )
103
104 If this is not a descendant of the relevant remote, then we are going
105 to have a problem when we push so issue a warning or fail.
106
107
108
109 How about
110
111   git-debrebase start or git-debrebase [continue]
112
113     with no recorded will-overwrite
114
115         putative will-overwrite is 
116             one model:
117                 our current tip
118                 obviously it is safe to say we will overwrite this
119                 we do not need to worry about whether this will
120                     overwrite not-included changes in the remote
121                     because either the will-overwrite is not
122                     ff from the remote (in which case later failure,
123                     see below); or the will-overwrite _is_ ff
124                     from the remote ie our tip is later than the
125                     remote and includes all of its changes
126
127                 this model tends to keep ad-hoc commits made on our
128                 tip branch before we did rebase start, in the
129                 `interchange view' and also in the rebase stack.
130
131             other model:
132                 merge-base( current remote, current tip )
133
134                 it is safe to overwrite current tip, by the
135                 argument above
136
137                 it is always safe to rewind will-overwrite: all
138                 that does is overwrite _less_ stuff
139
140                 this is the earliest overwrite we can make that
141                     will be pushable to the remote
142
143                 in practical terms this can only be ff from the
144                 current remote if it is equal to the current remote;
145                 so what we are actually checking below is that our tip
146                 is ff from the remote.  This ought to be true before
147                 the first of our rebases.
148
149                 this model tends to rewind and rebase ad-hoc commits
150                 made on our tip branch before we did rebase start,
151                 this is better
152
153         in any case putative will-overwrite must be ff from remote.
154         Otherwise when we push it will not be ff, even though we have
155         made pseudomerge to overwrite will-overwrite.  So if we spot
156         this, report an error.
157
158     with a recorded will-overwrite
159
160         we may need to advance will-overwrite, to allow us to generate
161         future pseudomerges that will be pushable
162
163         advancing will-overwrite is dangerous, since it might
164         effectively cancel the commits that will-ovewrite is advanced
165         over.
166
167         we advance it to merge-base( current remote, current tip )
168         if possible (see above), - ie to current remote, subject
169         to the condition that that is an ancestor of current tip
170
171 In each case we can strip pseudomerges freely, as needed.  We do not
172 want to record what pseudomerges we strip, because whether we need to
173 keep them depends (only) on whether they have been pushed.
174
175 Is that actually true ?  What if the user actually _wanted_ to keep
176 the pseudomerge despite not having pushed it ?
177
178 In that case we need to advance will-overwrite past it.  We could
179 provide an explicit command to do this: it would advance
180 will-overwrite to the current tip (see rules above, which show that
181 this is OK).  Or maybe to the last pseudomerge on the current tip,
182 so that the overall result will be series of pseudomerges.
183
184 ========================================
185
186 So, pm handling specifics:
187
188 strategy is to avoid making needless pseudomerges
189 pseudomerges that exist will be preserved
190 (by being included in will-overwrite)
191
192 This is good because the presence of a pseudomerge means we know we
193 want to keep it; and that allows explicit control over history detail
194 level.
195
196 It does mean we must avoid making the pseudomerges unnecessarily.
197 They should be made just before (ideally, part of) dgit push.
198
199 1. git-debrebase [-i etc.]
200
201      should:
202         check for will-overwrite
203         if is already a will-overwrite, fine, do no more
204         if not:
205
206         check our origin branch exists and we are ff from it
207         if not fail
208
209         check our other might-be-pushed to branches
210         check we are ff from them
211         if not fail
212
213         set will-overwrite to something which is ff from
214           all above branches
215
216         we use our tip, as discussed above
217         (optionally, can use some other commit which is ff
218          from all of the above, eg one of them)
219
220 N. git-debrebase [--noop-ok] record-ffq-prev
221
222      does what is described above
223
224 2. git-debrebase [--noop-ok] stitch
225
226     makes pseudomerge with will-overwrite
227     deletes will-overwrite
228
229     we will teach dgit to do
230        git-debrebase stitch
231
232 3. git-debrebase push
233
234     like git push only does stitch first
235     ??? command line parsing!
236
237 4. git-debrebase release
238
239     stiches, finalises changelog, signs tags, pushes everything
240     for the future, when there is some automatic builder
241
242 will-overwrite for each ref
243     refs/heads/FOO
244 is
245     refs/ffq-prev/FOO
246
247 ========================================
248
249 import from gbp
250
251 [ all this is done now:
252  inputs:
253    current HEAD (patches-unapplied),
254      this is going to be the base of the old breakwater
255    nominated upstream
256
257  checks:
258    HEAD:<upstream> = upstream:<upstream>
259    upstream..HEAD:<upstream> is empty (overrideable)
260    upstremm:debian is empty (overrideable)
261
262  procedure:
263    construct
264      run gbp pq import to generate pq branch
265      new breakwater is
266        old HEAD
267        commit to remove d/patches
268        breakwater pseudomerge with upstream
269        "rebase" of pq branch, each commit with d/patches stripped
270 ]
271
272 what about dgit view branch ?
273 ideally, would make pseudomerge over dgit view
274 would need to check that dgit view is actually dgit view of
275   ond of our ancestors
276 failing that first push will need --overwrite
277
278 should this be called import or gbp2debrebase as it is now ?
279 gbp uses "import" oddly but I'm tempted to use it normally here.