X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=dgit.git;a=blobdiff_plain;f=dgit;h=4f85e5c1d9aed3d4c4c0a3d531d44a56cd644e6a;hp=5ca4a817aa1ddf47c52ace3f2e36f12ae5b53391;hb=76e5c4414c5d0ecd5efdd55c6e93290763873eff;hpb=87e828d271c0f37bb33ca723fa991d6afc3ec76f diff --git a/dgit b/dgit index 5ca4a817..4f85e5c1 100755 --- a/dgit +++ b/dgit @@ -34,7 +34,6 @@ use POSIX; use IPC::Open2; use Digest::SHA; use Digest::MD5; -use List::Util qw(any); use List::MoreUtils qw(pairwise); use Text::Glob qw(match_glob); use Fcntl qw(:DEFAULT :flock); @@ -144,6 +143,8 @@ our %opts_cfg_insertpos = map { } keys %opts_opt_map; sub parseopts_late_defaults(); +sub setup_gitattrs(;$); +sub check_gitattrs($$); our $keyid; @@ -668,7 +669,7 @@ sub git_get_config ($) { my ($c) = @_; foreach my $src (@gitcfgsources) { my $l = $gitcfgs{$src}{$c}; - croak "$l $c" if $l && !ref $l; + confess "internal error ($l $c)" if $l && !ref $l; printdebug"C $c ".(defined $l ? join " ", map { messagequote "'$_'" } @$l : "undef")."\n" @@ -1698,6 +1699,7 @@ sub mktree_in_ud_here () { runcmd qw(git config gc.auto 0); rmtree('.git/objects'); symlink '../../../../objects','.git/objects' or die $!; + setup_gitattrs(1); } sub git_write_tree () { @@ -2799,6 +2801,11 @@ sub fetch_from_archive_record_2 ($) { } } +sub parse_dsc_field_def_dsc_distro () { + $dsc_distro //= cfg qw(dgit.default.old-dsc-distro + dgit.default.distro); +} + sub parse_dsc_field ($$) { my ($dsc, $what) = @_; my $f; @@ -2807,20 +2814,16 @@ sub parse_dsc_field ($$) { last if defined $f; } - my $def_dsc_distro = sub { - $dsc_distro //= cfg qw(dgit.default.old-dsc-distro - dgit.default.distro); - }; - if (!defined $f) { progress "$what: NO git hash"; + parse_dsc_field_def_dsc_distro(); } elsif (($dsc_hash, $dsc_distro, $dsc_hint_tag, $dsc_hint_url) = $f =~ m/^(\w+)\s+($distro_re)\s+($versiontag_re)\s+(\S+)(?:\s|$)/) { progress "$what: specified git info ($dsc_distro)"; $dsc_hint_tag = [ $dsc_hint_tag ]; } elsif ($f =~ m/^\w+\s*$/) { $dsc_hash = $&; - $def_dsc_distro->(); + parse_dsc_field_def_dsc_distro(); $dsc_hint_tag = [ debiantags +(getfield $dsc, 'Version'), $dsc_distro ]; progress "$what: specified git hash"; @@ -3254,6 +3257,8 @@ END lrfetchref_used lrfetchref(); + check_gitattrs($hash, "fetched source tree"); + unshift @end, $del_lrfetchrefs; return $hash; } @@ -3315,11 +3320,88 @@ sub ensure_setup_existing_tree () { set_local_git_config $k, 'true'; } +sub open_gitattrs () { + my $gai = new IO::File ".git/info/attributes" + or $!==ENOENT + or die "open .git/info/attributes: $!"; + return $gai; +} + +sub is_gitattrs_setup () { + my $gai = open_gitattrs(); + return 0 unless $gai; + while (<$gai>) { + return 1 if m{^\[attr\]dgit-defuse-attrs\s}; + } + $gai->error and die $!; + return 0; +} + +sub setup_gitattrs (;$) { + my ($always) = @_; + return unless $always || access_cfg_bool(1, 'setup-gitattributes'); + + if (is_gitattrs_setup()) { + progress < $af.new" or die $!; + print GAO <) { + chomp; + print GAO $_, "\n" or die $!; + } + $gai->error and die $!; + } + close GAO or die $!; + rename "$af.new", "$af" or die "install $af: $!"; +} + sub setup_new_tree () { setup_mergechangelogs(); setup_useremail(); + setup_gitattrs(); } +sub check_gitattrs ($$) { + my ($treeish, $what) = @_; + + return if is_gitattrs_setup; + + local $/="\0"; + my @cmd = (@git, qw(ls-tree -lrz --), "${treeish}:"); + debugcmd "|",@cmd; + my $gafl = new IO::File; + open $gafl, "-|", @cmd or die $!; + while (<$gafl>) { + chomp or die; + s/^\d+\s+\w+\s+\w+\s+(\d+)\t// or die; + next if $1 == 0; + next unless m{(?:^|/)\.gitattributes$}; + + # oh dear, found one + print STDERR <(), and returns undef @@ -3519,6 +3601,7 @@ sub clone ($) { mkdir $dstdir or fail "create \`$dstdir': $!"; changedir $dstdir; runcmd @git, qw(init -q); + setup_new_tree(); clone_set_head(); my $giturl = access_giturl(1); if (defined $giturl) { @@ -3537,7 +3620,6 @@ sub clone ($) { $vcsgiturl =~ s/\s+-b\s+\S+//g; runcmd @git, qw(remote add vcs-git), $vcsgiturl; } - setup_new_tree(); clone_finish($dstdir); } @@ -6049,6 +6131,15 @@ sub cmd_quilt_fixup { build_maybe_quilt_fixup(); } +sub import_dsc_result { + my ($dstref, $newhash, $what_log, $what_msg) = @_; + my @cmd = (@git, qw(update-ref -m), $what_log, $dstref, $newhash); + runcmd @cmd; + check_gitattrs($newhash, "source tree"); + + progress "dgit: import-dsc: $what_msg"; +} + sub cmd_import_dsc { my $needsig = 0; @@ -6116,6 +6207,12 @@ sub cmd_import_dsc { parse_dsc_field($dsc, "Dgit metadata in .dsc") unless forceing [qw(import-dsc-with-dgit-field)]; + parse_dsc_field_def_dsc_distro(); + + $isuite = 'DGIT-IMPORT-DSC'; + $idistro //= $dsc_distro; + + notpushing(); if (defined $dsc_hash) { progress "dgit: import-dsc of .dsc with Dgit field, using git hash"; @@ -6139,10 +6236,9 @@ END fail "Not fast forward to $dsc_hash"; } } - @cmd = (@git, qw(update-ref -m), "dgit import-dsc (Dgit): $info", - $dstbranch, $dsc_hash); - runcmd @cmd; - progress "dgit: import-dsc updated git ref $dstbranch"; + import_dsc_result $dstbranch, $dsc_hash, + "dgit import-dsc (Dgit): $info", + "updated git ref $dstbranch"; return 0; } @@ -6153,8 +6249,6 @@ Specify +$specbranch to overwrite, discarding existing history END if $oldhash && !$force; - notpushing(); - my @dfi = dsc_files_info(); foreach my $fi (@dfi) { my $f = $fi->{Filename}; @@ -6204,10 +6298,9 @@ END } } - my @cmd = (@git, qw(update-ref -m), "dgit import-dsc: $info", - $dstbranch, $newhash); - runcmd @cmd; - progress "dgit: import-dsc results are in in git ref $dstbranch"; + import_dsc_result $dstbranch, $newhash, + "dgit import-dsc: $info", + "results are in in git ref $dstbranch"; } sub cmd_archive_api_query { @@ -6248,6 +6341,11 @@ sub cmd_setup_useremail { setup_useremail(1); } +sub cmd_setup_gitattributes { + badusage "no arguments allowed to dgit setup-useremail" if @ARGV; + setup_gitattrs(1); +} + sub cmd_setup_new_tree { badusage "no arguments allowed to dgit setup-tree" if @ARGV; setup_new_tree();