|author||Ian Jackson <firstname.lastname@example.org>||2018-02-18 21:14:14 +0000|
|committer||Ian Jackson <email@example.com>||2018-06-16 16:06:59 +0100|
git-debrebase(5): wip, converting from README
Signed-off-by: Ian Jackson <firstname.lastname@example.org>
4 files changed, 325 insertions, 67 deletions
@@ -12,4 +12,5 @@ dgit-maint-native.7
@@ -27,6 +27,7 @@ bindir=$(prefix)/bin
@@ -35,6 +36,8 @@ absurddir=$(prefix)/share/dgit/absurd
PROGRAMS=dgit dgit-badcommit-fixup git-debrebase
dgit-user.7 dgit-nmu-simple.7 \
@@ -54,7 +57,9 @@ INFRA_PERLMODULES= \
-all: $(MAN7PAGES) $(addprefix substituted/,$(PROGRAMS))
+MANPAGES=$(MAN1PAGES) $(MAN5PAGES) $(MAN7PAGES)
+all: $(MANPAGES) $(addprefix substituted/,$(PROGRAMS))
mkdir -p substituted
@@ -67,6 +72,7 @@ install: installdirs all
$(INSTALL_PROGRAM) $(addprefix absurd/,$(ABSURDITIES)) \
$(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
$(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; \
@@ -105,5 +112,10 @@ clean distclean mostlyclean maintainer-clean:
--name=$(subst .7,,$@) \
+ pod2man --section=$* --date="Debian Project" --center="git-debrebase" \
+ --name=$(subst .$*,,$@) \
+ $^ $@
man -l $*
diff --git a/README.git-debrebase b/README.git-debrebase
index ba00951..19ddbc0 100644
@@ -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
- 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
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
-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
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
@@ -0,0 +1,309 @@
+git-debrebase - git data model for Debian packaging
+git-debrebase is a tool for representing in git,
+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.
+ ------/--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
+ 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
+Within the ancenstry of the interchange branch,
+there is another importnt, implicit branch, the
+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
+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
+It contains B<in this order> (ancestors first):
+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.
+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.
+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.
+branch state is the same,
+except that it may contain,
+in B<in any order>:
+=item Linear commits to the source
+Further commit(s) containing changes to
+to upstream files
+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.
+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):
+=item Pseudomerge to make fast forward
+A pseudomerge making the branch fast forward from
+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).
+=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. 
+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.
+ 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,
+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.
+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/>.)
+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.
+=head1 SEE ALSO
+dgit(1), dgit(7), dgit-maint-*(7)