chiark / gitweb /
i18n: po4a: Add a symlink to po/README
[dgit.git] / dgit-user.7.pod
index 1b12573..5713064 100644 (file)
 =head1 NAME
 
-dgit - tutorial for users of Debian-derived distros supported by dgit
+dgit-user - making and sharing changes to Debian packages, with git
 
 =head1 INTRODUCTION
 
-dgit lets you get the source code to every package on your system as a
-git tree.
+dgit lets you fetch the source code to every package on your
+system
+as if your distro used git to maintain all of it.
 
-You can then edit it, build updated binary packages and install and
-run them.  You can also share your work with others.
+You can then edit it,
+build updated binary packages (.debs)
+and install and run them.
+You can also share your work with others.
 
-This tutorial assumes you have basic familiarity with git.  It does
-not assume any initial familiarity with Debian's packaging processes.
+This tutorial gives some recipes and hints for this.
+It assumes you have basic familiarity with git.
+It does not assume any initial familiarity with
+Debian's packaging processes.
 
-.head1 SUMMARY
+If you are a package maintainer within Debian; a DM or DD;
+and/or a sponsee:
+this tutorial is not for you.
+Try L<dgit-nmu-simple(7)>, L<dgit-maint-*(7)>,
+or L<dgit(1)> and L<dgit(7)>.
 
-=over 4
-
-% dgit clone glibc jessie
-% cd glibc
-% wget 'https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=28250;mbox=yes;msg=89' | patch -p1 -u 
-% 
-
-
-=item
-
-Maintaining convenient and powerful git workflows takes priority over
-the usefulness of the raw Debian source package.  The Debian archive
-is thought of as an output format.
-
-For example, we don't spend time curating a series of quilt patches.
-However, the information such a series would contain is readily
-available from B<dgit-repos>.
-
-=item
+=head1 SUMMARY
 
-It is more important to have the Debian package's git history be a
-descendent of upstream's git history than to use exactly the orig.tar
-that upstream makes available for download.
-
-=back
-
-=head1 GIT CONFIGURATION
-
-Add the following to your ~/.gitconfig to teach git-archive(1) how to
-compress orig tarballs:
+(These runes will be discussed later.)
 
 =over 4
 
-    [tar "tar.xz"]
-       command = xz -c
-    [tar "tar.gz"]
-       command = gzip -c
+    % dgit clone glibc jessie,-security
+    % cd glibc
+    % curl 'https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=28250;mbox=yes;msg=89' | patch -p1 -u
+    % git commit -a -m 'Fix libc lost output bug'
+    % gbp dch -S --since=dgit/dgit/sid --ignore-branch --commit
+    % mk-build-deps --root-cmd=sudo --install
+    % dpkg-buildpackage -uc -b
+    % sudo dpkg -i ../libc6_*.deb
 
 =back
 
-=head1 INITIAL DEBIANISATION
-
-=head2 When upstream tags releases in git
-
-Suppose that the latest stable upstream release is 1.2.2, and this has
-been tagged '1.2.2' by upstream.
+Occasionally:
 
 =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
+    % git clean -xdf
+    % git reset --hard
 
 =back
 
-The final command detachs your master branch from the upstream remote,
-so that git doesn't try to push anything there, or merge unreleased
-upstream commits.  If you want to maintain a copy of your packaging
-branch on B<alioth.debian.org> in addition to B<dgit-repos>, you can
-do something like this:
+Later:
 
 =over 4
 
-    % git remote add -f origin git.debian.org:/git/collab-maint/foo.git
-    % git push --follow-tags -u origin master
+    % cd glibc
+    % dgit pull jessie,-security
+    % gbp dch -S --since=dgit/dgit/sid --ignore-branch --commit
+    % dpkg-buildpackage -uc -b
+    % sudo dpkg -i ../libc6_*.deb
 
 =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, just make commits that change files
