chiark / gitweb /
git-debrebase(5): wip, converting from README
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 18 Feb 2018 21:14:14 +0000 (21:14 +0000)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 16 Jun 2018 15:06:59 +0000 (16:06 +0100)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
.gitignore
Makefile
README.git-debrebase
git-debrebase.5.pod [new file with mode: 0644]

index 13e2c4b..8397a80 100644 (file)
@@ -12,4 +12,5 @@ dgit-maint-native.7
 dgit-maint-merge.7
 dgit-maint-gbp.7
 dgit-sponsorship.7
+git-debrebase.5
 substituted
index 7e6ece3..c1470a1 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -27,6 +27,7 @@ bindir=$(prefix)/bin
 mandir=$(prefix)/share/man
 perldir=$(prefix)/share/perl5
 man1dir=$(mandir)/man1
+man5dir=$(mandir)/man5
 man7dir=$(mandir)/man7
 infraexamplesdir=$(prefix)/share/doc/dgit-infrastructure/examples
 txtdocdir=$(prefix)/share/doc/dgit
@@ -35,6 +36,8 @@ absurddir=$(prefix)/share/dgit/absurd
 PROGRAMS=dgit dgit-badcommit-fixup git-debrebase
 MAN1PAGES=dgit.1
 
+MAN5PAGES=git-debrebase.5
+
 MAN7PAGES=dgit.7                               \
        dgit-user.7 dgit-nmu-simple.7           \
        dgit-maint-native.7                     \
@@ -54,7 +57,9 @@ INFRA_PERLMODULES= \
        Debian/Dgit/Infra.pm \
        Debian/Dgit/Policy/Debian.pm
 
-all:   $(MAN7PAGES) $(addprefix substituted/,$(PROGRAMS))
+MANPAGES=$(MAN1PAGES) $(MAN5PAGES) $(MAN7PAGES)
+
+all:   $(MANPAGES) $(addprefix substituted/,$(PROGRAMS))
 
 substituted/%: %
        mkdir -p substituted
@@ -67,6 +72,7 @@ install:      installdirs all
        $(INSTALL_PROGRAM) $(addprefix absurd/,$(ABSURDITIES)) \
                $(DESTDIR)$(absurddir)
        $(INSTALL_DATA) $(MAN1PAGES) $(DESTDIR)$(man1dir)
+       $(INSTALL_DATA) $(MAN5PAGES) $(DESTDIR)$(man5dir)
        $(INSTALL_DATA) $(MAN7PAGES) $(DESTDIR)$(man7dir)
        $(INSTALL_DATA) $(TXTDOCS) $(DESTDIR)$(txtdocdir)
        set -e; for m in $(PERLMODULES); do \
@@ -75,7 +81,8 @@ install:      installdirs all
 
 installdirs:
        $(INSTALL_DIR) $(DESTDIR)$(bindir) \
-               $(DESTDIR)$(man1dir) $(DESTDIR)$(man7dir) \
+               $(DESTDIR)$(man1dir) $(DESTDIR)$(man5dir) \
+               $(DESTDIR)$(man7dir) \
                $(DESTDIR)$(txtdocdir) $(DESTDIR)$(absurddir) \
                $(addprefix $(DESTDIR)$(perldir)/, $(dir $(PERLMODULES)))
 
@@ -96,7 +103,7 @@ check installcheck:
 
 clean distclean mostlyclean maintainer-clean:
        rm -rf tests/tmp substituted
-       set -e; for m in $(MAN7PAGES); do \
+       set -e; for m in $(MANPAGES); do \
                test -e $$m.pod && rm -f $$m; \
        done
 
@@ -105,5 +112,10 @@ clean distclean mostlyclean maintainer-clean:
                --name=$(subst .7,,$@) \
                $^ $@
 
+git-debrebase.%: git-debrebase.%.pod
+       pod2man --section=$* --date="Debian Project" --center="git-debrebase" \
+               --name=$(subst .$*,,$@) \
+               $^ $@
+
 %.view:        %
        man -l $*
index ba00951..19ddbc0 100644 (file)
@@ -1,57 +1,5 @@
 
 
-My preferred answer is that it is a constantly rebasing branch topped
-with a series of pseudomerges to make it fast-forwarding.
-
-           ------/--A!----/--B3!--%--/--> interchange view
-                /        /          /      with debian/ directory
-               %        %          %       all upstream changes applied
-              /        /          /        3.0 (quilt) has debian/patches
-             /        /          3*
-            /        /          /
-           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-generated commit of debian/patches.
-              `3.0 (quilt)' only; dropped by rebase tool.
-
-      *       Maintainer's HEAD was here while they were editing,
-              before they said they were done, at which point their
-              tools generated [% and] -/- commit[s] to convert to
-              the fast-forwarding interchange branch.  (Maybe the
-              tooling is simply `dgit push'.)
-
-      !       NMUer's HEAD was here when they said `dgit push'.
-              Rebase branch launderer turns each ! into an
-              equivalent *.
-
-
-Looking from the tip of the interchange view, it is I think always
-possible to classify these commits appropriately: pseudomerges are
-fairly obvious (if all three trees are identical, we descend to the
-parent with the most recent commit date).  The `@' special merge is
-the only non-pseudo merge and has a special form; also, it will be
-generated only by our tools so can have an annotation in the commit
-message.
-
 So it would be possible to write a `git-debrebase' tool which would
 take (for example) B4, above, and be able to perform functions like:
 
