From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham autolearn_force=no version=3.4.4 Received: (qmail 22067 invoked from network); 3 Aug 2021 21:34:14 -0000 Received: from 1ess.inri.net (216.126.196.35) by inbox.vuxu.org with ESMTPUTF8; 3 Aug 2021 21:34:14 -0000 Received: from mimir.eigenstate.org ([206.124.132.107]) by 1ess; Tue Aug 3 15:43:27 -0400 2021 Received: from abbatoir.myfiosgateway.com (pool-74-108-56-225.nycmny.fios.verizon.net [74.108.56.225]) by mimir.eigenstate.org (OpenSMTPD) with ESMTPSA id 5c2d6c8f (TLSv1.2:ECDHE-RSA-AES256-SHA:256:NO) for <9front@9front.org>; Tue, 3 Aug 2021 12:43:11 -0700 (PDT) Message-ID: <24F7706D609399B43057E1268EEBB3B8@eigenstate.org> To: 9front@9front.org Date: Tue, 03 Aug 2021 15:43:10 -0400 From: ori@eigenstate.org MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit List-ID: <9front.9front.org> List-Help: X-Glyph: ➈ X-Bullshit: encrypted webscale interface-aware out-scaling database Subject: [9front] git: better handling of absolute paths, regex metachars Reply-To: 9front@9front.org Precedence: bulk Git currently gets a bit confused if you try to manipulate files by absolute path. There were also a number of places where user-controlled file paths ended up getting passed to regex interpretation, which could confuse things. This change mainly does 2 things: - Adds a 'drop' function which drops a non-regex prefix from a string, and uses that to manipulate paths, simplifies 'subst', and removes 'subst -g', which was only used with fixed regexes; sed does this job fine. - When getting a path from a user, we make it absolute and then strip out the head Along the way it cleans up a couple of stupids: - 'for(f in $list) if(! ~ $#f 0) use $f: $f can't be a nil list because of list flattening. - removes a useless substitution here: all=`$nl{{git/query -c $1 $2; git/query -c $2 $3} | sed 's/^..//' | \ gsubst '^('$ourbr'|'$basebr'|'$theirbr')/*' | sort | uniq} where git/query -c doesn't produce paths prefixed with the query. Testing and review requested. --- //.git/fs/object/7f832df53d2a1d45fb7c7b2129e56b6b9e855682/tree//sys/lib/git/common.rc +++ /sys/lib/git/common.rc @@ -11,23 +11,22 @@ exit 'usage' } -# subst [-g] this [that] -fn subst{ - awk 'BEGIN{ - global = 0 - for(i = 1; ARGV[i] ~ /^-/; i++){ - if(ARGV[i] == "-g") - global = 1 - ARGC-- - } - this = ARGV[i++]; ARGC-- - that = ARGV[i++]; ARGC-- - } +fn subst { + awk ' + BEGIN{ARGC=0} + {sub(ARGV[1], ARGV[2]); print} + ' $* +} + +fn drop { + awk ' + BEGIN{ARGC=0} { - if(global) gsub(this, that) - else sub(this, that) + if(index($0, ARGV[1]) == 1) + $0=substr($0, length(ARGV[1])+1) print - }' $* + } + ' $* } fn present { @@ -77,7 +76,7 @@ if(~ $#gitroot 0) die 'not a git repository' gitfs=$gitroot/.git/fs - gitrel=`{pwd | subst '^'$"gitroot'/?'} + gitrel=`{pwd | drop $gitroot} if(~ $#gitrel 0) gitrel='.' cd $gitroot --- //.git/fs/object/7f832df53d2a1d45fb7c7b2129e56b6b9e855682/tree//sys/src/cmd/git/add +++ /sys/src/cmd/git/add @@ -16,11 +16,11 @@ if(~ $#* 0) exec aux/usage -paths=`$nl{cleanname -d $gitrel $*} +paths=`$nl{cleanname -d $gitrel $* | drop $gitroot} if(~ $add tracked) - files=`$nl{walk -f $paths} + files=`$nl{walk -f ./$paths} if not - files=`$nl{cd .git/index9/tracked/ && walk -f $paths} + files=`$nl{cd .git/index9/tracked/ && walk -f ./$paths} for(f in $files){ if(! ~ `$nl{cleanname $f} .git/*){ --- //.git/fs/object/7f832df53d2a1d45fb7c7b2129e56b6b9e855682/tree//sys/src/cmd/git/clone +++ /sys/src/cmd/git/clone @@ -7,7 +7,7 @@ if(~ $debug 1) debug=(-d) -remote=`{echo $1 | subst -g '/*$'} +remote=`{echo $1 | sed 's@/*$@@'} local=$2 if(~ $#remote 0) @@ -79,7 +79,7 @@ tree=.git/fs/HEAD/tree lbranch=`{git/branch} - rbranch=`{echo $lbranch | subst '^heads' 'remotes/origin'} + rbranch=`{echo $lbranch | subst 'heads' 'remotes/origin'} echo checking out repository... if(test -f .git/refs/$rbranch){ cp .git/refs/$rbranch .git/refs/$lbranch @@ -86,12 +86,10 @@ git/fs @ {builtin cd $tree && tar cif /fd/1 .} | @ {tar xf /fd/0} \ || die 'checkout failed:' $status - for(f in `$nl{walk -f $tree | subst '^'$tree'/*'}){ - if(! ~ $#f 0){ - idx=.git/index9/tracked/$f - mkdir -p `$nl{basename -d $idx} - walk -eq $f > $idx - } + for(f in `$nl{walk -f $tree | drop $tree}){ + idx=.git/index9/tracked/$f + mkdir -p `$nl{basename -d $idx} + walk -eq ./$f > $idx } } if not{ --- //.git/fs/object/7f832df53d2a1d45fb7c7b2129e56b6b9e855682/tree//sys/src/cmd/git/commit +++ /sys/src/cmd/git/commit @@ -58,7 +58,7 @@ echo '#' for(p in $parents) echo '# parent:' $p - git/walk -fAMR $files | subst -g '^' '# ' + git/walk -fAMR $files | sed 's/^/# /g' echo '#' echo '# Commit message:' } --- //.git/fs/object/7f832df53d2a1d45fb7c7b2129e56b6b9e855682/tree//sys/src/cmd/git/merge +++ /sys/src/cmd/git/merge @@ -8,7 +8,7 @@ theirbr=$gitfs/object/$3/tree all=`$nl{{git/query -c $1 $2; git/query -c $2 $3} | sed 's/^..//' | \ - subst -g '^('$ourbr'|'$basebr'|'$theirbr')/*' | sort | uniq} + gsubst '^('$ourbr'|'$basebr'|'$theirbr')/*' | sort | uniq} for(f in $all){ ours=$ourbr/$f base=$basebr/$f --- //.git/fs/object/7f832df53d2a1d45fb7c7b2129e56b6b9e855682/tree//sys/src/cmd/git/push +++ /sys/src/cmd/git/push @@ -34,7 +34,7 @@ updates=`$nl{git/send $debug $force $branch $remove $remote} || die $status for(ln in $updates){ u=`{echo $ln} - refpath=`{echo $u(2) | subst '^refs/heads/' '.git/refs/remotes/'$upstream'/'} + refpath=`{echo $u(2) | sub '^refs/heads/' '.git/refs/remotes/'$upstream'/'} switch($u(1)){ case update; mkdir -p `{basename -d $refpath} --- //.git/fs/object/7f832df53d2a1d45fb7c7b2129e56b6b9e855682/tree//sys/src/cmd/git/revert +++ /sys/src/cmd/git/revert @@ -11,8 +11,8 @@ if(~ $#query 1) commit=`{git/query -p $query} -files=`$nl{cleanname -d $gitrel $*} -for(f in `$nl{cd $commit/tree/ && walk -f $files}){ +files=`$nl{cleanname -d $gitrel $* | drop $gitroot} +for(f in `$nl{cd $commit/tree/ && walk -f ./$files}){ mkdir -p `{basename -d $f} cp -x -- $commit/tree/$f $f git/add $f