-outside of the I<debian/> directory.  It is best to separate commits
-that touch I<debian/> from commits that touch upstream source, so that
-the latter can be cherry-picked by upstream.
-
-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.  Generate one with git-archive(1):
+=head1 FINDING THE RIGHT SOURCE CODE - DGIT CLONE
 
 =over 4
 
-    % git archive -o ../foo_1.2.2.orig.tar.xz 1.2.2
+    % dgit clone glibc jessie,-security
+    % cd glibc
 
 =back
 
-If you are using the version 1.0 source package format, replace 'xz'
-with 'gz'.
+dgit clone needs to be told the source package name
+(which might be different to the binary package name,
+which was the name you passed to "apt-get install")
+and the codename or alias of the Debian release
+(this is called the "suite").
 
-This tarball is ephemeral and easily regenerated, so we don't commit
-it anywhere (e.g. with tools like pristine-tar(1)).
+=head2 Finding the source package name
 
-=head3 Verifying upstream's tarball releases
+For many packages, the source package name is obvious.
+Otherwise, if you know a file that's in the package,
+you can look it up with dpkg:
 
 =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-archive(1).
+    % dpkg -S /lib/i386-linux-gnu/libc.so.6 
+    libc6:i386: /lib/i386-linux-gnu/libc.so.6
+    % dpkg -s libc6:i386
+    Package: libc6
+    Status: install ok installed
+    ...
+    Source: glibc
 
 =back
 
