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