"GOT", but the "O" is a cute, smiling pufferfish. Index | Thread | Search

From:
Tracey Emery <tracey@traceyemery.net>
Subject:
Re: branches in got.conf
To:
Stefan Sperling <stsp@stsp.name>
Cc:
gameoftrees@openbsd.org
Date:
Fri, 25 Sep 2020 14:54:20 -0600

Download raw body.

Thread
On Fri, Sep 25, 2020 at 12:35:39AM +0200, Stefan Sperling wrote:
> This allows branches in got.conf, as an equivalent to the -b option of
> got fetch. Branches specified in the configuration file are overridden
> by any -b options given to got fetch on the command line.
> 
> I am pondering whether an equivalent to got fetch -R (arbitary references)
> should be added to got.conf as well. Does anyone have a use case for that?
> 

Now with 100% more comments down there ...

> diff e03cc83491255ff69034ff6c824f9ba6062fcddd /home/stsp/src/got
> blob - fd46852d20b5897c487045e6e0c4d99e0bda0508
> file + got/got.c
> --- got/got.c
> +++ got/got.c
> @@ -2096,6 +2096,14 @@ cmd_fetch(int argc, char *argv[])
>  		goto done;
>  	}
>  
> +	if (TAILQ_EMPTY(&wanted_branches) && remote->nbranches > 0) {
> +		for (i = 0; i < remote->nbranches; i++) {
> +			got_pathlist_append(&wanted_branches,
> +			    remote->branches[i], NULL);
> +		}
> +		

tabs

> +	}
> +
>  	error = got_fetch_parse_uri(&proto, &host, &port, &server_path,
>  	    &repo_name, remote->url);
>  	if (error)
> blob - f1c3eb07dd31dd3a4620452bfdfab1b4119d3c66
> file + got/got.conf.5
> --- got/got.conf.5
> +++ got/got.conf.5
> @@ -105,6 +105,15 @@ for details.
>  If not specified, the default port of the specified
>  .Cm protocol
>  will be used.
> +.It Ic branch Brq Ar branch ...
> +Specify one or more branches which
> +.Cm got fetch
> +should fetch from the remote repository by default.
> +The list of branches specified here can be overridden at the
> +.Cm got fetch
> +command line with the
> +.Fl b
> +option.
>  .It Ic mirror-references Ar yes | no
>  This option controls the behaviour of
>  .Cm got fetch
> @@ -138,6 +147,7 @@ remote "origin" {
>  	server git.gameoftrees.org
>  	protocol git
>  	repository got
> +	branch { "main" }
>  }
>  .Ed
>  .Pp
> blob - 2b104798d08e7adbf100ae6c9d7a0877630dacdd
> file + include/got_repository.h
> --- include/got_repository.h
> +++ include/got_repository.h
> @@ -57,7 +57,17 @@ struct got_remote_repo {
>  	 * If not set, references are mapped into "refs/remotes/$name/".
>  	 */
>  	int mirror_references;
> +
> +	/* Branches to fetch by default. */
> +	int nbranches;
> +	char **branches;
>  };
> +
> +/*
> + * Free data allocated for the specified remote repository.
> + * Do not free the remote_repo pointer itself.
> + */
> +void got_repo_free_remote_repo_data(struct got_remote_repo *);
>  
>  /* Obtain the list of remote repositories parsed from gitconfig. */ 

trailing space
also in struct got_remote_repo there is an extra tab, just as a note

