commit - 1601cb9fb1c61348022d15d2f34797672e2c3cc3
commit + 50b0790ed9a28fced631f31e5b7ca76a9a610ea5
blob - 27b8780c69c81f08f6abd29001c803e5e4e2f601
blob + c244659a0df74322caa231ad293ecbe3d0c6656e
--- got/Makefile
+++ got/Makefile
object_idset.c object_parse.c opentemp.c path.c pack.c \
privsep.c reference.c repository.c sha1.c worktree.c \
inflate.c buf.c rcsutil.c diff3.c lockfile.c \
- deflate.c object_create.c delta_cache.c fetch.c
+ deflate.c object_create.c delta_cache.c fetch.c \
+ gotconfig.c
MAN = ${PROG}.1 got-worktree.5 git-repository.5
CPPFLAGS = -I${.CURDIR}/../include -I${.CURDIR}/../lib
blob - c3d8db9ba60678629dd9370b6ba329c9404d86e8
blob + bd2b0aec4cc1520b2e11a1932a8969d74cd65804
--- got/git-repository.5
+++ got/git-repository.5
.Xr git-config 1 .
.It Pa description
A human-readable description of the repository.
+.It Pa got.conf
+Configuration file for
+.Xr got 1 .
+See
+.Xr got.conf 5 .
.It Pa hooks/
This directory contains hook scripts to run when certain events occur.
.It Pa index
.Xr deflate 3 ,
.Xr SHA1 3 ,
.Xr got-worktree 5
+.Xr got.conf 5
.Sh HISTORY
The Git repository format was initially designed by Linus Torvalds in 2005
and has since been extended by various people involved in the development
blob - 49ede63463e6753340669f22f44dd1d2dc419a94
blob + 8f8ac0e97ca4c5e796623f8c6c176dbabf331a52
--- got/got-worktree.5
+++ got/got-worktree.5
File status information.
.It Pa format
Work tree format number.
+.It Pa got.conf
+Configuration file for
+.Xr got 1 .
+See
+.Xr got.conf 5 .
.It Pa head-ref
Name of the reference to the current branch.
.It Pa lock
.Xr stat 2 ,
.Xr umask 2 ,
.Xr lockf 3 ,
-.Xr git-repository 5
+.Xr git-repository 5 ,
+.Xr got.conf 5
blob - fc2c1967ab5a100d7afd85ed536d8bec33d4c31f
blob + 19a06c86f792b3c3404b00fa130431da3857d9c2
--- got/got.1
+++ got/got.1
is specified,
.Dq origin
will be used.
-The remote repository's URL is obtained from the corresponding entry in the
+The remote repository's URL is obtained from the corresponding entry in
.Xr got.conf 5
-or
+or Git's
.Pa config
file of the local repository, as created by
.Cm got clone .
.Ev GOT_AUTHOR
environment variables with a missing email address.
.Pp
-If present,
-configuration settings in
-.Xr got.conf 5 ,
-or Git's
+.Ev GOT_AUTHOR will be overriden by configuration settings in
+.Xr got.conf 5
+or by Git's
.Dv user.name
and
.Dv user.email
configuration settings in the repository's
.Pa .git/config
-file,
-will override the value of
-.Ev GOT_AUTHOR .
+file.
The
.Dv user.name
and
.It Pa got.conf
Repository-wide configuration settings for
.Nm .
-If present, this configuration file is located in the root directory
-of a Git repository and supersedes any relevant settings in Git's
+If present, a
+.Xr got.conf 5
+configuration file located in the root directory of a Git repository
+supersedes any relevant settings in Git's
.Pa config
file.
+.Pp
+.It Pa .got/got.conf
+Worktree-specific configuration settings for
+.Nm .
+If present, a
+.Xr got.conf
+configuration file in the
+.Pa .got
+meta-data directory of a work tree supersedes any relevant settings in
+the repository's
+.Xr got.conf 5
+configuration file and Git's
+.Pa config
+file.
.El
.Sh EXIT STATUS
.Ex -std got
blob - 0ddfc1d7596b2d3089ba662148743015a36ab107
blob + da2b1166ac33d3f36f0666ef6026f72a8c51cbcc
--- got/got.c
+++ got/got.c
#include "got_blame.h"
#include "got_privsep.h"
#include "got_opentemp.h"
+#include "got_gotconfig.h"
#ifndef nitems
#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
}
static const struct got_error *
-get_author(char **author, struct got_repository *repo)
+get_author(char **author, struct got_repository *repo,
+ struct got_worktree *worktree)
{
const struct got_error *err = NULL;
- const char *got_author, *name, *email;
+ const char *got_author = NULL, *name, *email;
+ const struct got_gotconfig *worktree_conf = NULL, *repo_conf = NULL;
*author = NULL;
- got_author = got_repo_get_gotconfig_author(repo);
+ if (worktree)
+ worktree_conf = got_worktree_get_gotconfig(worktree);
+ repo_conf = got_repo_get_gotconfig(repo);
+
+ /*
+ * Priority of potential author information sources, from most
+ * significant to least significant:
+ * 1) work tree's .got/got.conf file
+ * 2) repository's got.conf file
+ * 3) repository's git config file
+ * 4) environment variables
+ * 5) global git config files (in user's home directory or /etc)
+ */
+
+ if (worktree_conf)
+ got_author = got_gotconfig_get_author(worktree_conf);
+ if (got_author == NULL)
+ got_author = got_gotconfig_get_author(repo_conf);
if (got_author == NULL) {
name = got_repo_get_gitconfig_author_name(repo);
email = got_repo_get_gitconfig_author_email(repo);
if (error)
goto done;
- error = get_author(&author, repo);
+ error = get_author(&author, repo, NULL);
if (error)
return error;
static const struct got_error *
delete_missing_refs(struct got_pathlist_head *their_refs,
- struct got_pathlist_head *their_symrefs, struct got_remote_repo *remote,
+ struct got_pathlist_head *their_symrefs,
+ const struct got_remote_repo *remote,
int verbosity, struct got_repository *repo)
{
const struct got_error *err = NULL, *unlock_err;
const char *remote_name;
char *proto = NULL, *host = NULL, *port = NULL;
char *repo_name = NULL, *server_path = NULL;
- struct got_remote_repo *remotes, *remote = NULL;
+ const struct got_remote_repo *remotes, *remote = NULL;
int nremotes;
char *id_str = NULL;
struct got_repository *repo = NULL;
struct got_worktree *worktree = NULL;
+ const struct got_gotconfig *repo_conf = NULL, *worktree_conf = NULL;
struct got_pathlist_head refs, symrefs, wanted_branches, wanted_refs;
struct got_pathlist_entry *pe;
struct got_object_id *pack_hash = NULL;
if (error)
goto done;
- got_repo_get_gotconfig_remotes(&nremotes, &remotes, repo);
- for (i = 0; i < nremotes; i++) {
- remote = &remotes[i];
- if (strcmp(remote->name, remote_name) == 0)
- break;
+ if (worktree) {
+ worktree_conf = got_worktree_get_gotconfig(worktree);
+ if (worktree_conf) {
+ got_gotconfig_get_remotes(&nremotes, &remotes,
+ worktree_conf);
+ for (i = 0; i < nremotes; i++) {
+ remote = &remotes[i];
+ if (strcmp(remote->name, remote_name) == 0)
+ break;
+ }
+ }
}
- if (i == nremotes) {
+ if (remote == NULL) {
+ repo_conf = got_repo_get_gotconfig(repo);
+ if (repo_conf) {
+ got_gotconfig_get_remotes(&nremotes, &remotes,
+ repo_conf);
+ for (i = 0; i < nremotes; i++) {
+ remote = &remotes[i];
+ if (strcmp(remote->name, remote_name) == 0)
+ break;
+ }
+ }
+ }
+ if (remote == NULL) {
got_repo_get_gitconfig_remotes(&nremotes, &remotes, repo);
for (i = 0; i < nremotes; i++) {
remote = &remotes[i];
if (strcmp(remote->name, remote_name) == 0)
break;
}
- if (i == nremotes) {
- error = got_error_path(remote_name, GOT_ERR_NO_REMOTE);
- goto done;
- }
}
+ if (remote == NULL) {
+ error = got_error_path(remote_name, GOT_ERR_NO_REMOTE);
+ goto done;
+ }
error = got_fetch_parse_uri(&proto, &host, &port, &server_path,
&repo_name, remote->url);
}
static const struct got_error *
-add_tag(struct got_repository *repo, const char *tag_name,
- const char *commit_arg, const char *tagmsg_arg)
+add_tag(struct got_repository *repo, struct got_worktree *worktree,
+ const char *tag_name, const char *commit_arg, const char *tagmsg_arg)
{
const struct got_error *err = NULL;
struct got_object_id *commit_id = NULL, *tag_id = NULL;
if (tag_name[0] == '-')
return got_error_path(tag_name, GOT_ERR_REF_NAME_MINUS);
- err = get_author(&tagger, repo);
+ err = get_author(&tagger, repo, worktree);
if (err)
return err;
goto done;
}
- error = add_tag(repo, tag_name,
+ error = add_tag(repo, worktree, tag_name,
commit_id_str ? commit_id_str : commit_id_arg, tagmsg);
}
done:
if (error != NULL)
goto done;
- error = get_author(&author, repo);
+ error = get_author(&author, repo, worktree);
if (error)
return error;
blob - d6d11e44ab3797c4469bc5d41a882b8be638c18d
blob + 734c2588bf80cb8172f32339ab787239afdda279
--- got/got.conf.5
+++ got/got.conf.5
is the run-time configuration file for
.Xr got 1 .
.Pp
+.Nm
+may be present in the root directory of a Git repository for
+repository-wide settings, or in the
+.Pa .got
+meta-data directory of a work tree to override repository-wide
+settings for
+.Xr got 1
+commands executed within this work tree.
+.Pp
The file format is line-based, with one configuration directive per line.
Any lines beginning with a
.Sq #
.Sh FILES
.Bl -tag -width Ds -compact
.It Pa got.conf
-If present, the
+If present,
.Nm
-configuration file is located in the root directory of a Git repository
-and supersedes any relevant settings in Git's
+located in the root directory of a Git repository supersedes any relevant
+settings in Git's
.Pa config
file.
+.Pp
+.It Pa .got/got.conf
+If present,
+.Nm
+located in the
+.Pa .got
+meta-data directory of a
+.Xr got 1
+work tree supersedes any relevant settings in the repository's
+.Nm
+configuration file and Git's
+.Pa config
+file.
.El
.Sh SEE ALSO
.Xr got 1 ,
-.Xr git-repository 5
+.Xr git-repository 5,
+.Xr got-worktree 5
blob - f22b8bb81af7cfdf1f29b916d2c0fb8cfe1a58a4
blob + 86cf8bc92c4952d24ebe4dce99160c0be49ac598
--- gotweb/Makefile
+++ gotweb/Makefile
object_idset.c object_parse.c opentemp.c path.c pack.c \
privsep.c reference.c repository.c sha1.c worktree.c \
inflate.c buf.c rcsutil.c diff3.c lockfile.c \
- deflate.c object_create.c delta_cache.c
+ deflate.c object_create.c delta_cache.c gotconfig.c
MAN = ${PROG}.conf.5 ${PROG}.8
CPPFLAGS += -I${.CURDIR}/../include -I${.CURDIR}/../lib -I${.CURDIR} \
blob - /dev/null
blob + 3dbe5d7d43cf45ec0e7997d43f266c3ce0c9fcbe (mode 644)
--- /dev/null
+++ include/got_gotconfig.h
+/*
+ * Copyright (c) 2020 Stefan Sperling <stsp@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+struct got_gotconfig;
+
+/*
+ * Obtain the commit author parsed from got.conf.
+ * Return NULL if no configuration file or author could be found.
+ */
+const char *got_gotconfig_get_author(const struct got_gotconfig *);
+
+/*
+ * Obtain the list of remote repositories parsed from got.conf.
+ * Return 0 and NULL if no configuration file or remote repository
+ * could be found.
+ */
+void got_gotconfig_get_remotes(int *, const struct got_remote_repo **,
+ const struct got_gotconfig *);
blob - bc9bddc1aebed32b0412d1f87f93b3ec0b753271
blob + 2b104798d08e7adbf100ae6c9d7a0877630dacdd
--- include/got_repository.h
+++ include/got_repository.h
int mirror_references;
};
-/* Obtain the commit author if parsed from got.conf, else NULL. */
-const char *got_repo_get_gotconfig_author(struct got_repository *);
-
/* Obtain the list of remote repositories parsed from gitconfig. */
-void got_repo_get_gitconfig_remotes(int *, struct got_remote_repo **,
+void got_repo_get_gitconfig_remotes(int *, const struct got_remote_repo **,
struct got_repository *);
-/* Obtain the list of remote repositories parsed from got.conf. */
-void got_repo_get_gotconfig_remotes(int *, struct got_remote_repo **,
- struct got_repository *);
+/*
+ * Obtain a parsed representation of this repository's got.conf file.
+ * Return NULL if this configuration file could not be read.
+ */
+const struct got_gotconfig *got_repo_get_gotconfig(struct got_repository *);
/*
* Obtain paths to various directories within a repository.
blob - c655d810c3ca855bdbd7d38b7191e1243efb8b91
blob + 24fddd52e81d96ff7b1800a61de1f80319326a3e
--- include/got_worktree.h
+++ include/got_worktree.h
*/
const struct got_error *got_worktree_set_base_commit_id(struct got_worktree *,
struct got_repository *, struct got_object_id *);
+
+/*
+ * Obtain a parsed representation of this worktree's got.conf file.
+ * Return NULL if this configuration file could not be read.
+ */
+const struct got_gotconfig *got_worktree_get_gotconfig(struct got_worktree *);
/* A callback function which is invoked when a path is checked out. */
typedef const struct got_error *(*got_worktree_checkout_cb)(void *,
blob - /dev/null
blob + 5e02aa1efeff0dd226e617da410a4663d8376d9a (mode 644)
--- /dev/null
+++ lib/got_lib_gotconfig.h
+/*
+ * Copyright (c) 2020 Stefan Sperling <stsp@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#define GOT_GOTCONFIG_FILENAME "got.conf"
+
+struct got_gotconfig {
+ char *author;
+ int nremotes;
+ struct got_remote_repo *remotes;
+};
+
+const struct got_error *got_gotconfig_read(struct got_gotconfig **,
+ const char *);
+void got_gotconfig_free(struct got_gotconfig *);
blob - 53390eff4e10f3f105c870ac188b9a0db1df2416
blob + 87f25580cb957d598ce95524a992a2d67f95d9ad
--- lib/got_lib_repository.h
+++ lib/got_lib_repository.h
#define GOT_REFS_DIR "refs"
#define GOT_HEAD_FILE "HEAD"
#define GOT_GITCONFIG "config"
-#define GOT_GOTCONFIG "got.conf"
/* Other files and directories inside the git directory. */
#define GOT_FETCH_HEAD_FILE "FETCH_HEAD"
char *gitconfig_owner;
/* Settings read from got.conf. */
- char *gotconfig_author;
- int ngotconfig_remotes;
- struct got_remote_repo *gotconfig_remotes;
+ struct got_gotconfig *gotconfig;
};
const struct got_error*got_repo_cache_object(struct got_repository *,
blob - c45a95888b5015de44ca323f6dd4759e19eb36f4
blob + 067bac22c55a94684a7dcb779417671747de7972
--- lib/got_lib_worktree.h
+++ lib/got_lib_worktree.h
* shared lock must be upgraded to an exclusive lock.
*/
int lockfd;
+
+ /* Absolute path to worktree's got.conf file. */
+ char *gotconfig_path;
+
+ /* Settings read from got.conf. */
+ struct got_gotconfig *gotconfig;
};
struct got_commitable {
blob - /dev/null
blob + c52b0ab71b1a027b3dde159ef7941c99e8811c52 (mode 644)
--- /dev/null
+++ lib/gotconfig.c
+/*
+ * Copyright (c) 2020 Stefan Sperling <stsp@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+#include <sys/queue.h>
+#include <sys/uio.h>
+#include <sys/socket.h>
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <imsg.h>
+#include <sha1.h>
+#include <limits.h>
+
+#include "got_error.h"
+#include "got_object.h"
+#include "got_repository.h"
+
+#include "got_lib_delta.h"
+#include "got_lib_object.h"
+#include "got_lib_privsep.h"
+#include "got_lib_gotconfig.h"
+
+const struct got_error *
+got_gotconfig_read(struct got_gotconfig **conf, const char *gotconfig_path)
+{
+ const struct got_error *err = NULL, *child_err = NULL;
+ int fd = -1;
+ int imsg_fds[2] = { -1, -1 };
+ pid_t pid;
+ struct imsgbuf *ibuf;
+
+ *conf = calloc(1, sizeof(**conf));
+ if (*conf == NULL)
+ return got_error_from_errno("calloc");
+
+ fd = open(gotconfig_path, O_RDONLY);
+ if (fd == -1) {
+ if (errno == ENOENT)
+ return NULL;
+ return got_error_from_errno2("open", gotconfig_path);
+ }
+
+ ibuf = calloc(1, sizeof(*ibuf));
+ if (ibuf == NULL) {
+ err = got_error_from_errno("calloc");
+ goto done;
+ }
+
+ if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, imsg_fds) == -1) {
+ err = got_error_from_errno("socketpair");
+ goto done;
+ }
+
+ pid = fork();
+ if (pid == -1) {
+ err = got_error_from_errno("fork");
+ goto done;
+ } else if (pid == 0) {
+ got_privsep_exec_child(imsg_fds, GOT_PATH_PROG_READ_GOTCONFIG,
+ gotconfig_path);
+ /* not reached */
+ }
+
+ if (close(imsg_fds[1]) == -1) {
+ err = got_error_from_errno("close");
+ goto done;
+ }
+ imsg_fds[1] = -1;
+ imsg_init(ibuf, imsg_fds[0]);
+
+ err = got_privsep_send_gotconfig_parse_req(ibuf, fd);
+ if (err)
+ goto done;
+ fd = -1;
+
+ err = got_privsep_send_gotconfig_author_req(ibuf);
+ if (err)
+ goto done;
+
+ err = got_privsep_recv_gotconfig_str(&(*conf)->author, ibuf);
+ if (err)
+ goto done;
+
+ err = got_privsep_send_gotconfig_remotes_req(ibuf);
+ if (err)
+ goto done;
+
+ err = got_privsep_recv_gotconfig_remotes(&(*conf)->remotes,
+ &(*conf)->nremotes, ibuf);
+ if (err)
+ goto done;
+
+ imsg_clear(ibuf);
+ err = got_privsep_send_stop(imsg_fds[0]);
+ child_err = got_privsep_wait_for_child(pid);
+ if (child_err && err == NULL)
+ err = child_err;
+done:
+ if (imsg_fds[0] != -1 && close(imsg_fds[0]) == -1 && err == NULL)
+ err = got_error_from_errno("close");
+ if (imsg_fds[1] != -1 && close(imsg_fds[1]) == -1 && err == NULL)
+ err = got_error_from_errno("close");
+ if (fd != -1 && close(fd) == -1 && err == NULL)
+ err = got_error_from_errno2("close", gotconfig_path);
+ if (err) {
+ got_gotconfig_free(*conf);
+ *conf = NULL;
+ }
+ free(ibuf);
+ return err;
+}
+
+void
+got_gotconfig_free(struct got_gotconfig *conf)
+{
+ int i;
+
+ free(conf->author);
+
+ for (i = 0; i < conf->nremotes; i++) {
+ free(conf->remotes[i].name);
+ free(conf->remotes[i].url);
+ }
+ free(conf->remotes);
+ free(conf);
+}
+
+const char *
+got_gotconfig_get_author(const struct got_gotconfig *conf)
+{
+ return conf->author;
+}
+
+void
+got_gotconfig_get_remotes(int *nremotes, const struct got_remote_repo **remotes,
+ const struct got_gotconfig *conf)
+{
+ *nremotes = conf->nremotes;
+ *remotes = conf->remotes;
+}
blob - 803b58014d1ed3dce991365b1c035c4c54f45af9
blob + 84e9477170999aa739a81012b9df1b76060ec4f2
--- lib/repository.c
+++ lib/repository.c
#include "got_lib_sha1.h"
#include "got_lib_object_cache.h"
#include "got_lib_repository.h"
+#include "got_lib_gotconfig.h"
#ifndef nitems
#define nitems(_a) (sizeof(_a) / sizeof((_a)[0]))
char *
got_repo_get_path_gotconfig(struct got_repository *repo)
{
- return get_path_git_child(repo, GOT_GOTCONFIG);
+ return get_path_git_child(repo, GOT_GOTCONFIG_FILENAME);
}
-void
-got_repo_get_gitconfig_remotes(int *nremotes, struct got_remote_repo **remotes,
- struct got_repository *repo)
+const struct got_gotconfig *
+got_repo_get_gotconfig(struct got_repository *repo)
{
- *nremotes = repo->ngitconfig_remotes;
- *remotes = repo->gitconfig_remotes;
+ return repo->gotconfig;
}
-const char *
-got_repo_get_gotconfig_author(struct got_repository *repo)
-{
- return repo->gotconfig_author;
-}
-
void
-got_repo_get_gotconfig_remotes(int *nremotes, struct got_remote_repo **remotes,
- struct got_repository *repo)
+got_repo_get_gitconfig_remotes(int *nremotes,
+ const struct got_remote_repo **remotes, struct got_repository *repo)
{
- *nremotes = repo->ngotconfig_remotes;
- *remotes = repo->gotconfig_remotes;
+ *nremotes = repo->ngitconfig_remotes;
+ *remotes = repo->gitconfig_remotes;
}
static int
goto done;
done:
free(repo_gitconfig_path);
- return err;
-}
-
-static const struct got_error *
-parse_gotconfig_file(char **author,
- struct got_remote_repo **remotes, int *nremotes,
- const char *gotconfig_path)
-{
- const struct got_error *err = NULL, *child_err = NULL;
- int fd = -1;
- int imsg_fds[2] = { -1, -1 };
- pid_t pid;
- struct imsgbuf *ibuf;
-
- if (author)
- *author = NULL;
- if (remotes)
- *remotes = NULL;
- if (nremotes)
- *nremotes = 0;
-
- fd = open(gotconfig_path, O_RDONLY);
- if (fd == -1) {
- if (errno == ENOENT)
- return NULL;
- return got_error_from_errno2("open", gotconfig_path);
- }
-
- ibuf = calloc(1, sizeof(*ibuf));
- if (ibuf == NULL) {
- err = got_error_from_errno("calloc");
- goto done;
- }
-
- if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, imsg_fds) == -1) {
- err = got_error_from_errno("socketpair");
- goto done;
- }
-
- pid = fork();
- if (pid == -1) {
- err = got_error_from_errno("fork");
- goto done;
- } else if (pid == 0) {
- got_privsep_exec_child(imsg_fds, GOT_PATH_PROG_READ_GOTCONFIG,
- gotconfig_path);
- /* not reached */
- }
-
- if (close(imsg_fds[1]) == -1) {
- err = got_error_from_errno("close");
- goto done;
- }
- imsg_fds[1] = -1;
- imsg_init(ibuf, imsg_fds[0]);
-
- err = got_privsep_send_gotconfig_parse_req(ibuf, fd);
- if (err)
- goto done;
- fd = -1;
-
- if (author) {
- err = got_privsep_send_gotconfig_author_req(ibuf);
- if (err)
- goto done;
-
- err = got_privsep_recv_gotconfig_str(author, ibuf);
- if (err)
- goto done;
- }
-
- if (remotes && nremotes) {
- err = got_privsep_send_gotconfig_remotes_req(ibuf);
- if (err)
- goto done;
-
- err = got_privsep_recv_gotconfig_remotes(remotes,
- nremotes, ibuf);
- if (err)
- goto done;
- }
-
- imsg_clear(ibuf);
- err = got_privsep_send_stop(imsg_fds[0]);
- child_err = got_privsep_wait_for_child(pid);
- if (child_err && err == NULL)
- err = child_err;
-done:
- if (imsg_fds[0] != -1 && close(imsg_fds[0]) == -1 && err == NULL)
- err = got_error_from_errno("close");
- if (imsg_fds[1] != -1 && close(imsg_fds[1]) == -1 && err == NULL)
- err = got_error_from_errno("close");
- if (fd != -1 && close(fd) == -1 && err == NULL)
- err = got_error_from_errno2("close", gotconfig_path);
- if (err) {
- if (author) {
- free(*author);
- *author = NULL;
- }
- }
- free(ibuf);
return err;
}
if (gotconfig_path == NULL)
return got_error_from_errno("got_repo_get_path_gotconfig");
- err = parse_gotconfig_file(&repo->gotconfig_author,
- &repo->gotconfig_remotes, &repo->ngotconfig_remotes,
- gotconfig_path);
+ err = got_gotconfig_read(&repo->gotconfig, gotconfig_path);
free(gotconfig_path);
return err;
}
err = got_error_from_errno("close");
}
- free(repo->gotconfig_author);
- for (i = 0; i < repo->ngotconfig_remotes; i++) {
- free(repo->gotconfig_remotes[i].name);
- free(repo->gotconfig_remotes[i].url);
- }
- free(repo->gotconfig_remotes);
+ if (repo->gotconfig)
+ got_gotconfig_free(repo->gotconfig);
free(repo->gitconfig_author_name);
free(repo->gitconfig_author_email);
for (i = 0; i < repo->ngitconfig_remotes; i++) {
blob - 3d078a53722abb4003341e563cdeca7f44e4dffe
blob + cade3cf24e001a4b116276ca9e6b7c97fa64e827
--- lib/worktree.c
+++ lib/worktree.c
#include "got_lib_object_create.h"
#include "got_lib_object_idset.h"
#include "got_lib_diff.h"
+#include "got_lib_gotconfig.h"
#ifndef MIN
#define MIN(_a,_b) ((_a) < (_b) ? (_a) : (_b))
err = read_meta_file(&(*worktree)->head_ref_name, path_got,
GOT_WORKTREE_HEAD_REF);
+ if (err)
+ goto done;
+
+ if (asprintf(&(*worktree)->gotconfig_path, "%s/%s/%s",
+ (*worktree)->root_path,
+ GOT_WORKTREE_GOT_DIR, GOT_GOTCONFIG_FILENAME) == -1) {
+ err = got_error_from_errno("asprintf");
+ goto done;
+ }
+
+ err = got_gotconfig_read(&(*worktree)->gotconfig,
+ (*worktree)->gotconfig_path);
done:
if (repo)
got_repo_close(repo);
err = got_error_from_errno2("close",
got_worktree_get_root_path(worktree));
free(worktree->root_path);
+ free(worktree->gotconfig_path);
+ got_gotconfig_free(worktree->gotconfig);
free(worktree);
return err;
}
{
return worktree->repo_path;
}
-
const char *
got_worktree_get_path_prefix(struct got_worktree *worktree)
{
free(id_str);
free(path_got);
return err;
+}
+
+const struct got_gotconfig *
+got_worktree_get_gotconfig(struct got_worktree *worktree)
+{
+ return worktree->gotconfig;
}
static const struct got_error *
blob - 13a4e58bcc3693cd4eb419089a8e29ea5e377524
blob + 7e2e93f01cb45ae2344a72007a67db4942a023f5
--- regress/cmdline/commit.sh
+++ regress/cmdline/commit.sh
fi
echo "from: Flan Luck <flan_luck@openbsd.org>" \
+ > $testroot/stdout.expected
+ cmp -s $testroot/stdout.expected $testroot/stdout
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ diff -u $testroot/stdout.expected $testroot/stdout
+ fi
+ test_done "$testroot" "$ret"
+}
+
+function test_commit_gotconfig_worktree_author {
+ local testroot=`test_init commit_gotconfig_worktree_author`
+
+ got checkout $testroot/repo $testroot/wt > /dev/null
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+ echo 'author "Flan Luck <flan_luck@openbsd.org>"' \
+ > $testroot/repo/.git/got.conf
+ echo 'author "Flan Squee <flan_squee@openbsd.org>"' \
+ > $testroot/wt/.got/got.conf
+
+ echo "modified alpha" > $testroot/wt/alpha
+ (cd $testroot/wt && got commit -m 'test gotconfig author' > /dev/null)
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ (cd $testroot/repo && got log -l1 | grep ^from: > $testroot/stdout)
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ echo "from: Flan Squee <flan_squee@openbsd.org>" \
> $testroot/stdout.expected
cmp -s $testroot/stdout.expected $testroot/stdout
ret="$?"
run_test test_commit_no_email
run_test test_commit_tree_entry_sorting
run_test test_commit_gotconfig_author
+run_test test_commit_gotconfig_worktree_author
run_test test_commit_gitconfig_author
run_test test_commit_xbit_change
run_test test_commit_normalizes_filemodes
blob - 22fde4a90a75e2c5a0bb28cb02c1fa209ef6f3e2
blob + a131768e455946cd8609feb790b2dd1a83b1644c
--- regress/cmdline/fetch.sh
+++ regress/cmdline/fetch.sh
>> $testroot/stdout.expected
echo "refs/remotes/origin/master: $commit_id" \
>> $testroot/stdout.expected
+
+ cmp -s $testroot/stdout $testroot/stdout.expected
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ diff -u $testroot/stdout.expected $testroot/stdout
+ fi
+ test_done "$testroot" "$ret"
+}
+
+function test_fetch_gotconfig_remote_repo {
+ local testroot=`test_init fetch_gotconfig_remote_repo`
+ local testurl=ssh://127.0.0.1/$testroot
+ local commit_id=`git_show_head $testroot/repo`
+
+ got branch -r $testroot/repo -c $commit_id foo
+ got ref -r $testroot/repo -c $commit_id refs/hoo/boo/zoo
+ got tag -r $testroot/repo -c $commit_id -m tag "1.0" >/dev/null
+
+ got clone -q $testurl/repo $testroot/repo-clone
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ echo "got clone command failed unexpectedly" >&2
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+cat > $testroot/repo-clone/got.conf <<EOF
+remote "foobar" {
+ protocol ssh
+ server 127.0.0.1
+ repository "$testroot/repo"
+}
+
+remote "barbaz" {
+ protocol ssh
+ server 127.0.0.1
+ repository "$testroot/does-not-exist"
+}
+EOF
+ (cd $testroot/repo-clone && got fetch -l foobar \
+ > $testroot/stdout)
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ echo "got fetch command failed unexpectedly" >&2
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+ echo "Connecting to \"foobar\" 127.0.0.1" > $testroot/stdout.expected
+ got ref -l -r $testroot/repo >> $testroot/stdout.expected
+
cmp -s $testroot/stdout $testroot/stdout.expected
ret="$?"
if [ "$ret" != "0" ]; then
diff -u $testroot/stdout.expected $testroot/stdout
+ test_done "$testroot" "$ret"
+ return 1
fi
+
+ got checkout $testroot/repo $testroot/wt > /dev/null
+
+cat > $testroot/wt/.got/got.conf <<EOF
+remote "barbaz" {
+ protocol ssh
+ server 127.0.0.1
+ repository "$testroot/repo"
+}
+EOF
+ (cd $testroot/wt && got fetch -l barbaz > $testroot/stdout)
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ echo "got fetch command failed unexpectedly" >&2
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ echo "Connecting to \"barbaz\" 127.0.0.1" > $testroot/stdout.expected
+ got ref -l -r $testroot/repo >> $testroot/stdout.expected
+
+ cmp -s $testroot/stdout $testroot/stdout.expected
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ diff -u $testroot/stdout.expected $testroot/stdout
+ fi
test_done "$testroot" "$ret"
+
}
test_parseargs "$@"
run_test test_fetch_replace_symref
run_test test_fetch_update_headref
run_test test_fetch_headref_deleted_locally
+run_test test_fetch_gotconfig_remote_repo
blob - 9834aeeb0ffac0003745cb75c3ecbe20d3a2d6ff
blob + f9e0d6b0ee0b8e3d702b742b51baa3819d382ff2
--- regress/fetch/Makefile
+++ regress/fetch/Makefile
SRCS = error.c privsep.c reference.c sha1.c object.c object_parse.c path.c \
opentemp.c repository.c lockfile.c object_cache.c pack.c inflate.c \
deflate.c delta.c delta_cache.c object_idset.c object_create.c \
- fetch.c fetch_test.c
+ fetch.c gotconfig.c fetch_test.c
CPPFLAGS = -I${.CURDIR}/../../include -I${.CURDIR}/../../lib
LDADD = -lutil -lz
blob - aafde1a4c7fe645f39e2b0acb46faa64767369c7
blob + 41af3bef58e4bdab819c0a659369ee2a3c2f2e2f
--- tog/Makefile
+++ tog/Makefile
object_idset.c object_parse.c opentemp.c path.c pack.c \
privsep.c reference.c repository.c sha1.c worktree.c \
utf8.c inflate.c buf.c rcsutil.c diff3.c \
- lockfile.c deflate.c object_create.c delta_cache.c
+ lockfile.c deflate.c object_create.c delta_cache.c \
+ gotconfig.c
MAN = ${PROG}.1
CPPFLAGS = -I${.CURDIR}/../include -I${.CURDIR}/../lib