diff options
Diffstat (limited to 'git-debrebase.5.pod')
-rw-r--r-- | git-debrebase.5.pod | 611 |
1 files changed, 611 insertions, 0 deletions
diff --git a/git-debrebase.5.pod b/git-debrebase.5.pod new file mode 100644 index 0000000..e445c0e --- /dev/null +++ b/git-debrebase.5.pod @@ -0,0 +1,611 @@ +=head1 NAME + +git-debrebase - git data model for Debian packaging + +=head1 INTRODUCTION + +git-debrebase is a tool for representing in git, +and manpulating, +Debian packages based on upstream source code. + +The Debian packaging +has a fast forwarding history. +The delta queue (changes to upstream files) is represented +as a series of individual git commits, +which can worked on with rebase, +and also shared. + +git-debrebase is designed to work well with dgit. +git-debrebase can also be used in workflows without source packages, +for example to work on Debian-format packages outside or alongside Debian. + +git-debrebase +itself is not very suitable for use by Debian derivatives, +to work on packages inherited from Debian, +because it assumes that you want to throw away any packaging +provided by your upstream. +However, use of git-debrebase in Debian does not make anything harder for +derivatives, and it can make some things easier. + +=head1 TERMINOLOGY + +=over + +=item Pseudomerge + +A merge which does not actually merge the trees; +instead, it is constructed by taking the tree +from one of the parents +(ignoring the contents of the other parents). +These are used to make a rewritten history fast forward +from a previous tip, +so that it can be pushed and pulled normally. +Manual construction of pseudomerges can be done with +C<git merge -s ours> +but is not normally needed when using git-debrebase. + +=item Packaging files + +Files in the source tree within B<debian/>, +excluding anything in B<debian/patches/>. + +=item Upstream + +The version of the package without Debian's packaging. +Typically provided by the actual upstream project, +and sometimes tracked by Debian contributors in a branch C<upstream>. + +Upstream contains upstream files, +but some upstreams also contain packaging files in B<debian/>. +Any such non-upstream files found in upstream +are thrown away by git-debrebase +each time a new upstream version is incorporated. + +=item Upstream files + +Files in the source tree outside B<debian/>. +These may include unmodified source from upstream, +but also files which have been modified or created for Debian. + +=item Delta queue + +Debian's changes to upstream files: +a series of git commits. + +=item Quilt patches + +Files in B<debian/patches/> generated for the benefit of +dpkg-source's 3.0 (quilt) .dsc source package format. +Not used, often deleted, and regenerated when needed +(such as when uploading to Debian), +by git-debrebase. + +=item Interchange branch; breakwater; stitched; laundered + +See L</BRANCHES AND BRANCH STATES - OVERVIEW>. + +=item Anchor; Packaging + +See L</BRANCH CONTENTS - DETAILED SPECIFICATION>. + +=item ffq-prev; debrebase-last + +See L</STITCHING, PSEUDO-MERGES, FFQ RECORD>. + +=back + +=head1 DIAGRAM + + ------/--A!----/--B3!--%--/--> interchange view + / / / with debian/ directory + % % % entire delta queue applied + / / / 3.0 (quilt) has debian/patches + / / 3* "master" on Debian git servers + / / / + 2* 2* 2 + / / / + 1 1 1 breakwater branch, merging baseline + / / / unmodified upstream code + ---@-----@--A----@--B--C plus debian/ (but no debian/patches) + / / / no ref refers to this: we + --#-----#-------#-----> upstream reconstruct its identity by + inspecting interchange branch + Key: + + 1,2,3 commits touching upstream files only + A,B,C commits touching debian/ only + B3 mixed commit (eg made by an NMUer) + # upstream releases + + -@- anchor merge, takes contents of debian/ from the + / previous `breakwater' commit and rest from upstream + + -/- pseudomerge; contents are identical to + / parent lower on diagram. + + % dgit- or git-debrebase- generated commit of debian/patches. + `3.0 (quilt)' only; generally dropped by git-debrebase. + + * Maintainer's HEAD was here while they were editing, + before they said they were done, at which point their + tools made -/- (and maybe %) to convert to + the fast-forwarding interchange branch. + + ! NMUer's HEAD was here when they said `dgit push'. + Rebase branch launderer turns each ! into an + equivalent *. + +=head1 BRANCHES AND BRANCH STATES - OVERVIEW + +git-debrebase has one primary branch, +the B<interchange branch>. +This branch is found on Debian contributor's workstations +(typically, a maintainer would call it B<master>), +in the Debian dgit git server as the suite branch (B<dgit/dgit/sid>) +and on other git servers which support Debian work +(eg B<master> on salsa). + +The interchange branch is fast-forwarding +(by virtue of pseudomerges, where necessary). + +It is possible to have multiple different interchange branches +for the same package, +stored as different local and remote git branches. +However, divergence should be avoided where possible - +see L</OTHER MERGES>. + +A suitable interchange branch can be used directly with dgit. +In this case each dgit archive suite branch is a separate +interchange branch. + +Within the ancestry of the interchange branch, +there is another important, implicit branch, the +B<breakwater>. +The breakwater contains unmodified upstream source, +but with Debian's packaging superimposed +(replacing any C<debian/> directory that may be in +the upstream commits). +The breakwater does not contain any representation of +the delta queue (not even debian/patches). +The part of the breakwater processed by git-debrebase +is the part since the most reecent B<anchor>, +which is usually a special merge generated by git-debrebase. + +When working, locally, +the user's branch can be in a rebasing state, +known as B<unstitched>. +While a branch is unstitched, +it is not in interchange format. +The previous interchange branch tip +is recorded, +so that the previous history +and the user's work +can later be +stitched into the fast-forwarding interchange form. + +An unstitched branch may be in +B<laundered> +state, +which means it has a more particular special form +convenient for manipulating the delta queue. + +=head1 BRANCH CONTENTS - DETAILED SPECIFICATION + +It is most convenient to describe the +B<breakwater> +branch first. +A breakwater is B<fast-forwarding>, +but is not usually named by a ref. +It contains B<in this order> (ancestors first): + +=over + +=item Anchor + +An B<anchor> commit, +which is usually a special two-parent merge: + +The first parent +contains the most recent version, at that point, +of the Debian packaging (in debian/); +it also often contains upstream files, +but they are to be ignored. +Often the first parent is a previous breakwater tip. + +The second parent +is an upstream source commit. +It may sometimes contain a debian/ subdirectory, +but if so that is to be ignored. +The second parent's upstream files +are identical to the anchor's. +Anchor merges always contain +C<[git-debrebase anchor: ...]> +as a line in the commit message. + +Alternatively, +an anchor may be a single-parent commit which introduces +the C<debian/> directory and makes no other changes: +ie, the start of Debian packaging. + +=item Packaging + +Zero or more single-parent commits +containing only packaging changes. +(And no quilt patch changes.) + +=back + +The +B<laundered> +branch state is B<rebasing>. +A laundered branch is based on a breakwater +but also contains, additionally, +B<after> the breakwater, +a representation of the delta queue: + +=over + +=item Delta queue commits + +Zero or more single-parent commits +contaioning only changes to upstream files. + +=back + +The merely +B<unstitched> +(ie, unstitched but unlaundered) +branch state is also B<rebasing>. +It has the same contents as the laundered state, +except that it may contain, +additionally, +in B<in any order but after the breakwater>: + +=over + +=item Linear commits to the source + +Further commit(s) containing changes to +to upstream files +and/or +to packaging, +possibly mixed within a single commit. +(But not quilt patch changes.) + +=item Quilt patch addition for `3.0 (quilt)' + +Commit(s) which add patches to B<debian/patches/>, +and add those patches to the end of B<series>. + +These are only necessary when working with +packages in C<.dsc 3.0 (quilt)> format. +For git-debrebase they are purely an output; +they are deleted when branches are laundered. +git-debrebase takes care to make a proper patch +series out of the delta queue, +so that any resulting source packages are nice. + +=back + +Finally, an +B<interchange> +branch is B<fast forwarding>. +It has the same contents as an +unlaundered branch state, +but may (and usually will) additionally contain +(in some order, +possibly intermixed with the extra commits +which may be found on an unstitched unlaundered branch): + +=over + +=item Pseudomerge to make fast forward + +A pseudomerge making the branch fast forward from +previous history. +The contributing parent is itself in interchange format. +Normally the overwritten parent is +a previous tip of an interchange branch, +but this is not necessary as the overwritten +parent is not examined. + +If the two parents have identical trees, +the one with the later commit date +(or, if the commit dates are the same, +the first parent) +is treated as +the contributing parent. + +=item dgit dsc import pseudomerge + +Debian .dsc source package import(s) +made by dgit +(during dgit fetch of a package most recently +uploaded to Debian without dgit, +or during dgit import-dsc). + +git-debrebase requires that +each such import is in the fast-forwarding +format produced by dgit: +a two-parent pseudomerge, +whose contributing parent is in the +non-fast-forwarding +dgit dsc import format (not described further here), +and whose overwritten parent is +the previous interchange tip +(eg, the previous tip of the dgit suite branch). + +=back + +=head1 STITCHING, PSEUDO-MERGES, FFQ RECORD + +Whenever the branch C<refs/B> is unstitched, +the previous head is recorded in the git ref C<refs/ffq-prev/B>. + +Unstiched branches are not fast forward from the published +interchange branches [1]. +So before a branch can be pushed, +the right pseudomerge must be reestablished. +This is the stitch operation, +which consumes the ffq-prev ref. + +When the user has an unstitched branch, +they may rewrite it freely, +from the breakwater tip onwards. +Such a git rebase is the default operation for git-debrebase. +Rebases should not go back before the breakwater tip, +and certainly not before the most recent anchor. + +Unstitched branches must not be pushed to interchange branch refs +(by the use of C<git push -f> or equivalent). +It is OK to share an unstitched branch +in similar circumstances and with similar warnings +to sharing any other rebasing git branch. + +[1] Strictly, for a package +which has never had a Debian delta queue, +the interchange and breakwater branches may be identical, +in which case the unstitched branch is fast forward +from the interchange branch and no pseudomerge is needed. + +When ffq-prev is not present, +C<refs/debrebase-last/B> records some ancestor of refs/B, +(usually, the result of last stitch). +This can be used to quickly determine whether refs/B +is being maintained in git-debrebase form. + +=head1 OTHER MERGES + +Note that the representation described here does not permit +general merges on any of the relevant branches. +For this reason the tools will try to help the user +avoid divergence of the interchange branch. + +See dgit-maint-rebase(7) +for a discussion of what kinds of behaviours +should be be avoided +because +they might generate such merges. + +Automatic resolution of divergent interchange branches +(or laundering of merges on the interchange branch) +is thought to be possible, +but there is no tooling for this yet: + +Nonlinear (merging) history in the interchange branch is awkward +because it (obviously) does not preserve +the linearity of the delta queue. +Easy merging of divergent delta queues is a research problem. + +Nonlinear (merging) history in the breakwater branch is +in principle tolerable, +but each of the parents would have to be, in turn, +a breakwater, +and difficult questions arise if they don't have the same anchor. + +We use the commit message annotation to +distinguish the special anchor merges from other general merges, +so we can at least detect unsupported merges. + +=head1 LEGAL OPERATIONS + +The following basic operations follows from this model +(refer to the diagram above): + +=over + +=item Append linear commits + +No matter the branch state, +it is always fine to simply git commit +(or cherry-pick etc.) +commits containing upstream file changes, packaging changes, +or both. + +(This may make the branch unlaundered.) + +=item Launder branch + +Record the previous head in ffq-prev, +if we were stitched before +(and delete debrebase-last). + +Reorganise the current branch so that the packaging +changes come first, +followed by the delta queue, +turning C<-@-A-1-2-B3> into C<...@-A-B-1-2-3>. + +Drop pseudomerges and any quilt patch additions. + +=item Interactive rebase + +With a laundered branch, +one can do an interactive git rebase of the delta queue. + +=item New upstream rebase + +Start rebasing onto a new upstream version, +turning C<...#..@-A-B-1-2-3> into C<(...#..@-A-B-, ...#'-)@'-1-2>. + +This has to be a wrapper around git-rebase, +which prepares @' and then tries to rebase 1 2 onto @'. +If the user asks for an interactive rebase, +@' doesn't appear in the commit list, since +@' is the newbase of the rebase (see git-rebase(1)). + +Note that the construction of @' cannot fail +because @' simply copies debian/ from B and and everything else from #'. +(Rebasing A and B is undesirable. +We want the debian/ files to be non-rebasing +so that git log shows the packaging history.) + +=item Stitch + +Make a pseudomerge, +whose contributing parent to is the unstitched branch +and +whose overwritten parent is ffq-prev, +consuming ffq-prev in the process +(and writing debrebase-last instead). +Ideally the contributing parent would be a laundered branch, +or perhaps a laundered branch with a quilt patch addition commit. + +=item Commit quilt patches + +To generate a tree which can be represented as a +3.0 (quilt) .dsc source packages, +the delta queue must be reified inside the git tree +in B<debian/patches/>. +These patch files can be stripped out and/or regenerated as needed. + +=back + +=head1 COMMIT MESSAGE ANNOTATIONS + +git-debrebase makes annotations +in the messages of commits it generates. + +The general form is + + [git-debrebase[ COMMIT-TYPE [ ARGS...]]: PROSE, MORE PROSE] + +git-debrebase treats anything after the colon as a comment, +paying no attention to PROSE. + +The full set of annotations is: + [git-debrebase: split mixed commit, debian part] + [git-debrebase: split mixed commit, upstream-part] + [git-debrebase: convert dgit import, debian changes] + [git-debrebase anchor: convert dgit import, upstream changes] + + [git-debrebase upstream-combine . PIECE[ PIECE...]: new upstream] + [git-debrebase anchor: new upstream NEW-UPSTREAM-VERSION, merge] + [git-debrebase: new upstream NEW-UPSTREAM-VERSION, changelog] + [git-debrebase: export and commit patches] + + [git-debrebase convert-from-gbp: drop patches] + [git-debrebase anchor: declare upstream] + [git-debrebase pseudomerge: stitch] + + [git-debrebase convert-to-gbp: commit patches] + +Only anchor merges have the C<[git-debrebase anchor: ...]> tag. +Single-parent anchors are not generated by git-debrebase, +and when made manually should not +contain any C<[git-debrebase ...]> annotation. + +The C<split mixed commit> and C<convert dgit import> +tags are added to the pre-existing commit message, +when git-debrebase rewrites the commit. + +=head1 APPENDIX - DGIT IMPORT HANDLING + +The dgit .dsc import format is not documented or specified +(so some of the following terms are not defined anywhere). +The dgit import format it is defined by the implementation in dgit, +of which git-debrebase has special knowledge. + +Consider a non-dgit NMU followed by a dgit NMU: + + interchange --/--B3!--%--//----D*--> + / / + % 4 + / 3 + / 2 + / 1 + 2 &_ + / /| \ + 1 0 00 =XBC% + / + / + --@--A breakwater + / + --#--------> upstream + + + Supplementary key: + + =XBC% dgit tarball import of .debian.tar.gz containing + Debian packaging including changes B C and quilt patches + 0 dgit tarball import of upstream tarball + 00 dgit tarball import of supplementary upstream piece + &_ dgit import nearly-breakwater-anchor + // dgit fetch / import-dsc pseudomerge to make fast forward + + &' git-debrebase converted import (upstream files only) + C' git-debrebase converted packaging change import + + * ** before and after HEAD + +We want to transform this into: + +=over + +=item I. No new upstream version + + (0 + 00 eq #) + --/--B3!--%--//-----D*-------------/--> + / / / + % 4 4** + / 3 3 + / 2 2 + / 1 1 + 2 &_ / + / /| \ / + 1 0 00 =XBC% / + / / + / / + --@--A-----B---------------------C'---D + / + --#-----------------------------------------> + +=item II. New upstream + + (0 + 00 neq #) + + --/--B3!--%--//-----D*-------------/--> + / / / + % 4 4** + / 3 3 + / 2 2 + / 1 1 + 2 &_ / + / /| \ / + 1 0 00 =XBC% / + / / + / / + --@--A-----B-----------------@---C'---D + / / + --#--------------------- - - / - - ---------> + / + &' + /| + 0 00 + +=back + +=head1 SEE ALSO + +git-debrebase(1), +dgit-maint-rebase(7), +dgit(1) |