From: ori@eigenstate.org To: 9front@9front.org Subject: [9front] git/merge: preserve exec bit correctly Date: Sat, 16 Apr 2022 17:13:04 -0400 [thread overview] Message-ID: <25433F41CD401BB8B6FA55036C80E4F1@eigenstate.org> (raw) A while ago, qwx noticed that we clobbered the exec bit when merging files. This is not what we want, so we changed the operator precedence to avoid merging dirty files implicitly. But we do want to merge, because it's convenient for maintaining permissions. So, instead, we should do a 3 way merge of the exec bit. This patch does that, as well as reverting the rollback of that change. While we're here, we adjust the timestamps correctly in git/branch. This requires changes to git/fs, because without an open handler, lib9p allows opening any file with any mode, which confuses 'test -x'. diff 061ec57021a7c813844582f6f1973dafae6e668b uncommitted --- a//sys/lib/git/common.rc +++ b//sys/lib/git/common.rc @@ -29,13 +29,18 @@ ' $* } -fn present { +fn mergeperm { if(~ $1 /dev/null && cmp $2 $3>/dev/null) status=gone if not if (~ $3 /dev/null && cmp $1 $2>/dev/null) status=gone - if not + if not { + if(test -x $2 && {! test -x $1 || ! test -x $3}) + mergedperms='-x' + if not + mergedperms='+x' status=() + } } fn whoami{ @@ -76,9 +81,10 @@ if(! ape/diff3 -3 -m $ours $base $theirs > $tmp) echo merge needed: $out >[1=2] - if(present $ours $base $theirs){ + if(mergeperm $ours $base $theirs){ mv $tmp $out git/add $out + chmod $mergedperms $out } if not { rm -f $tmp $out --- a/sys/src/cmd/git/branch +++ b/sys/src/cmd/git/branch @@ -48,9 +48,12 @@ modified=`$nl{git/query -c HEAD $base | grep '^[^-]' | subst '^..'} deleted=`$nl{git/query -c HEAD $base | grep '^-' | subst '^..'} -if(! ~ $#modified 0 || {! ~ $#deleted 0 && ~ $#merge 0}){ - git/walk -fRMA $modified $deleted || - die 'uncommitted changes would be clobbered' +# if we're not merging, don't clobber existing changes. +if(~ $#merge 0){ + if(! ~ $#modified 0 || ! ~ $#deleted 0){ + git/walk -fRMA $modified $deleted || + die 'uncommitted changes would be clobbered' + } } if(~ $delete 1){ rm -f .git/$new @@ -97,10 +100,9 @@ rm -rf .git/index9/tracked/$m } if(~ $b file){ - if(cp -x -- $basedir/tree/$m $m) - walk -eq $m > .git/index9/tracked/$m - if not - echo -n > .git/index9/tracked/$m + cp -x -- $basedir/tree/$m $m) + walk -eq $m > .git/index9/tracked/$m + touch $m } } --- a/sys/src/cmd/git/fs.c +++ b/sys/src/cmd/git/fs.c @@ -70,13 +70,14 @@ "ctl", }; -#define Eperm "permission denied"; -#define Eexist "does not exist"; -#define E2long "path too long"; -#define Enodir "not a directory"; -#define Erepo "unable to read repo"; -#define Egreg "wat"; -#define Ebadobj "invalid object"; +#define Eperm "permission denied" +#define Eexist "does not exist" +#define E2long "path too long" +#define Enodir "not a directory" +#define Erepo "unable to read repo" +#define Eobject "invalid object" +#define Egreg "wat" +#define Ebadobj "invalid object" char gitdir[512]; char *username; @@ -624,9 +625,9 @@ e = objwalk1(q, o->obj, o, c, name, Qobject, aux); }else{ if(hparse(&h, name) == -1) - return "invalid object name"; + return Eobject; if((c->obj = readobject(h)) == nil) - return "could not read object"; + return Eobject; if(c->obj->type == GBlob || c->obj->type == GTag){ c->mode = 0644; q->type = 0; @@ -805,6 +806,34 @@ } static void +gitopen(Req *r) +{ + Gitaux *aux; + Crumb *c; + + aux = r->fid->aux; + c = crumb(aux, 0); + switch(r->ifcall.mode&3){ + default: + respond(r, "botched mode"); + break; + case OWRITE: + respond(r, Eperm); + break; + case OREAD: + case ORDWR: + respond(r, nil); + break; + case OEXEC: + if((c->mode & 0111) == 0) + respond(r, Eperm); + else + respond(r, nil); + break; + } +} + +static void gitstat(Req *r) { Gitaux *aux; @@ -830,6 +859,7 @@ .attach=gitattach, .walk1=gitwalk1, .clone=gitclone, + .open=gitopen, .read=gitread, .stat=gitstat, .destroyfid=gitdestroyfid,
next reply other threads:[~2022-04-16 21:14 UTC|newest] Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top 2022-04-16 21:13 ori [this message] 2022-04-16 21:46 ` ori 2022-04-19 8:46 ` igor 2022-04-19 14:18 ` ori 2022-04-26 6:10 ` igor
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=25433F41CD401BB8B6FA55036C80E4F1@eigenstate.org \ --to=ori@eigenstate.org \ --cc=9front@9front.org \ --subject='Re: [9front] git/merge: preserve exec bit correctly' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).