.SH SYNOPSIS
.B dgit
[\fIdgit\-opts\fP] \fBclone\fP [\fIdgit\-opts\fP]
-\fIpackage\fP [\fIsuite\fP] [\fB./\fP\fIdir|\fB/\fP\fIdir]
+\fIpackage\fP [\fIsuite\fP] [\fB./\fP\fIdir|\fB/\fP\fIdir\fR]
.br
.B dgit
[\fIdgit\-opts\fP] \fBfetch\fP|\fBpull\fP [\fIdgit\-opts\fP]
[\fIsuite\fP]
.br
.B dgit
-[\fIdgit\-opts\fP] \fBbuild\fP
-[\fIgit\-buildpackage\-opts\fP|\fIdpkg\-buildpackage\-opts\fp]
+[\fIdgit\-opts\fP] \fBbuild\fP|\fBsbuild\fP|\fBbuild-source\fP
+[\fIbuild\-opts\fp]
.br
.B dgit
[\fIdgit\-opts\fP] \fBpush\fP [\fIdgit\-opts\fP]
[\fIsuite\fP]
+.br
+.B dgit
+[\fIdgit\-opts\fP] \fIaction\fR ...
.SH DESCRIPTION
.B dgit
treats the Debian archive as a version control system, and
.B dgit-repos
which lives outside the Debian archive (currently, on Alioth).
-.B dgit clone
+The usual workflow is: 1. clone or fetch; 2. make and commit changes
+in git as desired; 3. run dgit build, dgit sbuild or dgit
+build-source, or generate the source and binary packages for upload
+some other way; 4. do pre-upload tests of the proposed upload; 5. run
+dgit push.
+.TP
+\fBdgit clone\fR \fIpackage\fP [\fIsuite\fP] [\fB./\fP\fIdir|\fB/\fP\fIdir\fR]
+Consults the archive and dgit-repos to construct the git view of
+history for
+.I package
+in
+.I suite
+.RB ( sid
+by default)
+in a new directory (named
+.BI ./ package
+by default);
+also, downloads any necessary orig tarballs.
+
+The suite's git tip is
+left on the local branch
+.BI dgit/ suite
+ready for work, and on the corresponding dgit remote tracking branch.
+Also, the
+.B origin
+remote will be set up to point to the package's dgit-repos tree
+for the distro to which
+.I suite
+belongs.
+.TP
+\fBdgit fetch\fR [\fIsuite\fP]
+Consults the archive and git-repos to update the git view of
+history for a specific suite (and downloads any necessary orig
+tarballs), and updates the remote tracking branch
+.BR remotes/dgit/dgit/ \fIsuite\fR.
+If the current branch is
+.BI dgit/ suite
+then dgit fetch defaults to
+.IR suite ;
+otherwise it parses debian/changelog and uses the suite specified
+there.
+.TP
+\fBdgit pull\fR [\fIsuite\fP]
+Does dgit fetch, and then merges the new head of the remote tracking
+branch
+.BI remotes/dgit/dgit/ suite
+into the current branch.
+.TP
+\fBdgit build\fR ...
+Runs
+.B dpkg-buildpackage
+with some suitable options. Options and argumments after build
+will be passed on to dpkg-buildpackage. It is not necessary to use
+dgit build when using dgit; it is OK to use any approach which ensures
+that the generated source package corresponds to the relevant git
+commit.
+
+Tagging, signing and actually uploading should be left to dgit push.
+.TP
+\fBdgit build-source\fR ...
+Builds the source package, and a changes file for a prospective
+source-only upload, using
+.BR dpkg-source .
+The output is left in
+.IR package \fB_\fR version \fB.dsc\fR
and
-.B dgit fetch
-consult the archive and dgit-repos and fetch and/or construct the
-git view of the history. With clone, the destination directory (by
-default, the package name in the current directory) will be created,
-and the new directory's `origin' remote will be set up to point to
-the package's dgit-repos tree.
-
-.B dgit build
-runs
+.IR package \fB_\fR version \fB_source.changes\fR.
+
+Tagging, signing and actually uploading should be left to dgit push.
+.TP
+\fBdgit sbuild\fR ...
+Constructs the source package, uses
+.B sbuild
+to do a binary build, and uses mergechanges to merge the source and
+binary changes files. Options and argumments after sbuild will be
+passed on to sbuild. Changes files matching
+.IB package _ version _*.changes
+in the parent directory will be removed; the output is left in
+.IR package \fB_\fR version \fB_multi.changes\fR.
+
+Tagging, signing and actually uploading should be left to dgit push.
+.TP
+\fBdgit git-build\fR ...
+Runs
.B git-buildpackage
-with some suitable options. Options after
-.B build
-will be passed on to git-buildpackage. It is not necessary to
-use dgit build; it is OK to use any approach which ensures that
-the generated source package corresponds to the relevant git commit.
-Tagging and signing should be left to dgit push.
+with some suitable options. Options and argumments after git-build
+will be passed on to git-buildpackage.
+Tagging, signing and actually uploading should be left to dgit push.
+.TP
.B dgit push
-does an `upload', pushing the current HEAD to the archive (as a source
-package) and to dgit-repos (as git commits). This also involves
-making a signed git tag, and signing the files to be uploaded to the
+Does an `upload', pushing the current HEAD to the archive (as a source
+package) and to dgit-repos (as git commits). The package must already
+have been built ready for upload, with the .dsc and .changes
+left in the parent directory.
+
+In more detail: dgit push checks that the current HEAD corresponds to
+the .dsc. It then pushes the HEAD to the suite's dgit-repos branch,
+makes a signed git tag, edits the .dsc to contain the dgit metadata
+field, runs debsign to sign the upload (.dsc and .changes), pushes the
+signed tag, and finally uses dput to upload the .changes to the
archive.
-.SH MODEL AND WORKFLOW
+
+dgit push always uses the package, suite and version specified in the
+debian/changelog and the .dsc, which must agree.
+
+If dgit push fails while uploading, it is fine to simply retry the
+dput on the .changes file at your leisure.
+.TP
+.B dgit quilt-fixup
+Looks to see if the tree is one which dpkg-source cannot properly
+represent. If it isn't, dgit will fix it up for you (in quilt terms,
+by making a new debian/ patch containing your unquilty changes) and
+make a commit of the changes it has made.
+
+This is normally done automatically by dgit build and dgit push.
+.SH WORKFLOW - SIMPLE
+It is always possible with dgit to clone or fetch a package, make
+changes in git (using git-commit) on the suite branch
+.RB ( "git checkout dgit/" \fIsuite\fR)
+and then dgit push. You can use whatever gitish techniques you like
+to construct the commit to push; the only requirement is that it is a
+descendant of the state of the archive, as provided by dgit in the
+remote tracking branch
+.BR remotes/dgit/dgit/ \fIsuite\fR.
+
+If you are lucky the other uploaders have also used dgit and
+integrated the other relevant git history; if not you can fetch it
+into your tree and cherry-pick etc. as you wish.
+.SH WORKFLOW - INTEGRATING BETWEEN DGIT AND OTHER GIT HISTORY
+If you are the maintainer of a package dealing with uploads made
+without dgit, you will probably want to merge the synthetic commits
+(made by dgit to represent the uploads) into your git history.
+Normally you can just merge the dgit branch into your own master, or
+indeed if you do your work on the dgit local suite branch
+.BI dgit/ suite
+you can just use dgit pull.
+
+However the first time dgit is used it will generate a new origin
+commit from the archive which won't be linked into the rest of your
+git history. You will need to merge this.
+
+If last upload was in fact made with git, you should usually proceed
+as follows: identify the commit which was actually used to build the
+package. (Hopefully you have a tag for this.) Check out the dgit
+branch
+.RB ( "git checkout dgit/" \fIsuite\fR)
+and merge that other commit
+.RB ( "git merge debian/" \fIversion\fR).
+Hopefully this merge will be trivial because the two trees should
+be the same. The resulting branch head can be merged into your
+working branches
+.RB ( "git checkout master && git merge dgit/" \fIsuite\fR).
+
+If last upload was not made with git, a different approach is required
+to start using dgit. First, do
+.B dgit fetch
+(or clone) to obtain a git history representation of what's in the
+archive and record it in the
+.BI remotes/dgit/dgit/ suite
+tracking branch. Then somehow, using your other git history
+plus appropriate diffs and cherry picks from the dgit remote tracking
+branch, construct a git commit whose tree corresponds to the tree to use for the
+next upload. If that commit-to-be-uploaded is not a descendant of the
+dig remote tracking branch, check it out and say
+.BR "git merge -s ours remotes/dgit/dgit/" \fIsuite\fR;
+that tells git that we are deliberately throwing away any differences
+between what's in the archive and what you intend to upload.
+Then run
+.BR "dgit push"
+to actually upload the result.
+.SH MODEL
You may use any suitable git workflow with dgit, provided you
satisfy dgit's requirements:
normally the dgit-repos repo for the package will be accessible via
the remote name `origin'.
+dgit push will also (by default) make signed tags called
+.BI debian/ version
+and push them to dgit-repos, but nothing depends on these tags
+existing.
+
dgit push can operate on any commit which is a descendant of the
current dgit/suite tip in dgit-repos.
Uploads not made by dgit are represented in git by commits which are
synthesised by dgit. The tree of each such commit corresponds to the
-unpacked source; the single parent is the last known upload - that is,
-the contents of the dgit/suite branch.
+unpacked source; there is an origin commit with the contents, and a
+psuedo-merge from last known upload - that is, from the contents of
+the dgit/suite branch.
dgit expects repos that it works with to have a
.B dgit
remote. This refers to the well-known dgit-repos location
(currently, the dgit-repos project on Alioth). dgit fetch updates
the remote tracking branch for dgit/suite.
+
+dgit does not (currently) represent the orig tarball(s) in git; nor
+does it represent the patch statck of a `3.0 (quilt)' package. The
+orig tarballs are downloaded and kept in the parent directory, as with
+a traditional (non-gitish) dpkg-source workflow.
+
+To a user looking at the archive, changes pushed using dgit look like
+changes made in an NMU: in a `3.0 (quilt)' package the delta from the
+previous upload is recorded in a new patch constructed by dpkg-source.
+.SH PACKAGE SOURCE FORMATS
+If you are not the maintainer, you do not need to worry about the
+source format of the package. You can just make changes as you like
+in git. If the package is a `3.0 (quilt)' package, the patch stack
+will usually not be represented in the git history.
+
+If you are the maintainer of a non-native package, you currently have
+two sensible options:
+
+Firstly, you can regard your git history as primary, and the archive
+as an export format. For example, you could maintain topic branches
+in git and a fast-forwarding release branch; or you could do your work
+directly in a merging way on the
+.BI dgit/ suite
+branches. If you do this you should probably use a `1.0' format
+source package if you can. In the archive, the delta between upstream
+will be represented in the single Debian patch.
+
+Secondly, you can use `3.0 (quilt)', and regard your quiltish patch
+stack in the archive as primary. You will have to use other tools
+besides dgit to import and export this patch stack. But see below:
+.SH FORMAT 3.0 (QUILT)
+For a format `3.0 (quilt)' source package, dgit may have to make a
+commit on your current branch to contain metadata used by quilt and
+dpkg-source.
+
+This is because (i) the `3.0 (quilt)' source format cannot represent
+certain trees, and (ii) packing up a tree in `3.0 (quilt)' and then
+unpacking it does not always yield the same tree. Instead,
+dpkg-source insists on the trees having extra quilty metadata and
+patch files in the debian/ and .pc/ directories, which dpkg-source
+sometimes modifies.
+
+dgit will automatically work around this braindamage for you when
+building and pushing. The only thing you need to know is that dgit
+build, sbuild, etc., may make a new commit on your HEAD. If you're
+not a quilt user this commit won't contain any changes to files you
+care about.
+
+You can explicitly request that dgit do just this fixup, by running
+dgit quilt-fixup.
+
+We recommend against the use of `3.0 (quilt)'.
.SH OPTIONS
.TP
.BR --dry-run | -n
rather than looking in debian/control or debian/changelog.
Valid with dgit fetch and dgit pull, only.
.TP
+.BR --clean=git | -wg
+The source tree should be cleaned, before building a source package
+with one of the build options, using
+.BR "git clean -xdf" .
+This will delete all files which are not tracked by git.
+.TP
+.BR --clean=none | -wn
+Do not clean the tree before building a source package. If there are
+files which are not in git, a subsequent dgit push will fail.
+.TP
+.BR --clean=dpkg-source | -wd
+Use dpkg-buildpackage to do the build, so that the source package
+is cleaned by dpkg-source running the package's clean target.
+This is the default. It requires the package's build dependencies.
+.TP
+.BR -N | --new
+The package may be new in this suite. Without this, dgit will
+refuse to push.
+.TP
+.BR --ignore-dirty
+Do not complain if the working tree does not match your git HEAD.
+This can be useful with build, if you plan to commit later. (dgit
+push will still ensure that the .dsc you upload and the git tree
+you push are identical, so this option won't make broken pushes.)
+
+This option may not work properly on `3.0 (quilt)' packages, as in
+that case dgit needs to use and perhaps commit parts of your working
+tree.
+.TP
+.BR --no-quilt-fixup
+Do not fix up source format `3.0 (quilt)' metadata. If you use this
+option and the package did in fact need fixing up, dgit push will
+fail.
+.TP
.BI -D
Prints debugging information to stderr. Repeating the option produces
more output (currently, up to -DD is meaningfully different).
Specifies a git configuration option. dgit itself is also controlled
by git configuration options.
.TP
-.RI \fB--dget=\fR program |\fB--dput=\fR program |\fB--debsign=\fR program
-Specifies alternative programs to use instead of dget, dput
-or debsign.
+.RI \fB-v\fR version |\fB-m\fR maintaineraddress
+Passed to dpkg-genchanges (eventually).
+.TP
+.RI \fB--ch:\fR option
+Specifies a single additional option to pass, eventually, to
+dpkg-genchanges.
+.TP
+.RI \fB--dget=\fR program |\fB--dput=\fR program |...
+Specifies alternative programs to use instead of
+.BR dget ,
+.BR dput ,
+.BR debsign ,
+.BR dpkg-source ,
+.BR dpkg-buildpackage ,
+.BR dpkg-genchanges ,
+.BR sbuild ,
+or
+.BR mergechanges .
+This applies only when the program is invoked directly by dgit.
.TP
-.RI \fB--dget:\fR option |\fB--dput:\fR option |\fB--debsign:\fR option
-Specifies a single additional option to pass to dget, dput or
-debsign. Use repeatedly if multiple additional options are required.
+.RI \fB--dget:\fR option |\fB--dput:\fR option |...
+Specifies a single additional option to pass to
+.BR dget ,
+.BR dput ,
+.BR debsign ,
+.BR dpkg-source ,
+.BR dpkg-buildpackage ,
+.BR dpkg-genchanges ,
+.BR sbuild ,
+or
+.BR mergechanges .
+Can be repeated as necessary.
+This applies only when the program is invoked directly by dgit.
+Usually, for passing options to dpkg-genchanges, use
+.BR --ch: \fIoption\fR.
+.TP
+.BR -d "\fIdistro\fR | " --distro= \fIdistro\fR
+Specifies that the suite to be operated on is part of distro
+.IR distro .
+This overrides the default value found from the git config option
+.BR dgit-suite. \fIsuite\fR .distro .
+The only effect is that other configuration variables (used
+for accessing the archive and dgit-repos) used are
+.BR dgit-distro. \fIdistro\fR .* .
+
+If your suite is part of a distro that dgit already knows about, you
+can use this option to make dgit work even if your dgit doesn't know
+about the suite. For example, specifying
+.B -ddebian
+will work when the suite is an unknown suite in the Debian archive.
+
+To define a new distro it is necessary to define methods and URLs
+for fetching (and, for dgit push, altering) a variety of information both
+in the archive and in dgit-repos. How to do this is not yet
+documented, and currently the arrangements are unpleasant. See
+BUGS.
.TP
.BI -C changesfile
Specifies the .changes file which is to be uploaded. By default
dgit push looks for single .changes file in the parent directory whose
-filename suggests it is for the right package and version.
+filename suggests it is for the right package and version - or,
+if there is a _multi.changes file, dgit uses that.
+.TP
+.BI --existing-package= package
+dgit push needs to canonicalise the suite name. But currently
+there is no way to ask the archive to do this without knowing the
+name of an existing package. Without --new we can just use the
+package we are trying to push. But with --new that will not work, so
+we guess
+.B dpkg
+or use the value of this option.
+.TP
+.BR -h | --help
+Print a usage summary.
+.SH SEE ALSO
+\fBdget\fP(1),
+\fBdput\fP(1),
+\fBdebsign\fP(1),
+\fBgit-config\fP(1),
+\fBgit-buildpackage\fP(1),
+\fBdpkg-buildpackage\fP(1),
+.br
+https://wiki.debian.org/Alioth
.SH CONFIGURATION
dgit looks at the following git config keys to control its behaviour.
You may set them with git-config (either in system-global or per-tree
.TP
.BI dgit.default.distro
.TP
-.BI dgit.default.username
+.BI dgit-distro. distro .username
.TP
.BI dgit-distro. distro .git-url
.TP
+.BI dgit-distro. distro .git-user
+.TP
.BI dgit-distro. distro .git-host
.TP
.BI dgit-distro. distro .git-proto
.TP
.BI dgit-distro. distro .archive-query-default-component
.TP
+.BI dgit-distro. distro .sshdakls-user
+.TP
+.BI dgit-distro. distro .sshdakls-host
+.TP
+.BI dgit-distro. distro .sshdakls-dir
+.TP
.BI dgit-distro. distro .ssh
.TP
+.BI dgit-distro. distro .keyid
+.TP
.BR dgit.default. *
for each
.BR dgit-distro. \fIdistro\fR . *
field (and to specify that it is an RC bug for that field to refer
to an unavailable commit).
-dgit cannot currently introduce a package into a suite.
+The method of canonicalising suite names is bizarre. See the
+.B --existing-package
+option for one of the implications.
dgit push should perhaps do `git push origin', or something similar,
by default.
+Debian does not have a working rmadison server, so to find out what
+version of a package is in the archive, or to canonicalise suite
+names, we ssh directly into the ftpmaster server.
+
The mechanism for checking for and creating per-package repos on
alioth is a hideous bodge. One consequence is that dgit currently
only works for people with push access.
push (perhaps enabled automatically by a note left by rebase-prep)
which will make the required pseudo-merge.
+If the dgit push fails halfway through, it should be restartable and
+idempotent. However this is not true for the git tag operation.
+Also, it would be good to check that the proposed signing key is
+available before starting work.
+
dgit's handling of .orig.tar.gz is not very sophisticated. Ideally
the .orig.tar.gz could be transported via the git repo as git tags.
Doing this is made more complicated by the possibility of a `3.0
(quilt)' package with multiple .orig tarballs.
-The error messages are often unhelpfully terse and tend to refer to
-line numbers in dgit.
+dgit's build functions, and dgit push, should not make any changes to
+your current HEAD. Sadly this is necessary for packages in the `3.0
+(quilt)' source format. This is ultimately due to design problems in
+quilt and dpkg-source.
+
+There should be an option which arranges for the `3.0 (quilt)'
+autocommit to not appear on your HEAD, but instead only in the
+remote tracking suite branch.
+
+There should at the very least be some advice in the manpage about how
+to use dgit when the signing key is not available on the same machine
+as the build host.
The option parser requires values to be cuddled to the option name.