X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=dgit.git;a=blobdiff_plain;f=NOTES.git-debrebase;h=97038733dca16ae3337a2a29c1e7a41be0be21ab;hp=635f72bbbc5ddde5a431e0d8720f9496ac447f5c;hb=8872ad84313c7a9175c7dfbd63b4c94bc4df6d51;hpb=1f4480c7fe42d8e997db608c35a3500de1052528 diff --git a/NOTES.git-debrebase b/NOTES.git-debrebase index 635f72bb..97038733 100644 --- a/NOTES.git-debrebase +++ b/NOTES.git-debrebase @@ -1,33 +1,20 @@ +TODO + reference docs + git-debrebase(5) data model + git-debrebase(1) command line + tutorial + dgit-maint-debrebase(7) + someone should set branch..mergeOptions to include --ff-only ? -# -# git-ffqrebase start [BASE] -# # records previous HEAD so it can be overwritten -# # records base for future git-ffqrebase -# git-ffqrebase set-base BASE -# git-ffqrebase -# git-ffqrebase finish -# git-ffqrebase status [BRANCH] -# -# refs/ffqrebase-prev/BRANCH BRANCH may be refs/...; if not it means -# refs/ffqrebase-base/BRANCH refs/heads/BRANCH -# zero, one, or both of these may exist -# -# git-debrebase without start, if already started, is willing -# to strip pseudomerges provided that they overwrite exactly -# the previous HEAD -# xxxx is this right ? what matters is have we pushed -# I think in fact the right answer is: -# git-debrebase always strips out pseudomerges from its branch -# a pseudomerge is put in at the time we want to push -# at that time, we make a pseudomerge of the remote tracking -# branch (if raw git) or the dgit view (if dgit) -# for raw git git-ffqrebase, do want preciseley to record -# value of remote tracking branch or our branch, on start, so we -# overwrite only things we intend to -# the previous pseudomerge check for tags and remote branches ? - - -========= + clean up remains of NOTES and README + + arrange for dgit to automatically stitch on push + +======================================== + +# refs/ffq-prev/REF relates to refs/REF + +======================================= special commit tags overall format @@ -36,18 +23,32 @@ overall format [git-debrebase: split mixed commit, debian part] [git-debrebase: split mixed commit, upstream-part] [git-debrebase: convert dgit import, debian changes] -[git-debrebase breakwater: convert dgit import, upstream changes] +[git-debrebase anchor: convert dgit import, upstream changes] [git-debrebase upstream-combine . PIECE[ PIECE...]: new upstream] -[git-debrebase breakwater: new upstream NEW-UPSTREAM-VERSION, merge] +[git-debrebase anchor: new upstream NEW-UPSTREAM-VERSION, merge] [git-debrebase: new upstream NEW-UPSTREAM-VERSION, changelog] -[git-debrebase: gbp2debrebase, drop patches] -[git-debrebase breakwater: declare upstream] +[git-debrebase convert-from-gbp: drop patches] +[git-debrebase anchor: declare upstream] +[git-debrebase pseudomerge: stitch] + +[git-debrebase convert-to-gbp: commit patches] m{^\[git-debrebase (?:\w*-)?upstream combine \.((?: $extra_orig_namepart_re)+)\]} -========= +Every anchor commit must be a merge. In principle, this is not +necessary. After all, we are relying on the + [git-debrebase anchor: ...] +commit message annotation in "declare" anchor merges (which +do not have any upstream changes), to distinguish those anchor +merges from ordinary pseudomerges (which we might just try to strip). + +However, the user is going to be doing git-rebase a lot. We really +don't want them to rewrite an anchor commit. git-rebase +trips up on merges, so that is a useful safety catch. + +======================================= workflow @@ -56,114 +57,125 @@ workflow commit / git-debrebase / etc. dgit --damp-run push - hook: call git-debrebase prep-push adds new pm ? passes --overwrite ? - dgit push does not update remote + hook: call git-debrebase prep-push dgit push does not update remote + or something, must add patches at least - commit / git-debrebase / etc. strips pm(s) including last one + commit / git-debrebase / etc. strips patches dgit push - hook: call git-debrebase prep-push adds new pm ? passes --overwrite ? - dgit push DOES update remote + hook: call git-debrebase prep-push dgit push DOES update remote commit / git-debrebase / etc. strips last pm, but arranges that remade pm will incorporate it -Aha! +======================================== + +Theory for ffq-prev When we strip a pm, we need to maybe record it (or something) as the new start point. -We do this if the pm is contained within the output branch. +When we do a thing -Actually this is not special to PMs. + with no recorded ffq-prev -We need to record a new to-be-overwritten commit - merge-base( our branch tip, relevant remote ) + ffq-prev is our current tip -If this is not a descendant of the relevant remote, then we are going -to have a problem when we push so issue a warning or fail. + obviously it is safe to say we will overwrite this + we do check whether there are not-included changes in the remotes + because if the new ffq-prev is not ff from the remotes + the later pushes will fail + this model tends to keep ad-hoc commits made on our + tip branch before we did rebase start, in the + `interchange view' and also in the rebase stack. + also we can explicitly preserve with + git-debrebase stitch -How about + It is always safe to rewind ffq-prev: all + that does is overwrite _less_ stuff. - git-debrebase start or git-debrebase [continue] + in any case putative ffq-prev must be ff from remote. + Otherwise when we push it will not be ff, even though we have + made pseudomerge to overwrite ffq-prev. So if we spot + this, report an error. see above - with no recorded will-overwrite + with a recorded ffq-prev - putative will-overwrite is - one model: - our current tip - obviously it is safe to say we will overwrite this - we do not need to worry about whether this will - overwrite not-included changes in the remote - because either the will-overwrite is not - ff from the remote (in which case later failure, - see below); or the will-overwrite _is_ ff - from the remote ie our tip is later than the - remote and includes all of its changes + we may need to advance ffq-prev, to allow us to generate + future pseudomerges that will be pushable - this model tends to keep ad-hoc commits made on our - tip branch before we did rebase start, in the - `interchange view' and also in the rebase stack. + advancing ffq-prev is dangerous, since it might + effectively cancel the commits that will-ovewrite is advanced + over. - other model: - merge-base( current remote, current tip ) + ??? advance it to merge-base( current remote, current tip ) + if possible (see above), - ie to current remote, subject + to the condition that that is an ancestor of current tip - it is safe to overwrite current tip, by the - argument above + currently this is not implemented - it is always safe to rewind will-overwrite: all - that does is overwrite _less_ stuff + better maybe to detect divergence ? but it is rather late + by then! - this is the earliest overwrite we can make that - will be pushable to the remote +We check we are ff from remotes before recording new ffq-prev - in practical terms this can only be ff from the - current remote if it is equal to the current remote; - so what we are actually checking below is that our tip - is ff from the remote. This ought to be true before - the first of our rebases. + ---------- now follows much the same info in different words ---------- - this model tends to rewind and rebase ad-hoc commits - made on our tip branch before we did rebase start, - this is better +1. git-debrebase [-i etc.] - in any case putative will-overwrite must be ff from remote. - Otherwise when we push it will not be ff, even though we have - made pseudomerge to overwrite will-overwrite. So if we spot - this, report an error. + should: + check for ffq-prev + if is already a ffq-prev, fine, do no more + if not: - with a recorded will-overwrite + check our origin branch exists and we are ff from it + if not fail - we may need to advance will-overwrite, to allow us to generate - future pseudomerges that will be pushable + check our other might-be-pushed to branches + check we are ff from them + if not fail - advancing will-overwrite is dangerous, since it might - effectively cancel the commits that will-ovewrite is advanced - over. + set ffq-prev to something which is ff from + all above branches - we advance it to merge-base( current remote, current tip ) - if possible (see above), - ie to current remote, subject - to the condition that that is an ancestor of current tip + we use our tip, as discussed above + (optionally, can use some other commit which is ff + from all of the above, eg one of them) -In each case we can strip pseudomerges freely, as needed. We do not -want to record what pseudomerges we strip, because whether we need to -keep them depends (only) on whether they have been pushed. +N. git-debrebase [--noop-ok] record-ffq-prev -Is that actually true ? What if the user actually _wanted_ to keep -the pseudomerge despite not having pushed it ? + does what is described above -In that case we need to advance will-overwrite past it. We could -provide an explicit command to do this: it would advance -will-overwrite to the current tip (see rules above, which show that -this is OK). Or maybe to the last pseudomerge on the current tip, -so that the overall result will be series of pseudomerges. +2. git-debrebase [--noop-ok] stitch + + makes pseudomerge with ffq-prev + deletes ffq-prev + + we will teach dgit to do + git-debrebase stitch + +3. git-debrebase push + + like git push only does stitch first + ??? command line parsing! + +4. git-debrebase release + + stiches, finalises changelog, signs tags, pushes everything + for the future, when there is some automatic builder + +ffq-prev for each ref + refs/heads/FOO +is + refs/ffq-prev/FOO ======================================== import from gbp +[ all this is done now: inputs: current HEAD (patches-unapplied), this is going to be the base of the old breakwater @@ -180,11 +192,62 @@ import from gbp new breakwater is old HEAD commit to remove d/patches - breakwater pseudomerge with upstream + anchor merge with upstream "rebase" of pq branch, each commit with d/patches stripped +] what about dgit view branch ? ideally, would make pseudomerge over dgit view would need to check that dgit view is actually dgit view of ond of our ancestors failing that first push will need --overwrite + +======================================== + +how to handle divergence and merges (if not detected soon enough) + +same problem + if merge, look at branches before merge + generate new combined branch + pseudomerge to overwrite merge + +current avaiable strategies: + + maybe launder foreign branch + + if foreign branch is nmuish, can rebase it onto ours + + could merge breakwaters (use analyse to find them) + merge breakwaters (assuming same upstream) + manually construct new patch queue by inspection of + the other two patch queues + + instead of manually constructing patch queue, could use + gbp pq export and git merge the patch queues + (ie work with interdiffs) + + if upstreams are different and one is ahead + simply treat that as "ours" and + do the work to import changes from the other + + if upstreams have diverged, can + resolve somehow to make new upstream + do new-upstream on each branch separately + now reduced to previously "solved" problem + + in future, auto patch queue merge algorithm + determine next patch to apply + there are three versions o..O, l..L, r..R + we have already constructed m (previous patch or merged breakwater) + try using vector calculus in the implied cube and compute + multiple ways to check consistency ? + +======================================== + +# git-ffqrebase start [BASE] +# # records previous HEAD so it can be overwritten +# # records base for future git-ffqrebase +# git-ffqrebase set-base BASE +# git-ffqrebase +# git-ffqrebase finish +# git-ffqrebase status [BRANCH]