From: Ian Jackson Date: Fri, 16 Aug 2013 10:31:11 +0000 (+0100) Subject: wip doc X-Git-Tag: debian/0.2~38 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=dgit.git;a=commitdiff_plain;h=6a783c6b80a9cdd5d744e12637afcd5f10a987ba wip doc --- diff --git a/TODO b/TODO index 373e1183..5c9082a6 100644 --- a/TODO +++ b/TODO @@ -1,3 +1,5 @@ +clone support for output dir spec. + push should push to dgit remote (other branches) manpage should say not to push to suite branches newly cloned repos should have suite branches marked not to push diff --git a/dgit b/dgit index 2e40ad7e..edc3c227 100755 --- a/dgit +++ b/dgit @@ -26,8 +26,6 @@ use Dpkg::Control::Hash; use File::Path; use POSIX; -open DEBUG, ">&STDERR" or die $!; - our $mirror = 'http://mirror.relativity.greenend.org.uk/mirror/debian-ftp/'; our $suite = 'sid'; our $package; @@ -47,6 +45,8 @@ our (@dput) = qw(dput); our (@debsign) = qw(debsign); our $keyid; +open DEBUG, ">/dev/null" or die $!; + our %opts_opt_map = ('dget' => \@dget, 'dput' => \@dput, 'debsign' => \@debsign); @@ -67,7 +67,7 @@ sub url_get { $ua = LWP::UserAgent->new(); $ua->env_proxy; } - print DEBUG "fetching @_...\n"; + print "fetching @_...\n"; my $r = $ua->get(@_) or die $!; die "$_[0]: ".$r->status_line."; failed.\n" unless $r->is_success; return $r->decoded_content(); @@ -75,12 +75,30 @@ sub url_get { our ($dscdata,$dscurl,$dsc); +sub printcmd { + my $fh = shift @_; + my $intro = shift @_; + print $fh $intro or die $!; + local $_; + foreach my $a (@_) { + $_ = $a; + if (s{['\\]}{\\$&}g || m{\s} || m{[^-_./0-9a-z]}i) { + print $fh " '$_'" or die $!; + } else { + print $fh " $_" or die $!; + } + } + print $fh "\n" or die $!; +} + sub runcmd { + printcmd(\*DEBUG,"+",@_); $!=0; $?=0; die "@_ $! $?" if system @_; } sub cmdoutput_errok { + printcmd(\*DEBUG,"|",@_); open P, "-|", @_ or die $!; my $d; $!=0; $?=0; @@ -98,17 +116,7 @@ sub cmdoutput { } sub dryrun_report { - print "#" or die $!; - local $_; - foreach my $a (@_) { - $_ = $a; - if (s{['\\]}{\\$&}g || m{\s} || m{[^-_./0-9a-z]}i) { - print " '$_'" or die $!; - } else { - print " $_" or die $!; - } - } - print "\n" or die $!; + printcmd(\*STDOUT,"#",@_); } sub runcmd_ordryrun { @@ -162,13 +170,12 @@ sub get_archive_dsc () { # fixme madison does not show us the component my $prefix = substr($package, 0, $package =~ m/^l/ ? 4 : 1); $dscurl = "$mirror/pool/main/$prefix/$package/${package}_$vsn.dsc"; -#print DEBUG Dumper($pdodata, $&, $dscurl); $dscdata = url_get($dscurl); my $dscfh = new IO::File \$dscdata, '<' or die $!; -#print DEBUG Dumper($dscdata, $dscfh); + print DEBUG Dumper($dscdata); $dsc = Dpkg::Control::Hash->new(allow_pgp=>1); $dsc->parse($dscfh, 'dsc') or die "parsing of $dscurl failed\n"; -#print DEBUG Dumper($dsc); + print DEBUG Dumper($dsc); my $fmt = $dsc->{Format}; die "unsupported format $fmt, sorry\n" unless $fmt eq '1.0'; } @@ -180,11 +187,11 @@ sub check_for_git () { " set -e; cd $alioth_sshtestbodge->[1];". " if test -d $package.git; then echo 1; else echo 0; fi". "'"; - #print DEBUG "$cmd\n"; + print DEBUG "$cmd\n"; open P, "$cmd |" or die $!; $!=0; $?=0; my $r =

; close P; -#print STDERR ">$r<\n"; + print DEBUG ">$r<\n"; die "$r $! $?" unless $r =~ m/^[01]$/; return $r+0; } @@ -437,7 +444,11 @@ sub dopush () { # (uploadbranch()); $dsc->{$ourdscfield} = rev_parse('HEAD'); $dsc->save("../$dscfn.tmp") or die $!; - rename "../$dscfn.tmp","../$dscfn" or die "$dscfn $!"; + if (!$dryrun) { + rename "../$dscfn.tmp","../$dscfn" or die "$dscfn $!"; + } else { + print "[new .dsc left in $dscfn.tmp]\n"; + } if (!$changesfile) { my $pat = "../${package}_$clogp->{Version}_*.changes"; my @cs = glob $pat; @@ -560,6 +571,8 @@ sub parseopts () { while (m/^-./s) { if (s/^-n/-/) { $dryrun=1; + } elsif (s/^-D/-/) { + open DEBUG, ">&STDERR" or die $!; } elsif (s/^-c(.*=.*)//s) { push @git, $1; } elsif (s/^-C(.*)//s) { diff --git a/dgit.1 b/dgit.1 new file mode 100644 index 00000000..6394a16f --- /dev/null +++ b/dgit.1 @@ -0,0 +1,160 @@ +.TH dgit 1 "" "Debian Project" "dgit" +.SH NAME +dgit \- git integration with the Debian archive +. +.SH SYNOPSIS +.B dgit +[\fIdgit\-options\fP] \fBclone\fP [\fIdgit\-options\fP] +\fIpackage\fP [\fIsuite\fP] [\fB./\fP\fIdest-dir|\fB/\fP\fIdest-dir] +.br +.B dgit +[\fIdgit\-options\fP] \fBfetch\fP|\fBpull\fP [\fIdgit\-options\fP] +[\fIsuite\fP] +.br +.B dgit +[\fIdgit\-options\fP] \fBbuild\fP +[\fIgit\-buildpackage\-options\fP|\fIdpkg\-buildpackage\-options\fp] +.br +.B dgit +[\fIdgit\-options\fP] \fBpush\fP [\fIdgit\-options\fP] +[\fIsuite\fP] +.SH DESCRIPTION +.B dgit +treats the Debian archive as a version control system, and +bidirectionally gateways between the archive and git. The git view of +the package can contain the usual upstream git history, and will be +augmented by commits representing uploads done without using dgit. +This git history is stored in a canonical location +.B dgit-repos +which lives outside the Debian archive. + +.B dgit clone +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. + +.B dgit build +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. + +.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 +archive. +.SH MODEL AND WORKFLOW +You may use any suitable git workflow with dgit, provided you +satisfy dgit's requirements: + +The +.B dgit-repos +repository for each package contains one branch per suite named +\fBdgit/\fR\fIsuite\fR. These should be pushed to only by +dgit. They are fast forwarding. Each push on this branch +corresponds to an upload (or attempted upload). + +dgit push can operate on any commit which is a descendant of the +current dgit/suite tip in dgit-repos. + +Uploads made by dgit contain an additional field +.B Vcs-Git-Master +in the source package .dsc. (This is added by dgit push.) +This specifies a commit (an ancestor of the dgit/suite +branch) whose tree is identical to the unpacked source upload. + +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. + +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. +.SH OPTIONS +.TP +.BR --dry-run | -n +Go through the motions, fetching all information needed, but do not +actually update the output(s). For fetch and pull, dgit determines +which git commit corresponds to the archive but does not update +remotes/dgit/dgit/suite or do any merge. For push, dgit does +the required checks and leaves the new .dsc in a temporary file, +but does not sign, tag, push or upload. +.TP +.BI -k keyid +Use +.I keyid +for signing the tag and the upload. +.TP +.BR --no-sign +does not sign tags or uploads (meaningful only with push). +.TP +.BI -D +Spew debugging information to stderr. +.TP +.BI -c name = value +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. +.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. +.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 they it is for the right package and version. +.SH BUGS +dgit currently only works with Format 1.0 packages. + +dgit is not nearly configurable enough. The locations for dgit-repos +(on alioth) and for the Debian archive are currently hardcoded. +There is not yet any support for suites which are in different +distributions to Debian. + +dgit will only work with packages in main. The madison http query API +does not give the component. + +dgit assumes knowledge of the archive layout. There appears to be no +sane way to find the path in the archive pool of the .dsc for a +particular suite. + +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. + +Debian Maintainers are currently not able to push, as there is not +currently any mechanism for determining and honouring the archive's +ideas about access control. Currently only DDs can push. + +dgit's representation of Format 3.0 (quilt) source packages (even if +they were supported) would not represent the patch stack. Currently +the patch series representation cannot round trip through the archive. +Ideally dgit would represent a quilty package with an origin commit of +some kind followed by the patch stack as a series of commits followed +by a pseudo-merge (to make the branch fast-forwarding). This would +also mean a new "dgit rebase-prep" command or some such to turn such a +fast-forwarding branch back into a rebasing patch stack, and a "force" +option to dgit push (perhaps enabled automatically) which will make +the required pseudo-merge. + +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. + +The error messages are often unhelpfully terse and tend to refer to +line numbers in dgit. + +The option parser requires values to be cuddled to the option name.