>  void got_repo_get_gitconfig_remotes(int *, const struct got_remote_repo **,
> blob - 51acfb2fde45abd2e9073411ad36ae9a24fed30e
> file + lib/got_lib_privsep.h
> --- lib/got_lib_privsep.h
> +++ lib/got_lib_privsep.h
> @@ -377,8 +377,10 @@ struct got_imsg_remote {
>  	size_t name_len;
>  	size_t url_len;
>  	int mirror_references;
> +	int nbranches;
>  
>  	/* Followed by name_len + url_len data bytes. */
> +	/* Followed by nbranches GOT_IMSG_GITCONFIG_STR_VAL messages. */
>  } __attribute__((__packed__));
>  
>  /*
> blob - d3c83b325581b556b7bca0faa5d7f3fbc611c63b
> file + lib/gotconfig.c
> --- lib/gotconfig.c
> +++ lib/gotconfig.c
> @@ -138,10 +138,8 @@ got_gotconfig_free(struct got_gotconfig *conf)
>  
>  	free(conf->author);
>  
> -	for (i = 0; i < conf->nremotes; i++) {
> -		free(conf->remotes[i].name);
> -		free(conf->remotes[i].url);
> -	}
> +	for (i = 0; i < conf->nremotes; i++)
> +		got_repo_free_remote_repo_data(&conf->remotes[i]);
>  	free(conf->remotes);
>  	free(conf);
>  }
> blob - 77debd84e15bb4334632363ebe637cfbe88f4202
> file + lib/privsep.c
> --- lib/privsep.c
> +++ lib/privsep.c
> @@ -1785,6 +1785,18 @@ got_privsep_recv_gitconfig_int(int *val, struct imsgbu
>  	return err;
>  }
>  
> +static void
> +free_remote_data(struct got_remote_repo *remote)
> +{
> +	int i;
> +
> +	free(remote->name);
> +	free(remote->url);
> +	for (i = 0; i < remote->nbranches; i++)
> +		free(remote->branches[i]);
> +	free(remote->branches);
> +}
> +
>  const struct got_error *
>  got_privsep_recv_gitconfig_remotes(struct got_remote_repo **remotes,
>      int *nremotes, struct imsgbuf *ibuf)
> @@ -1838,6 +1850,7 @@ got_privsep_recv_gitconfig_remotes(struct got_remote_r
>  		switch (imsg.hdr.type) {
>  		case GOT_IMSG_GITCONFIG_REMOTE:
>  			remote = &(*remotes)[*nremotes];
> +			memset(remote, 0, sizeof(*remote));
>  			if (datalen < sizeof(iremote)) {
>  				err = got_error(GOT_ERR_PRIVSEP_LEN);
>  				break;
> @@ -1859,10 +1872,12 @@ got_privsep_recv_gitconfig_remotes(struct got_remote_r
>  			    iremote.name_len, iremote.url_len);
>  			if (remote->url == NULL) {
>  				err = got_error_from_errno("strndup");
> -				free(remote->name);
> +				free_remote_data(remote);
>  				break;
>  			}
>  			remote->mirror_references = iremote.mirror_references;
> +			remote->nbranches = 0;
> +			remote->branches = NULL;
>  			(*nremotes)++;
>  			break;
>  		default:
> @@ -1877,10 +1892,8 @@ got_privsep_recv_gitconfig_remotes(struct got_remote_r
>  
>  	if (err) {
>  		int i;
> -		for (i = 0; i < *nremotes; i++) {
> -			free((*remotes)[i].name);
> -			free((*remotes)[i].url);
> -		}
> +		for (i = 0; i < *nremotes; i++)
> +			free_remote_data(&(*remotes)[i]);
>  		free(*remotes);
>  		*remotes = NULL;
>  		*nremotes = 0;
> @@ -1970,6 +1983,7 @@ got_privsep_recv_gotconfig_str(char **str, struct imsg
>  	return err;
>  }
>  
> +
>  const struct got_error *
>  got_privsep_recv_gotconfig_remotes(struct got_remote_repo **remotes,
>      int *nremotes, struct imsgbuf *ibuf)
> @@ -2025,6 +2039,7 @@ got_privsep_recv_gotconfig_remotes(struct got_remote_r
>  		struct got_remote_repo *remote;
>  		const size_t min_datalen =
>  		    MIN(sizeof(struct got_imsg_error), sizeof(iremote));
> +		int i;
>  
>  		err = got_privsep_recv_imsg(&imsg, ibuf, min_datalen);
>  		if (err)
> @@ -2041,6 +2056,7 @@ got_privsep_recv_gotconfig_remotes(struct got_remote_r
>  			break;
>  		case GOT_IMSG_GOTCONFIG_REMOTE:
>  			remote = &(*remotes)[*nremotes];
> +			memset(remote, 0, sizeof(*remote));
>  			if (datalen < sizeof(iremote)) {
>  				err = got_error(GOT_ERR_PRIVSEP_LEN);
>  				break;
> @@ -2062,10 +2078,31 @@ got_privsep_recv_gotconfig_remotes(struct got_remote_r
>  			    iremote.name_len, iremote.url_len);
>  			if (remote->url == NULL) {
>  				err = got_error_from_errno("strndup");
> -				free(remote->name);
> +				free_remote_data(remote);
>  				break;
>  			}
>  			remote->mirror_references = iremote.mirror_references;
> +			if (iremote.nbranches > 0) {
> +				remote->branches = recallocarray(NULL, 0,
> +				    iremote.nbranches, sizeof(char *));
> +				if (remote->branches == NULL) {
> +					err = got_error_from_errno("calloc");
> +					free_remote_data(remote);
> +					break;
> +				}
> +			}
> +			remote->nbranches = 0;
> +			for (i = 0; i < iremote.nbranches; i++) {
> +				char *branch;
> +				err = got_privsep_recv_gotconfig_str(&branch,
> +				    ibuf);
> +				if (err) {
> +					free_remote_data(remote);
> +					goto done;
> +				}
> +				remote->branches[i] = branch;
> +				remote->nbranches++;
> +			}
>  			(*nremotes)++;
>  			break;
>  		default:
> @@ -2077,13 +2114,11 @@ got_privsep_recv_gotconfig_remotes(struct got_remote_r
>  		if (err)
>  			break;
>  	}
> -
> +done:
>  	if (err) {
>  		int i;
> -		for (i = 0; i < *nremotes; i++) {
> -			free((*remotes)[i].name);
> -			free((*remotes)[i].url);
> -		}
> +		for (i = 0; i < *nremotes; i++)
> +			free_remote_data(&(*remotes)[i]);
>  		free(*remotes);
>  		*remotes = NULL;
>  		*nremotes = 0;
> blob - 4c90acd881a0f23ba1cb6479838a991e6e8eb61f
> file + lib/repository.c
> --- lib/repository.c
> +++ lib/repository.c
> @@ -681,14 +681,28 @@ got_repo_close(struct got_repository *repo)
>  		got_gotconfig_free(repo->gotconfig);
>  	free(repo->gitconfig_author_name);
>  	free(repo->gitconfig_author_email);
> -	for (i = 0; i < repo->ngitconfig_remotes; i++) {
> -		free(repo->gitconfig_remotes[i].name);
> -		free(repo->gitconfig_remotes[i].url);
> -	}
> +	for (i = 0; i < repo->ngitconfig_remotes; i++)
> +		got_repo_free_remote_repo_data(&repo->gitconfig_remotes[i]);
>  	free(repo->gitconfig_remotes);
>  	free(repo);
>  
>  	return err;
> +}
> +
> +void
> +got_repo_free_remote_repo_data(struct got_remote_repo *repo)
> +{
> +	int i;
> +
> +	free(repo->name);
> +	repo->name = NULL;
> +	free(repo->url);
> +	repo->url = NULL;
> +	for (i = 0; i < repo->nbranches; i++)
> +		free(repo->branches[i]);
> +	free(repo->branches);
> +	repo->branches = NULL;
> +	repo->nbranches = 0;
>  }
>  
>  const struct got_error *
> blob - e7234d40124938d4a98b3294599098e47661c6f5
> file + libexec/got-read-gotconfig/got-read-gotconfig.c
> --- libexec/got-read-gotconfig/got-read-gotconfig.c
> +++ libexec/got-read-gotconfig/got-read-gotconfig.c
> @@ -142,7 +142,16 @@ send_gotconfig_remotes(struct imsgbuf *ibuf,
>  		struct got_imsg_remote iremote;
>  		size_t len = sizeof(iremote);
>  		struct ibuf *wbuf;
> +		struct node_branch *branch;
> +		int nbranches = 0;
>  
> +		branch = repo->branch;
> +		while (branch) {
> +			branch = branch->next;
> +			nbranches++;
> +		}
> +
> +		iremote.nbranches = nbranches;
>  		iremote.mirror_references = repo->mirror_references;
>  
>  		iremote.name_len = strlen(repo->name);
> @@ -189,6 +198,12 @@ send_gotconfig_remotes(struct imsgbuf *ibuf,
>  
>  		free(url);
>  		url = NULL;
> +
> +		branch = repo->branch;
> +		while (branch) {
> +			err = send_gotconfig_str(ibuf, branch->branch_name);
> +			branch = branch->next;
> +		}
>  	}
>  
>  	free(url);
> blob - ab55bd31f17ddbcdf0a483b21903f7e00a588c20
> file + libexec/got-read-gotconfig/gotconfig.h
> --- libexec/got-read-gotconfig/gotconfig.h
> +++ libexec/got-read-gotconfig/gotconfig.h
> @@ -15,6 +15,12 @@
>   * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>   */
>  
> +struct node_branch {
> +	char *branch_name;
> +	struct node_branch *next;
> +	struct node_branch *tail;
> +};
> +
>  struct gotconfig_remote_repo {
>  	TAILQ_ENTRY(gotconfig_remote_repo) entry;
>  	char	*name;
> @@ -23,6 +29,7 @@ struct gotconfig_remote_repo {
>  	char	*protocol;
>  	int	port;
>  	int	mirror_references;
> +	struct	node_branch *branch;
>  };
>  TAILQ_HEAD(gotconfig_remote_repo_list, gotconfig_remote_repo);
>  
> blob - aa7193a5915cdb3f05afe31c665b6ac7fbf31480
> file + libexec/got-read-gotconfig/parse.y
> --- libexec/got-read-gotconfig/parse.y
> +++ libexec/got-read-gotconfig/parse.y
> @@ -86,6 +86,7 @@ typedef struct {
>  	union {
>  		int64_t		 number;
>  		char		*string;
> +		struct node_branch *branch;
>  	} v;
>  	int lineno;
>  } YYSTYPE;
> @@ -93,11 +94,13 @@ typedef struct {
>  %}
>  
>  %token	ERROR
> -%token	REMOTE REPOSITORY SERVER PORT PROTOCOL MIRROR_REFERENCES AUTHOR
> +%token	REMOTE REPOSITORY SERVER PORT PROTOCOL MIRROR_REFERENCES BRANCH
> +%token	AUTHOR
>  %token	<v.string>	STRING
>  %token	<v.number>	NUMBER
>  %type	<v.number>	boolean portplain
>  %type	<v.string>	numberstring
> +%type	<v.branch>	branch xbranch branch_list
>  
>  %%
>  
> @@ -139,6 +142,28 @@ portplain	: numberstring	{
>  			free($1);
>  		}
>  		;
> +branch		: /* empty */				{ $$ = NULL; }
> +		| xbranch			{ $$ = $1; }
> +		| '{' optnl branch_list '}'	{ $$ = $3; }
> +		;
> +xbranch		: STRING {
> +			$$ = calloc(1, sizeof(struct node_branch));
> +			if ($$ == NULL) {
> +				yyerror("calloc");
> +				YYERROR;
> +			}
> +			$$->branch_name = $1;
> +			$$->tail = $$;
> +		}
> +		;
> +branch_list	: xbranch optnl			{ $$ = $1; }
> +		| branch_list comma xbranch optnl {
> +			$1->tail->next = $3;
> +			$1->tail = $3;
> +			$$ = $1;
> +		}
> +		;
> +
>  remoteopts2	: remoteopts2 remoteopts1 nl
>  	   	| remoteopts1 optnl
>  		;
> @@ -175,6 +200,9 @@ remoteopts1	: REPOSITORY STRING {
>  		| PORT portplain {
>  			remote->port = $2;
>  		}
> +		| BRANCH branch {
> +			remote->branch = $2;
> +		}
>  	   	;
>  remote		: REMOTE STRING {
>  			static const struct got_error* error;
> @@ -212,6 +240,9 @@ optnl		: '\n' optnl
>  		;
>  nl		: '\n' optnl
>  		;
> +comma		: ','
> +		| /* empty */
> +		;
>  %%
>  
>  struct keywords {
> @@ -254,6 +285,7 @@ lookup(char *s)
>  	/* This has to be sorted always. */
>  	static const struct keywords keywords[] = {
>  		{"author",		AUTHOR},
> +		{"branch",		BRANCH},
>  		{"mirror-references",	MIRROR_REFERENCES},
>  		{"port",		PORT},
>  		{"protocol",		PROTOCOL},

-- 

Tracey Emery