X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?a=blobdiff_plain;f=tb-create.pl;h=68c571f369cd280c7eeb9c3abe9825af9a4edd93;hb=9a8795b9394e4064ebe309bedf0162c193922952;hp=79d42749015088e8e6c883348733bad87dcbc7af;hpb=40c98ff5ceb966b62b7bdb42c3ddbb48ddb61bf3;p=topbloke.git diff --git a/tb-create.pl b/tb-create.pl index 79d4274..68c571f 100755 --- a/tb-create.pl +++ b/tb-create.pl @@ -1,4 +1,5 @@ #!/usr/bin/perl +# usage: tb-create use warnings; use strict; @@ -6,18 +7,20 @@ use strict; use Getopt::Long; use Topbloke; +fixme needs update to new metadata; + Getopt::Long::Configure(qw(bundling)); die "bad usage\n" unless @ARGV==1; -our $spec = parse_branch_spec($ARGV[0]); -our $current = current_tb_branch(); +our $spec = parse_patch_spec($ARGV[0]); +our $current = current_branch(); -die "cannot make branch starting at base of another;". - " check out a real branch\n" if $current->{Kind} eq 'base'; +die "cannot make patch starting at base of another;". + " check out a real branch or patch\n" if $current->{Kind} eq 'base'; die "strange branch ref $current->{Kind} $current->{Ref},\n". - " making new branch with this as dep is unwise\n" + " making new patch with this as dep is unwise\n" unless ($current->{Kind} eq 'foreign' || $current->{Kind} eq 'tip'); @@ -39,16 +42,110 @@ if (!defined $spec->{Date}) { chomp $spec->{Date} or die $!; } +defined $spec->{Nick} or die "no patch nickname specified\n"; + length($spec->{Date})==18 or die "partial date specified, not supported\n"; +chdir_toplevel(); + check_no_unwanted_metadata('HEAD') if $current->{Kind} ne 'tip'; -my $newbranch = "$spec->{Email}\@$spec->{Domain}/$spec->{Date}/$spec->{Nick}"; +run_git_check_nooutput("cannot create new patch with staged file(s)", + qw(diff --cached --name-only HEAD --)); + +run_git_check_nooutput("cannot create new patch with". + " modified metadata file(s)", + qw(diff --name-only HEAD -- .topbloke)); + +# For the metadata files in .topbloke, we hope that the user +# doesn't modify them. If they do then they get to keep all the pieces. +# +# For .topbloke/msg, if it's modified by the user (ie, if working +# version differs from HEAD) we keep that and stage it. + +my $newpatch = "$spec->{Email}\@$spec->{Domain}/$spec->{Date}/$spec->{Nick}"; + +$newpatch = run_git_1line(qw(check-ref-format --print), $newpatch); + +my $author = run_git_1line(qw(var GIT_AUTHOR_IDENT)); +$author =~ s/ \d+ [-+]\d+$// or die $!; -$newbranch = run_git_1line(qw(check-ref-format --print), $newbranch); +my $subjprefix = git_config('topbloke.subjectprefix', ''); -printf "creating %s\n", $newbranch; +printf "creating %s\n", $newpatch; setup_config(); +#----- subroutines for setup + +sub create_and_switch ($$) { + my ($branchref, $what) = @_; + enable_reflog($branchref); + run_git(qw(update-ref -m), "tb-create $newpatch $what", $branchref, 'HEAD'); + run_git(qw(symbolic-ref HEAD), $branchref); +} + +sub stage_meta ($) { + my ($file) = @_; + run_git(qw(add), ".topbloke/$file"); +} + +sub meta_and_stage ($$) { + my ($file, $contents) = @_; + wf_contents(".topbloke/$file", $contents); + stage_meta($file); +} + +#----- create the base branch + +if (lstat '.topbloke') { + -d _ or die; +} else { + mkdir('.topbloke') or die "create .topbloke: $!\n"; +} + +my $baseref = "refs/topbloke-bases/$newpatch"; +create_and_switch($baseref, 'base'); + +meta_and_stage('msg', "# not applicable\n"); +meta_and_stage('deps', ""); +meta_and_stage('props', "patch $current->{Fullname}\n"); + +if ($current->{Kind} eq 'foreign') { + meta_and_stage('included', $current->{DepSpec}."\n"); + meta_and_stage('pprops', ''); +} + +run_git(qw(commit -q -m), "tb-create $newpatch base"); + +#----- create the tip branch + +my $tipref = "refs/topbloke-tips/$newpatch"; +create_and_switch($tipref, 'tip'); + +my $nm = wf_start('.topbloke/msg'); +wf($nm, "From: $author\n"); +foreach my $h (qw(To CC BCC)) { + my $estatus; + run_git(\$estatus, sub { wf($nm, "$h: $_") or die $!; }, + qw(config), "topbloke.".lc $h); + die "$h $estatus" unless $estatus==0 || $estatus==256; +} +wf($nm, <{Nick} + + + +Signed-off-by: $author +END +wf_done($nm); +stage_meta('msg'); + +meta_and_stage('deps', "$current->{DepSpec}\n"); +# we inherit correct props and pprops from the base branch + +depsfile_add_dep('included','tb',$newpatch); +stage_meta('included'); + +run_git(qw(commit -q -m), "tb-create $newpatch tip");