@@ -83,18 +31,6 @@ take (for example) B4, above, and be able to perform functions like:
 Maybe some of these operations should automatically edit
 debian/changelog.
 
-Nonlinear (merging) history in the interchange branch is awkward
-because it (obviously) does not preserve the patch queue.
-
-Nonlinear (merging) history in the `packaging-only' branch is OK, if
-we could generate it.  We will use the commit message annotation to
-distinguish a merge of two `packaging-only' branches from the special
-merge `@'.  (Indeed I since upstream might copy debian/ from us,
-without the annotation and knowledge of the construction order it is
-not easy to reliably distinguish the two parents of a `@'.  In the
-most exciting edge case, upstream might `git merge' a previous
-instance of our interchange view, but I think even then everything
-still works.)
 
 Sean Whitton writes ("Re: Feedback on 3.0 source format problems"):
 >  Does the [breakwater] branch contain debian/ alone?
diff --git a/git-debrebase.5.pod b/git-debrebase.5.pod
new file mode 100644 (file)
index 0000000..f207c95
--- /dev/null
@@ -0,0 +1,309 @@
+=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 changes to upstream files are 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 Debian.
+
+git-debrebase 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.
+
+=head1 DIAGRAM
+
+           ------/--A!----/--B3!--%--/--> interchange view
+                /        /          /      with debian/ directory
+               %        %          %       all upstream changes applied
+              /        /          /        3.0 (quilt) has debian/patches
+             /        /          3*
+            /        /          /
+           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-generated commit of debian/patches.
+              `3.0 (quilt)' only; dropped by rebase tool.
+
+      *       Maintainer's HEAD was here while they were editing,
+              before they said they were done, at which point their
+              tools generated [% and] -/- commit[s] to convert to
+              the fast-forwarding interchange branch.  (Maybe the
+              tooling is simply `dgit push'.)
+
+      !       NMUer's HEAD was here when they said `dgit push'.
+              Rebase branch launderer turns each ! into an
+              equivalent *.
+
+=head1 BRANCHES AND BRANCH STATES
+
+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 owrk
+(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</STITCHING, PSEUDO-MERGES, FFQ RECORD>.
+
+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 ancenstry of the interchange branch,
+there is another importnt, 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 upstream).
+The breakwater does not contain any representation
+of Debian's changes to upstream files.
+The breakwater starts at an 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>.
+When a branch is unstitched,
+its previous tip is recorded so that it 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 changes to upstream files.
+
+=head1 BRANCH CONTENTS
+
+It is most convenient to describe the
+B<laundered>
+state first.
+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 is a previous breakwater branch,
+whose upstream files are irrelevant,
+and whose packaging files are identical to the anchor's.
+The second parent is an upstream source commit;
+whose packaging files (if any) are irrelevant,
+and whose 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 changes to B<debian/patches/>.)
+
+=item Delta from upstream
+
+Zero or more single-parent commits
+contaioning only changes to upstream files.
+
+=back
+
+The
+B<unstitched>
+(unlaundered)
+branch state is the same,
+except that it may contain,
+additionally,
+in B<in any order>:
+
+=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 no changes to B<debian/patches/>.)
+
+=item 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 or useful when working with
+packages in C<.dsc 3.0 (quilt)> format.
+
+=back
+
+The
+B<interchange>
+branch state is the same, but may 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 the interchange branch,
+but this is not necessary as the overwritten
+parent is not examined.
+
+=item dgit dsc import
+
+Debian .dsc source package import(s) made by dgit.
+Each such import must be a two-parent pseudomerge
+whose contributing parent is in the special
+dgit format (not described further here).
+The overwritten parent must be
+the previous interchange tip
+(and will be generated that way by normal use of dgit).
+
+=back
+
+=head1 STITCHING, PSEUDO-MERGES, FFQ RECORD
+
+Whenever the branch C<refs/B> is unstitched,
+the previous tip is recorded in the git ref C<refs/ffq-prev/heads/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 unstituched 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 Debian changes to upstream files,
+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.
+
+=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.
+
+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 qeustions 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 TERMINOLOGY
+
+=over
+
+=item Pseudomerge
+
+A merge which does not actually merge the trees;
+instead, it takes its tree by construction from one parent.
+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/>.
+(Does not include anything which may exist in B<debian/patches/>.)
+
+=item Upstream
+
+The version of the package without Debian's packaging.
+Typically provided by the actual upstream project,
+and often tracked by Debian contributors in a branch C<upstream>.
+
+=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.
+
+=back
+
+=head1 SEE ALSO
+
+dgit(1), dgit(7), dgit-maint-*(7)