9front - general discussion about 9front
 help / color / mirror / Atom feed
From: ori@eigenstate.org
To: 9front@9front.org
Subject: Re: [9front] git/merge: preserve exec bit correctly
Date: Sat, 16 Apr 2022 17:46:08 -0400	[thread overview]
Message-ID: <D0A8B3649947ABE952F062EE02500639@eigenstate.org> (raw)
In-Reply-To: <25433F41CD401BB8B6FA55036C80E4F1@eigenstate.org>

Quoth ori@eigenstate.org:
> 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,23 @@
 	' $*
 }
 
-fn present {
+fn mergep\x02erm {
 	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 {
+		mergedperms='-x'
+		if(test -x $2){
+			if(test -x $1 -a -x $3)
+				mergedperms='+x'
+		}
+		if not{
+			if(test -x $1 -o -x $3)
+				mergedperms='+x'
+		}
 		status=()
+	}
 }
 
 fn whoami{
@@ -76,9 +86,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,


  reply	other threads:[~2022-04-16 21:48 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-04-16 21:13 ori
2022-04-16 21:46 ` ori [this message]
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=D0A8B3649947ABE952F062EE02500639@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).