summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dgit-maint-debrebase.7.pod534
1 files changed, 534 insertions, 0 deletions
diff --git a/dgit-maint-debrebase.7.pod b/dgit-maint-debrebase.7.pod
new file mode 100644
index 0000000..0b4e756
--- /dev/null
+++ b/dgit-maint-debrebase.7.pod
@@ -0,0 +1,534 @@
+=head1 NAME
+
+dgit - tutorial for package maintainers, using a workflow centered around git-debrebase(1)
+
+=head1 INTRODUCTION
+
+This document describes elements of a workflow for maintaining a
+non-native Debian package using B<dgit>. We maintain the Debian delta
+as a series of git commits on our master branch. We use
+git-debrebase(1) to shuffle our branch such that this series of git
+commits appears at the end of the branch. This does not involve
+rewriting any public git history.
+
+Some advantages of this workflow:
+
+=over 4
+
+=item
+
+Manipulate the patch queue using the full power of git-rebase(1),
+instead of relying on quilt(1), and without having to switch away to
+another branch, as with gbp-pq(1).
+
+=item
+
+Avoid the git tree being dirtied by the application or unapplication
+of patches, as they are always applied.
+
+=item
+
+Benefit from dgit's safety catches. In particular, ensure that your
+upload always matches exactly your git HEAD.
+
+=item
+
+Provide your full git history in a standard format on B<dgit-repos>,
+where it can benefit downstream dgit users, such as people using dgit
+to do an NMU (see dgit-nmu-simple(7) and dgit-user(7)).
+
+=back
+
+This workflow is appropriate for packages where the Debian delta
+contains multiple pieces which interact, or which you don't expect to
+be able to upstream soon. For packages with simple and/or short-lived
+Debian deltas, use of git-debrebase(1) might introduce unneeded
+complexity. For such packages, consider the workflow described in
+dgit-maint-merge(7).
+
+=head1 INITIAL DEBIANISATION
+
+=head2 When upstream tags releases in git
+
+This section explains how to start using this workflow with a new
+package. It should be skipped when converting an existing package to
+this workflow.
+
+Suppose that the latest stable upstream release is 1.2.2, and this has
+been tagged '1.2.2' by upstream.
+
+=over 4
+
+ % git clone -oupstream https://some.upstream/foo.git
+ % cd foo
+ % git verify-tag 1.2.2
+ % git reset --hard 1.2.2
+ % git branch --unset-upstream
+
+=back
+
+The final command detaches your master branch from the upstream
+remote, so that git doesn't try to push anything there, or merge
+unreleased upstream commits. To maintain a copy of your packaging
+branch on B<salsa.debian.org> in addition to B<dgit-repos>, you can do
+something like this:
+
+=over 4
+
+ % git remote add -f origin salsa.debian.org:Debian/foo.git
+ % git push --follow-tags -u origin master
+
+=back
+
+Now go ahead and Debianise your package. Just make commits on the
+master branch, adding things in the I<debian/> directory. If you need
+to patch the upstream source, see "EDITING THE PATCH QUEUE", below.
+Note that there is no need to maintain a separate 'upstream' branch,
+unless you also happen to be involved in upstream development. We
+work with upstream tags rather than any branches, except when
+forwarding patches (see FORWARDING PATCHES UPSTREAM, below).
+
+Finally, you need an orig tarball:
+
+=over 4
+
+ % git deborig
+
+=back
+
+See git-deborig(1) if this fails.
+
+This tarball is ephemeral and easily regenerated, so we don't commit
+it anywhere (e.g. with tools like pristine-tar(1)).
+
+=head3 Verifying upstream's tarball releases
+
+=over 4
+
+It can be a good idea to compare upstream's released tarballs with the
+release tags, at least for the first upload of the package. If they
+are different, you might need to add some additional steps to your
+I<debian/rules>, such as running autotools.
+
+A convenient way to perform this check is to import the tarball as
+described in the following section, using a different value for
+'upstream-tag', and then use git-diff(1) to compare the imported
+tarball to the release tag. If they are the same, you can use
+upstream's tarball instead of running git-deborig(1).
+
+=back
+
+=head2 When upstream releases only tarballs
+
+We need a virtual upstream branch with virtual release tags.
+gbp-import-orig(1) can manage this for us. To begin
+
+=over 4
+
+ % mkdir foo
+ % cd foo
+ % git init
+
+=back
+
+Now create I<debian/gbp.conf>:
+
+=over 4
+
+ [DEFAULT]
+ upstream-branch = upstream
+ debian-branch = master
+ upstream-tag = %(version)s
+
+ sign-tags = True
+ pristine-tar = False
+ pristine-tar-commit = False
+
+ [import-orig]
+ merge-mode = merge
+
+=back
+
+gbp-import-orig(1) requires a pre-existing upstream branch:
+
+=over 4
+
+ % git add debian/gbp.conf && git commit -m "create gbp.conf"
+ % git checkout --orphan upstream
+ % git rm -rf .
+ % git commit --allow-empty -m "initial, empty branch for upstream source"
+ % git checkout -f master
+
+=back
+
+Then we can import the upstream version:
+
+=over 4
+
+ % gbp import-orig --merge-mode=replace ../foo_1.2.2.orig.tar.xz
+
+=back
+
+Our upstream branch cannot be pushed to B<dgit-repos>, but since we
+will need it whenever we import a new upstream version, we must push
+it somewhere. The usual choice is B<salsa.debian.org>:
+
+=over 4
+
+ % git remote add -f origin salsa.debian.org:Debian/foo.git
+ % git push --follow-tags -u origin master upstream
+
+=back
+
+You are now ready to proceed as above, making commits to the
+I<debian/> directory.
+
+=head1 CONVERTING AN EXISTING PACKAGE
+
+This section explains how to convert an existing Debian package to
+this workflow. It should be skipped when debianising a new package.
+
+=head2 No existing git history
+
+=over 4
+
+ % dgit clone foo
+ % cd foo
+ % git remote add -f upstream https://some.upstream/foo.git
+
+=back
+
+=head2 Existing git history using another workflow
+
+First, if you don't already have the git history locally, clone it,
+and obtain the corresponding orig.tar from the archive:
+
+=over 4
+
+ % git clone salsa.debian.org:Debian/foo
+ % cd foo
+ % origtargz
+
+=back
+
+If your tree is patches-unapplied, you will need to make a commit
+corresponding to each of the quilt patches. gbp-pq(1) can do this for
+us:
+
+=over 4
+
+ % gbp pq import
+ % gbp pq switch
+ % git merge --ff-only patch-queue/master
+ % gbp pq drop
+
+=back
+
+Then make new upstream tags available:
+
+=over 4
+
+ % git remote add -f upstream https://some.upstream/foo.git
+
+=back
+
+=for dgit-test dpkg-source-ignores begin
+
+Now you simply need to ensure that your git HEAD is dgit-compatible,
+i.e., it is exactly what you would get if you ran
+B<dpkg-buildpackage -i'(?:^|/)\.git(?:/|$)' -I.git -S>
+and then unpacked the resultant source package.
+
+=for dgit-test dpkg-source-ignores end
+
+To achieve this, you might need to delete
+I<debian/source/local-options>. One way to have dgit check your
+progress is to run B<dgit build-source>.
+
+The first dgit push will require I<--overwrite>. If this is the first
+ever dgit push of the package, consider passing
+I<--deliberately-not-fast-forward> instead of I<--overwrite>. This
+avoids introducing a new origin commit into your git history. (This
+origin commit would represent the most recent non-dgit upload of the
+package, but this should already be represented in your git history.)
+
+=head1 IMPORTING NEW UPSTREAM RELEASES
+
+=head2 Obtaining the release
+
+=head3 When upstream tags releases in git
+
+=over 4
+
+ % git remote update
+
+=back
+
+=head3 When upstream releases only tarballs
+
+You will need the I<debian/gbp.conf> from "When upstream releases only
+tarballs", above. You will also need your upstream branch. Above, we
+pushed this to B<salsa.debian.org>. You will need to clone or fetch
+from there, instead of relying on B<dgit clone>/B<dgit fetch> alone.
+
+Then, either
+
+=over 4
+
+ % gbp import-orig --no-merge ../foo_1.2.3.orig.tar.xz
+
+=back
+
+or if you have a working watch file
+
+=over 4
+
+ % gbp import-orig --no-merge --uscan
+
+=back
+
+=head2 Importing the release
+
+=over 4
+
+ % git debrebase new-upstream-v0 1.2.3
+ % dch -v1.2.3-1 New upstream release.
+ % git add debian/changelog && git commit -m changelog
+
+=back
+
+You can now review the merge of the new upstream release:
+
+=over 4
+
+ git diff debian/1.2.2-1..HEAD -- . ':!debian'
+
+=back
+
+Pass I<--stat> just to see the list of changed files, which is useful
+to determine whether there are any new or deleted files to may need
+accounting for in your copyright file.
+
+If you obtained a tarball from upstream, you are ready to try a build.
+If you merged a git tag from upstream, you will first need to generate
+a tarball:
+
+=over 4
+
+ % git deborig
+
+=back
+
+=head1 EDITING THE PATCH QUEUE
+
+=head2 Adding new patches
+
+Adding new patches is straightforward: just make commits touching only
+files outside of the I<debian/> directory. You can also use tools
+like git-revert(1), git-am(1) and git-cherrypick(1).
+
+=head2 Editing patches: starting a debrebase
+
+git-debrebase(1) is a wrapper around git-rebase(1) which allows us to
+edit, re-order and delete patches. Run
+
+=over 4
+
+ % git debrebase
+
+=back
+
+to start an interactive rebase. You can edit, re-order and delete
+commits just as you would during B<git rebase -i>. Alternatively, you
+can perform a non-interactive rebase like this:
+
+=over 4
+
+ % git debrebase -- [git-rebase options...]
+
+=back
+
+For example,
+
+=over 4
+
+ % git debrebase -- --autosquash
+
+=back
+
+A third alternative is to have git-debrebase(1) shuffle all the Debian
+changes to the end of your branch, and then manipulate them yourself
+using git-rebase(1). For example,
+
+=over 4
+
+ % git debrebase launder
+ % git rebase -i HEAD^5 # there are 4 Debian patches
+
+=back
+
+=head2 Editing patches: finishing a debrebase
+
+After completing the git rebase, your branch will not be a
+fast-forward of the git HEAD you had before the rebase. This means
+that we cannot push the branch anywhere. If you are ready to upload,
+B<dgit push> or B<dgit push-source> will take care of fixing this up
+for you.
+
+If you are not yet ready to upload, and want to push your branch to a
+git remote such as B<salsa.debian.org>,
+
+=over 4
+
+ % git debrebase stitch
+
+=back
+
+Note that each time you stitch a debrebase you introduce a pseudomerge
+into your git history, which may make it harder to read. Try to do
+all of the editing of the patch queue that you think will be needed
+for this upload in a single debrebase, so that there is a single
+debrebase stitch.
+
+A strategy is to debrebase only right before you upload. Before that
+point, instead of editing the existing patch series, you append fixup
+commits (and reversions of commits) that alter the upstream source to
+the required state. You can freely push and pull from
+B<salsa.debian.org> during this. Just before uploading, you debrebase
+to tidy everything up.
+
+=head1 BUILDING AND UPLOADING
+
+Use B<dgit build>, B<dgit sbuild>, B<dgit push> and B<dgit
+push-source> as detailed in dgit(1). If any command fails, dgit will
+provide a carefully-worded error message explaining what you should
+do. If it's not clear, file a bug against dgit. Remember to pass
+I<--new> for the first upload.
+
+After dgit pushing, be sure to git push to B<salsa.debian.org>, if
+you're using that.
+
+As an alternative to B<dgit build> and friends, you can use a tool
+like gitpkg(1). This works because like dgit, gitpkg(1) enforces that
+HEAD has exactly the contents of the source package. gitpkg(1) is
+highly configurable, and one dgit user reports using it to produce and
+test multiple source packages, from different branches corresponding
+to each of the current Debian suites.
+
+If you want to skip dgit's checks while iterating on a problem with
+the package build (for example, you don't want to commit your changes
+to git), you can just run dpkg-buildpackage(1) or debuild(1) instead.
+
+=head2 Laundering the patch queue before uploading
+
+Just before you B<dgit push> or B<dgit push-source>, you might want to
+have git-debrebase(1) shuffle your branch such that the Debian patch
+queue appears at the end:
+
+=over 4
+
+ % git debrebase launder
+ % dgit push-source
+
+=back
+
+Note that this will introduce a new pseudomerge.
+
+=head1 HANDLING DFSG-NON-FREE MATERIAL
+
+=head2 When upstream tags releases in git
+
+We create a DFSG-clean tag to import to master:
+
+=over 4
+
+ % git checkout -b pre-dfsg 1.2.3
+ % git rm evil.bin
+ % git commit -m "upstream version 1.2.3 DFSG-cleaned"
+ % git tag -s 1.2.3+dfsg
+ % git checkout master
+ % git branch -D pre-dfsg
+
+=back
+
+Before invoking B<git debrebase new-upstream-v0>, you should first
+determine whether it would be legally dangerous for the non-free
+material to be publicly accessible in the git history on
+B<dgit-repos>.
+
+If it would be dangerous, there is a big problem;
+in this case please consult your archive administrators
+(for Debian this is the dgit administrator dgit-owner@debian.org
+and the ftpmasters ftpmaster@ftp-master.debian.org).
+
+=head2 When upstream releases only tarballs
+
+The easiest way to handle this is to add a B<Files-Excluded> field to
+I<debian/copyright>, and a B<uversionmangle> setting in
+I<debian/watch>. See uscan(1). Alternatively, see the I<--filter>
+option detailed in gbp-import-orig(1).
+
+=head1 FORWARDING PATCHES UPSTREAM
+
+The basic steps are:
+
+=over 4
+
+=item 1.
+
+Create a new branch based off upstream's master branch.
+
+=item 2.
+
+git-cherry-pick(1) commits from your master branch onto your new
+branch.
+
+=item 3.
+
+Push the branch somewhere and ask upstream to merge it, or use
+git-format-patch(1) or git-request-pull(1).
+
+=back
+
+For example (and it is only an example):
+
+=over 4
+
+ % # fork foo.git on GitHub
+ % git remote add -f fork git@github.com:spwhitton/foo.git
+ % git checkout -b fix-error upstream/master
+ % git config branch.fix-error.pushRemote fork
+ % git cherry-pick master^2
+ % git push
+ % # submit pull request on GitHub
+
+=back
+
+Note that when you merge an upstream release containing your forwarded
+patches, a debrebase will transparently handle "dropping" the patches
+that have been forwarded, "retaining" the ones that haven't.
+
+=head1 INCORPORATING NMUS
+
+=over 4
+
+ % dgit pull
+
+=back
+
+If the NMUer added new commits modifying the upstream source, you will
+probably want to debrebase before your next upload to tidy those up.
+
+For example, the NMUer might have used git-revert(1) to unapply one of
+your patches. A debrebase will strip both the patch and the reversion
+from the patch series.
+
+=head1 SEE ALSO
+
+dgit(1), dgit(7)
+
+=head1 AUTHOR
+
+This tutorial was written and is maintained by Sean Whitton
+<spwhitton@spwhitton.name>. It contains contributions from other dgit
+contributors too - see the dgit copyright file.