9front - general discussion about 9front
 help / color / mirror / Atom feed
From: igor@9lab.org
To: 9front@9front.org
Cc: ori@eigenstate.org, igor@9lab.org
Subject: Re: [9front] git/merge: preserve exec bit correctly
Date: Tue, 19 Apr 2022 10:46:44 +0200	[thread overview]
Message-ID: <662EE35E4A9773AA51270EF917573B51@9lab.org> (raw)
In-Reply-To: <D0A8B3649947ABE952F062EE02500639@eigenstate.org>

Hi Ori,

I was testing the combination of two patches you sent via the list:

 * git/merge: preserve exec bit correctly
 * git/send: fill in 'theirs' object, even if we miss it 

To exercise the code I used a very large repo with many branches
cloned from an on-site GitLab instance.

When trying to switch between branches using git/branch things fall
over with the below error.

I have done no further debugging so far.  Hence, the issue could still
be between keyboard and chair.  More debug info to follow off list...

<snip>
  term% git/clone git+ssh://some-gitlab-repo.xyz/repo
  term% cd repo
  term% git/pull
  git-upload-pack: Command not found.
  up to date
  term% git/branch
  heads/develop
  term% git/branch xxx/yyyREDACTEDyyy
  git/query: resolve: invalid ref refs/heads/xxx/yyyREDACTEDyyy
  refs/heads/xxx/yyyREDACTEDyyy: 89d2917afd764b48d6fcf5a8b9c25e28da956eb2
  term% git/branch
  heads/xxx/yyyREDACTEDyyy
  term% git/branch develop
  assert failed: o->flag & Cloaded
  fs 2459926: suicide: sys: trap: fault read addr=0x0 pc=0x2125d9
  cp: can't stat /REDACTED/.git/fs/object/31423d28b3eb695f5cb9df954113bfef30f53fe9/tree/REDACTED-PATH/some.file: '/REDACTED/.git/fs/object' mount rpc error
<snap>

Here the stack trace:

<snip>
  acid: lstk()
  abort()+0x0 /sys/src/libc/9sys/abort.c:6
  _assert(s=0x4003a8)+0x42 /sys/src/libc/port/_assert.c:12
  clear(o=0x11626fd0)+0x108 /sys/src/cmd/git/pack.c:83
  unref()+0x1f /sys/src/cmd/git/pack.c:118
  gitdestroyfid()+0x53 /sys/src/cmd/git/fs.c:702
  	i=0x1162ea300000000c
  	aux=0x1162ea30
  closefid(f=0x11622710)+0x4f /sys/src/lib9p/fid.c:69
  closereq(r=0x11626c70)+0x84 /sys/src/lib9p/req.c:79
  	i=0x21994e00000000
  respond(error=0x0,r=0x11626c70)+0x31d /sys/src/lib9p/srv.c:924
  	srv=0x407b18
  	errbuf=0x21a36e00000000
  	n=0x11626c7000000007
  	i=0x218af200000000
  sclunk(r=0x11626c70)+0x56 /sys/src/lib9p/srv.c:590
  srvwork()+0x1d2 /sys/src/lib9p/srv.c:764
  	srv=0x407b18
  	r=0x11626c70
  srv(srv=0x407b18)+0x15b /sys/src/lib9p/srv.c:847
  postproc()+0x30 /sys/src/lib9p/post.c:12
  	s=0x407b18
  srvforker(fn=0x21713f,arg=0x407b18,flag=0x9)+0x30 /sys/src/lib9p/rfork.c:17
  postsrv(s=0x407b18,name=0x0)+0x112 /sys/src/lib9p/post.c:41
  	fd=0x400000003
  	buf=0x4003a800000000
  	cfd=0x3ffffffff
  postmountsrv(name=0x0,mtpt=0x407397,flag=0x4)+0x13 /sys/src/lib9p/mount.c:13
  	sfd=0x202a3600000000
  main(argc=0x0,argv=0x7fffffffefa0)+0xf1 /sys/src/cmd/git/fs.c:905
  	_argc=0x0
  	_args=0x0
  	d=0x40d9e8
  _main+0x40 /sys/src/libc/amd64/main9.s:15
  acid: 
<snap>

HTH

Cheers,
Igor


Quoth ori@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-19  8: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
2022-04-19  8:46   ` igor [this message]
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=662EE35E4A9773AA51270EF917573B51@9lab.org \
    --to=igor@9lab.org \
    --cc=9front@9front.org \
    --cc=ori@eigenstate.org \
    /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
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).