-=head2 When upstream releases only tarballs
+(In this example,
+libc6 is a "multi-arch: allowed" package,
+ which means that it exists in several different builds
+ for different architectures.
+That's where C<:i386> comes from.)
 
-We need a virtual upstream branch with virtual release tags.
-gbp-import-orig(1) can manage this for us.  To begin
+=head2 Finding the Debian release (the "suite")
 
-=over 4
+Internally,
+Debian (and derived) distros normally refer to their releases by codenames.
+Debian also has aliases which refer to the current stable release etc.
+So for example, at the time of writing
+Debian C<jessie> (Debian 8) is Debian C<stable>; and
+the current version of Ubuntu is C<yakkety> (Yakkety Yak, 16.10).
+You can specify either
+the codename C<jessie> or the alias C<stable>.
+If you don't say, you get C<sid>,
+which is Debian C<unstable> - the main work-in progress branch.
 
-    % mkdir foo
-    % cd foo
-    % git init
-
-=back
-
-Now create I<debian/gbp.conf>:
+If you don't know what you're running, try this:
 
 =over 4
 
-    [DEFAULT]
-    upstream-branch = upstream
-    debian-branch = master
-    upstream-tag = %(version)s
-
-    sign-tags = True
-    pristine-tar = False
-    pristine-tar-commit = False
+    % grep '^deb' /etc/apt/sources.list
+    deb http://the.earth.li/debian/ jessie main non-free contrib
+    ...
+    %
 
 =back
 
-Then we can import the upstream version:
+For Debian, you should add C<,-security>
+to the end of the suite name,
+unless you're on unstable or testing.
+Hence, in our example
+C<jessie> becomes C<jessie,-security>.
+(Yes, with a comma.)
+
+=head1 WHAT DGIT CLONE PRODUCES
+
+=head2 What branches are there
+
+dgit clone will give you a new working tree,
+and arrange for you to be on a branch named like
+C<dgit/jessie,-security> (yes, with a comma in the branch name).
+
+For each release (like C<jessie>)
+there is a tracking branch for the contents of the archive, called
+C<remotes/dgit/dgit/jessie>
+(and similarly for other suites).  This can be updated with
+C<dgit fetch jessie>.
+This, the I<remote suite branch>,
+is synthesized by your local copy of dgit.
+It is fast forwarding.
+
+Debian separates out the security updates, into C<*-security>.
+Telling dgit C<jessie,-security> means that it should include 
+any updates available in C<jessie-security>.
+The comma notation is a request to dgit to track jessie,
+or jessie-security if there is an update for the package there.
+
+(You can also dgit fetch in a tree that wasn't made by dgit clone.
+If there's no C<debian/changelog>
+you'll have to supply a C<-p>I<package> option to dgit fetch.)
+
+=head2 What kind of source tree do you get
+
+If the Debian package is based on some upstream release,
+the code layout should be like the upstream version.
+You should find C<git grep> helpful to find where to edit.
+
+The package's Debian metadata and the scripts for building binary
+packages are under C<debian/>.
+C<debian/control>, C<debian/changelog> and C<debian/rules> are the
+starting points.
+The Debian Policy Manual has most of the in-depth
+technical details.
+
+For many Debian packages,
+there will also be some things in C<debian/patches/>.
+It is best to ignore these.
+Insofar as they are relevant
+the changes there will have been applied to the actual files,
+probably by means of actual comments in the git history.
+The contents of debian/patches are ignored
+when building binaries
+from dgitish git branches.
+
+(For Debian afficionados:
+the git trees that come out of dgit are
+"patches-applied packaging branches
+without a .pc directory".)
+
+=head2 What kind of history you get
+
+If you're lucky, the history will be a version of,
+or based on,
+the Debian maintainer's own git history,
+or upstream's git history.
+
+But for many packages the real git history
+does not exist,
+or has not been published in a dgitish form.
+So you may find that the history is a rather short
+history invented by dgit.
+
+dgit histories often contain automatically-generated commits,
+including commits which make no changes but just serve
+to make a rebasing branch fast-forward.
+This is particularly true of
+combining branches like
+C<jessie,-security>.
+
+If the package maintainer is using git then
+after dgit clone
+you may find that there is a useful C<vcs-git> remote
+referring to the Debian package maintainer's repository
+for the package.
+You can see what's there with C<git fetch vcs-git>.
+But use what you find there with care:
+Debian maintainers' git repositories often have
+contents which are very confusing and idiosyncratic.
+In particular, you may need to manually apply the patches
+that are in debian/patches before you do anything else!
+
+=head1 BUILDING
+
+=head2 Always commit before building
 
 =over 4
 
-    % git add debian/gbp.conf && git commit -m "create gbp.conf"
-    % gbp import-orig ../foo_1.2.2.orig.tar.xz
+    % wget 'https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=28250;mbox=yes;msg=89' | patch -p1 -u
+    % git commit -a -m 'Fix libc lost output bug'
 
 =back
 
-You are now ready to proceed as above, making commits to both the
-upstream source and the I<debian/> directory.
+Debian package builds are often quite messy:
+they may modify files which are also committed to git,
+or leave outputs and temporary files not covered by C<.gitignore>.
 
-If you want to maintain a copy of your repository on
-B<alioth.debian.org>, you should push both the origin and the upstream
-branches:
+If you always commit,
+you can use
 
 =over 4
 
-    % git remote add -f origin git.debian.org:/git/collab-maint/foo.git
-    % git push --follow-tags -u origin master upstream
+    % git clean -xdf
+    % git reset --hard
 
 =back
 
-=head1 SOURCE PACKAGE CONFIGURATION
+to tidy up after a build.
+(If you forgot to commit, don't use those commands;
+instead, you may find that you can use C<git add -p>
+to help commit what you actually wanted to keep.)
 
-=head2 debian/source/options
+These are destructive commands which delete all new files
+(so you B<must> remember to say C<git add>)
+and throw away edits to every file
+(so you B<must> remember to commit).
 
-We set some source package options such that dgit can transparently
-handle the "dropping" and "refreshing" of changes to the upstream
-source:
+=head2 Update the changelog (at least once) before building
 
 =over 4
 
-    single-debian-patch
-    auto-commit
+    % gbp dch -S --since=dgit/dgit/sid --ignore-branch --commit
 
 =back
 
-You don't need to create this file if you are using the version 1.0
-source package format.
+The binaries you build will have a version number which ultimately
+comes from the C<debian/changelog>.
+You want to be able to tell your
+binaries apart from your distro's.
 
-=head2 Sample text for README.source
+So you should update C<debian/changelog>
+to add a new stanza at the top,
+for your build.
 
-It is a good idea to explain how a user can obtain a break down of the
-changes to the upstream source:
+This rune provides an easy way to do this.
+It adds a new changelog
+entry with an uninformative message and a plausible version number
+(containing a bit of your git commit id).
 
-=over 4
+If you want to be more sophisticated,
+the package C<dpkg-dev-el> has a good Emacs mode
+for editing changelogs.
+Alternatively, you could edit the changelog with another text editor,
+or run C<dch> or C<gbp dch> with different options.
+Choosing a good version number is slightly tricky and
+a complete treatment is beyond the scope of this tutorial.
 
-The Debian packaging of foo is maintained using dgit.  For the sake of
-an efficient workflow, Debian modifications to the upstream source are
-squashed into a single diff, rather than a series of quilt patches.
-To obtain a patch queue for package version 1.2.3-1:
+=head2 Actually building
 
 =over 4
 
-    # apt-get install dgit
-    % dgit clone foo
-    % cd foo
-    % git log --oneline 1.2.3..debian/1.2.3-1 -- . ':!debian'
-
-=back
-
-See dgit(1), dgit(7) and dgit-maint-merge(7) for more information.
+    % mk-build-deps --root-cmd=sudo --install
+    % dpkg-buildpackage -uc -b
 
 =back
 
-=head1 BUILDING AND UPLOADING
-
-Use B<dgit build>, B<dgit sbuild>, B<dgit build-source>, and B<dgit
-push> 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.
-
-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.
+dpkg-buildpackage is the primary tool for building a Debian source
+package.
+C<-uc> means not to pgp-sign the results.
+C<-b> means build all binary packages,
+but not to build a source package.
 
-=head1 NEW UPSTREAM RELEASES
+=head2 Using sbuild
 
-=head2 When upstream tags releases in git
-
-It's a good idea to preview the merge of the new upstream release.
-First, just check for any new or deleted files that may need
-accounting for in your copyright file:
+You can build in an schroot chroot, with sbuild, instead of in your
+main environment.  (sbuild is used by the Debian build daemons.)
 
 =over 4
 
-    % git remote update
-    % git diff --stat master..1.2.3 -- . ':!debian'
+    % git clean -xdf
+    % sbuild -c jessie -A --no-clean-source \
+             --dpkg-source-opts='-Zgzip -z1 --format=1.0 -sn'
 
 =back
 
-You can then review the full merge diff:
-
-=over 4
+Note that this will seem to leave a "source package"
+(.dsc and .tar.gz)
+in the parent directory,
+but that source package should not be used.
+It is likely to be broken.
+For more information see Debian bug #868527.
 
-    % git merge-tree `git merge-base master 1.2.3` master 1.2.3 | $PAGER
+=head1 INSTALLING
 
-=back
-
-Once you're satisfied with what will be merged, update your package:
+=head2 Debian Jessie or older
 
 =over 4
 
-    % git archive ../foo_1.2.3.orig.tar.xz 1.2.3
-    % git merge 1.2.3
-    % dch -v1.2.3-1 New upstream release.
-    % git add debian/changelog && git commit -m changelog
+    % sudo dpkg -i ../libc6_*.deb
 
 =back
 
-and you are ready to try a build.
-
-Again, if you are using the version 1.0 source package format, replace
-'xz' with 'gz'.
-
-=head2 When upstream releases only tarballs
+You can use C<dpkg -i> to install the
+.debs that came out of your package.
 
-Either
+If the dependencies aren't installed,
+you will get an error, which can usually be fixed with
+C<apt-get -f install>.
 
-=over 4
-
-    % gbp import-orig ../foo_1.2.2.orig.tar.xz
-
-=back
-
-or if you have a working watch file
+=head2 Debian Stretch or newer
 
 =over 4
 
-    % gbp import-orig --uscan
+    % sudo apt install ../libc6_*.deb
 
 =back
 
-=head1 HANDLING DFSG-NON-FREE MATERIAL
-
-=head2 When upstream tags releases in git
+=head1 Multiarch
 
-We create a DFSG-clean tag to merge to master:
+If you're working on a library package and your system has multiple
+architectures enabled,
+you may see something like this:
 
 =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
+    dpkg: error processing package libpcre3-dev:amd64 (--configure):
+     package libpcre3-dev:amd64 2:8.39-3~3.gbp8f25f5 cannot be configured because libpcre3-dev:i386 is at a different version (2:8.39-2)
 
 =back
 
-Before merging the new 1.2.3+dfsg tag to master, 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:
+The multiarch system used by Debian requires each package which is
+present for multiple architectures to be exactly the same across
+all the architectures for which it is installed.
+
+The proper solution
+is to build the package for all the architectures you
+have enabled.
+You'll need a chroot for each of the secondary architectures.
+This is somewhat tiresome,
+even though Debian has excellent tools for managing chroots.
+C<sbuild-debian-developer-setup> from the package of the same name
+and C<sbuild-createchroot> from the C<sbuild> package are
+good starting points.
+
+Otherwise you could deinstall the packages of interest
+for those other architectures
+with something like C<dpkg --remove libpcre3:i386>.
+
+If neither of those are an option,
+your desperate last resort is to try
+using the same version number
+as the official package for your own package.
+(The version is controlled by C<debian/changelog> - see above).
+This is not ideal because it makes it hard to tell what is installed,
+and because it will mislead and confuse apt.
+
+With the "same number" approach you may still get errors like
 
 =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.
+trying to overwrite shared '/usr/include/pcreposix.h', which is different from other instances of package libpcre3-dev
 
-=item 3.
+=back
 
-Push the branch somewhere and ask upstream to merge it, or use
-git-format-patch(1) or git-request-pull(1).
+but passing C<--force-overwrite> to dpkg will help
+- assuming you know what you're doing.
 
-=back
+=head1 SHARING YOUR WORK
 
-For example (and it is only an example):
+The C<dgit/jessie,-security> branch (or whatever) is a normal git branch.
+You can use C<git push> to publish it on any suitable git server.
 
-=over 4
+Anyone who gets that git branch from you
+will be able to build binary packages (.deb)
+just as you did.
 
-    % # 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
+If you want to contribute your changes back to Debian,
+you should probably send them as attachments to 
+an email to the
+L<Debian Bug System|https://bugs.debian.org/>
+(either a followup to an existing bug, or a new bug).
+Patches in C<git-format-patch> format are usually very welcome.
 
-=back
+=head2 Source packages
 
-Note that when you merge an upstream release containing your forwarded
-patches, git and dgit will transparently handle "dropping" the patches
-that have been forwarded, "retaining" the ones that haven't.
+The
+git branch is not sufficient to build a source package
+the way Debian does.
+Source packages are somewhat awkward to work with.
+Indeed many plausible git histories or git trees
+cannot be converted into a suitable source package.
+So I recommend you share your git branch instead.
 
-=head1 INCORPORATING NMUS
+If a git branch is not enough, and
+you need to provide a source package
+but don't care about its format/layout
+(for example because some software you have consumes source packages,
+not git histories)
+you can use this recipe to generate a C<3.0 (native)>
+source package, which is just a tarball
+with accompanying .dsc metadata file:
 
 =over 4
 
-    % dgit pull
+    % echo '3.0 (native)' >debian/source/format
+    % git commit -m 'switch to native source format' debian/source/format
+    % dgit -wgf build-source
 
 =back
 
-Alternatively, you can apply the NMU diff to your repository.  The
-next push will then require I<--overwrite>.
+If you need to provide a good-looking source package,
+be prepared for a lot more work.
+You will need to read much more, perhaps starting with
+L<dgit-nmu-simple(7)>,
+L<dgit-sponsorship(7)> or
+L<dgit-maint-*(7)>
 
 =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.