commit - e385fc421f331989f2e6518465e5ead42e5a0618
commit + 6480c871c8f9ffdce90c10e7a7313e1187de019a
blob - b008eec8b509913ce8be844f671bf5e5290d0296
blob + 1edb356b8da783560a7d0691d12708ca5376fb29
--- got/got.c
+++ got/got.c
if (TAILQ_EMPTY(&wanted_branches)) {
if (!fetch_all_branches)
fetch_all_branches = remote->fetch_all_branches;
- for (i = 0; i < remote->nbranches; i++) {
+ for (i = 0; i < remote->nfetch_branches; i++) {
got_pathlist_append(&wanted_branches,
- remote->branches[i], NULL);
+ remote->fetch_branches[i], NULL);
}
}
if (TAILQ_EMPTY(&wanted_refs)) {
- for (i = 0; i < remote->nrefs; i++) {
+ for (i = 0; i < remote->nfetch_refs; i++) {
got_pathlist_append(&wanted_refs,
- remote->refs[i], NULL);
+ remote->fetch_refs[i], NULL);
}
}
error = got_fetch_parse_uri(&proto, &host, &port, &server_path,
- &repo_name, remote->url);
+ &repo_name, remote->fetch_url);
if (error)
goto done;
}
error = got_fetch_parse_uri(&proto, &host, &port, &server_path,
- &repo_name, remote->url);
+ &repo_name, remote->send_url);
if (error)
goto done;
blob - 58e0d602e43b9e45856efd11c355b7c86cccedbc
blob + 7b400d18d82d02aba5e0b4d7b7dad40a43b51be5
--- got/got.conf.5
+++ got/got.conf.5
The specified
.Ar name
can be used to refer to the remote repository on the command line of
-.Cm got fetch .
+.Cm got fetch
+and
+.Cm got send .
.Pp
Information about this repository is declared in a block of options
enclosed in curly brackets:
.It Ic branch Brq Ar branch ...
Specify one or more branches which
.Cm got fetch
-should fetch from the remote repository by default.
+and
+.Cm got send
+should fetch and send from the remote repository by default.
The list of branches specified here can be overridden at the
.Cm got fetch
-command line with the
+and
+.Cm got send
+command lines with the
.Fl b
option.
.It Ic fetch-all-branches Ar yes | no
.Dq refs/heads/
namespace will be updated directly to match the corresponding branches in
the remote repository.
+.It Ic fetch Brq ...
+An optional
+.Ic fetch
+block may contain any of the following configuration settings
+for use by
+.Cm got fetch ,
+overriding corresponding settings in the containing
+.Ic remote Ar name Brq ...
+block.
+.Bl -bullet
+.It
+.Ic server Ar hostname
+.It
+.Ic repository Ar path
+.It
+.Ic protocol Ar path
+.It
+.Ic port Ar port
+.It
+.Ic branch Brq Ar branch ...
.El
+.It Ic send Brq ...
+An optional
+.Ic send
+block may contain any of the following configuration settings
+for use by
+.Cm got send ,
+overriding corresponding settings in the containing
+.Ic remote Ar name Brq ...
+block.
+.Bl -bullet
+.It
+.Ic server Ar hostname
+.It
+.Ic repository Ar path
+.It
+.Ic protocol Ar path
+.It
+.Ic port Ar port
+.It
+.Ic branch Brq Ar branch ...
.El
+.El
+.El
.Sh EXAMPLES
Configure author information:
.Bd -literal -offset indent
mirror-references yes
}
.Ed
+.Pp
+Fetch changes via the Git protocol and send changes via the SSH protocol:
+.Bd -literal -offset indent
+remote "origin" {
+ repository my_repo
+ server git.example.com
+ protocol git
+ send {
+ server git@git.example.com
+ protocol ssh
+ }
+}
+.Ed
.Sh FILES
.Bl -tag -width Ds -compact
.It Pa got.conf
blob - 9c2f8389ca9fc09f3499080dd949d464f4e85c67
blob + cad8fd52bf0d74bccf0f30ddd4d2173398530bcc
--- gotadmin/gotadmin.c
+++ gotadmin/gotadmin.c
got_gotconfig_get_remotes(&nremotes, &remotes, gotconfig);
for (i = 0; i < nremotes; i++) {
printf("remote \"%s\": %s\n", remotes[i].name,
- remotes[i].url);
+ remotes[i].fetch_url);
}
}
blob - daa3c3755d6b05b2eb1cfa3014d128ff50539685
blob + 16dcde35f5cc7689f88ae7e3486c4f1fe72aa8f2
--- include/got_repository.h
+++ include/got_repository.h
/* Information about one remote repository. */
struct got_remote_repo {
char *name;
- char *url;
+ char *fetch_url;
+ char *send_url;
/*
- * If set, references are mirrored 1:1 into the local repository.
+ * If set, fetched references are mirrored 1:1 into our repository.
* If not set, references are mapped into "refs/remotes/$name/".
*/
int mirror_references;
int fetch_all_branches;
/* Branches to fetch by default. */
- int nbranches;
- char **branches;
+ int nfetch_branches;
+ char **fetch_branches;
+ /* Branches to send by default. */
+ int nsend_branches;
+ char **send_branches;
+
/* Other arbitrary references to fetch by default. */
- int nrefs;
- char **refs;
+ int nfetch_refs;
+ char **fetch_refs;
};
/*
blob - daaf7f3639f1a1257da430a23bbc5529db74d685
blob + e60e8eb1808bf28909abf7034ebbce19c0dc5100
--- lib/got_lib_privsep.h
+++ lib/got_lib_privsep.h
} __attribute__((__packed__));
/*
- * Structure for GOT_IMSG_GITCONFIG_REMOTE data.
+ * Structure for GOT_IMSG_GOTCONFIG_REMOTE and
+ * GOT_IMSG_GOTCONFIG_REMOTE data.
*/
struct got_imsg_remote {
size_t name_len;
- size_t url_len;
+ size_t fetch_url_len;
+ size_t send_url_len;
int mirror_references;
int fetch_all_branches;
- int nbranches;
- int nrefs;
+ int nfetch_branches;
+ int nsend_branches;
+ int nfetch_refs;
- /* Followed by name_len + url_len data bytes. */
- /* Followed by nbranches GOT_IMSG_GITCONFIG_STR_VAL messages. */
- /* Followed by nrefs GOT_IMSG_GITCONFIG_STR_VAL messages. */
+ /* Followed by name_len data bytes. */
+ /* Followed by fetch_url_len + send_url_len data bytes. */
+ /* Followed by nfetch_branches GOT_IMSG_GITCONFIG_STR_VAL messages. */
+ /* Followed by nsend_branches GOT_IMSG_GITCONFIG_STR_VAL messages. */
+ /* Followed by nfetch_refs GOT_IMSG_GITCONFIG_STR_VAL messages. */
} __attribute__((__packed__));
/*
blob - ecad96e05628c923f414e7613a59a1e54b82bba0
blob + 4846f5880ced5034d986881b1a612ba1062686af
--- lib/privsep.c
+++ lib/privsep.c
int i;
free(remote->name);
- free(remote->url);
- for (i = 0; i < remote->nbranches; i++)
- free(remote->branches[i]);
- free(remote->branches);
- for (i = 0; i < remote->nrefs; i++)
- free(remote->refs[i]);
- free(remote->refs);
+ free(remote->fetch_url);
+ free(remote->send_url);
+ for (i = 0; i < remote->nfetch_branches; i++)
+ free(remote->fetch_branches[i]);
+ free(remote->fetch_branches);
+ for (i = 0; i < remote->nsend_branches; i++)
+ free(remote->send_branches[i]);
+ free(remote->send_branches);
+ for (i = 0; i < remote->nfetch_refs; i++)
+ free(remote->fetch_refs[i]);
+ free(remote->fetch_refs);
}
const struct got_error *
break;
}
memcpy(&iremote, imsg.data, sizeof(iremote));
- if (iremote.name_len == 0 || iremote.url_len == 0 ||
+ if (iremote.name_len == 0 ||
+ iremote.fetch_url_len == 0 ||
+ iremote.send_url_len == 0 ||
(sizeof(iremote) + iremote.name_len +
- iremote.url_len) > datalen) {
+ iremote.fetch_url_len + iremote.send_url_len) > datalen) {
err = got_error(GOT_ERR_PRIVSEP_LEN);
break;
}
err = got_error_from_errno("strndup");
break;
}
- remote->url = strndup(imsg.data + sizeof(iremote) +
- iremote.name_len, iremote.url_len);
- if (remote->url == NULL) {
+ remote->fetch_url = strndup(imsg.data + sizeof(iremote) +
+ iremote.name_len, iremote.fetch_url_len);
+ if (remote->fetch_url == NULL) {
err = got_error_from_errno("strndup");
free_remote_data(remote);
break;
}
+ remote->send_url = strndup(imsg.data + sizeof(iremote) +
+ iremote.name_len + iremote.fetch_url_len,
+ iremote.send_url_len);
+ if (remote->send_url == NULL) {
+ err = got_error_from_errno("strndup");
+ free_remote_data(remote);
+ break;
+ }
remote->mirror_references = iremote.mirror_references;
remote->fetch_all_branches = iremote.fetch_all_branches;
- remote->nbranches = 0;
- remote->branches = NULL;
- remote->nrefs = 0;
- remote->refs = NULL;
+ remote->nfetch_branches = 0;
+ remote->fetch_branches = NULL;
+ remote->nsend_branches = 0;
+ remote->send_branches = NULL;
+ remote->nfetch_refs = 0;
+ remote->fetch_refs = NULL;
(*nremotes)++;
break;
default:
return err;
}
-
const struct got_error *
got_privsep_recv_gotconfig_remotes(struct got_remote_repo **remotes,
int *nremotes, struct imsgbuf *ibuf)
break;
}
memcpy(&iremote, imsg.data, sizeof(iremote));
- if (iremote.name_len == 0 || iremote.url_len == 0 ||
+ if (iremote.name_len == 0 ||
+ (iremote.fetch_url_len == 0 &&
+ iremote.send_url_len == 0) ||
(sizeof(iremote) + iremote.name_len +
- iremote.url_len) > datalen) {
+ iremote.fetch_url_len + iremote.send_url_len) >
+ datalen) {
err = got_error(GOT_ERR_PRIVSEP_LEN);
break;
}
err = got_error_from_errno("strndup");
break;
}
- remote->url = strndup(imsg.data + sizeof(iremote) +
- iremote.name_len, iremote.url_len);
- if (remote->url == NULL) {
+ remote->fetch_url = strndup(imsg.data +
+ sizeof(iremote) + iremote.name_len,
+ iremote.fetch_url_len);
+ if (remote->fetch_url == NULL) {
+ err = got_error_from_errno("strndup");
+ free_remote_data(remote);
+ break;
+ }
+ remote->send_url = strndup(imsg.data +
+ sizeof(iremote) + iremote.name_len +
+ iremote.fetch_url_len, iremote.send_url_len);
+ if (remote->send_url == NULL) {
err = got_error_from_errno("strndup");
free_remote_data(remote);
break;
}
remote->mirror_references = iremote.mirror_references;
remote->fetch_all_branches = iremote.fetch_all_branches;
- if (iremote.nbranches > 0) {
- remote->branches = recallocarray(NULL, 0,
- iremote.nbranches, sizeof(char *));
- if (remote->branches == NULL) {
+ if (iremote.nfetch_branches > 0) {
+ remote->fetch_branches = recallocarray(NULL, 0,
+ iremote.nfetch_branches, sizeof(char *));
+ if (remote->fetch_branches == NULL) {
err = got_error_from_errno("calloc");
free_remote_data(remote);
break;
}
}
- remote->nbranches = 0;
- for (i = 0; i < iremote.nbranches; i++) {
+ remote->nfetch_branches = 0;
+ for (i = 0; i < iremote.nfetch_branches; i++) {
char *branch;
err = got_privsep_recv_gotconfig_str(&branch,
ibuf);
free_remote_data(remote);
goto done;
}
- remote->branches[i] = branch;
- remote->nbranches++;
+ remote->fetch_branches[i] = branch;
+ remote->nfetch_branches++;
}
- if (iremote.nrefs > 0) {
- remote->refs = recallocarray(NULL, 0,
- iremote.nrefs, sizeof(char *));
- if (remote->refs == NULL) {
+ if (iremote.nsend_branches > 0) {
+ remote->send_branches = recallocarray(NULL, 0,
+ iremote.nsend_branches, sizeof(char *));
+ if (remote->send_branches == NULL) {
err = got_error_from_errno("calloc");
free_remote_data(remote);
break;
}
}
- remote->nrefs = 0;
- for (i = 0; i < iremote.nrefs; i++) {
+ remote->nsend_branches = 0;
+ for (i = 0; i < iremote.nsend_branches; i++) {
+ char *branch;
+ err = got_privsep_recv_gotconfig_str(&branch,
+ ibuf);
+ if (err) {
+ free_remote_data(remote);
+ goto done;
+ }
+ remote->send_branches[i] = branch;
+ remote->nsend_branches++;
+ }
+ if (iremote.nfetch_refs > 0) {
+ remote->fetch_refs = recallocarray(NULL, 0,
+ iremote.nfetch_refs, sizeof(char *));
+ if (remote->fetch_refs == NULL) {
+ err = got_error_from_errno("calloc");
+ free_remote_data(remote);
+ break;
+ }
+ }
+ remote->nfetch_refs = 0;
+ for (i = 0; i < iremote.nfetch_refs; i++) {
char *ref;
err = got_privsep_recv_gotconfig_str(&ref,
ibuf);
free_remote_data(remote);
goto done;
}
- remote->refs[i] = ref;
- remote->nrefs++;
+ remote->fetch_refs[i] = ref;
+ remote->nfetch_refs++;
}
(*nremotes)++;
break;
blob - 3d857e3a7784f358729bd0b93b349fa77eaa1c10
blob + deb44a1116a2fcd589ff0e0db2fcc4a1c0e2c63d
--- lib/repository.c
+++ lib/repository.c
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;
+ free(repo->fetch_url);
+ repo->fetch_url = NULL;
+ free(repo->send_url);
+ repo->send_url = NULL;
+ for (i = 0; i < repo->nfetch_branches; i++)
+ free(repo->fetch_branches[i]);
+ free(repo->fetch_branches);
+ repo->fetch_branches = NULL;
+ repo->nfetch_branches = 0;
+ for (i = 0; i < repo->nsend_branches; i++)
+ free(repo->send_branches[i]);
+ free(repo->send_branches);
+ repo->send_branches = NULL;
+ repo->nsend_branches = 0;
}
const struct got_error *
blob - eadef712009b2da9a414361c8395ccbd43f2b1aa
blob + 3ce93f09be615d41528eb6af7e5f5a1bd77ce92f
--- libexec/got-read-gitconfig/got-read-gitconfig.c
+++ libexec/got-read-gitconfig/got-read-gitconfig.c
iremote.mirror_references = remotes[i].mirror_references;
iremote.name_len = strlen(remotes[i].name);
len += iremote.name_len;
- iremote.url_len = strlen(remotes[i].url);
- len += iremote.url_len;
+ iremote.fetch_url_len = strlen(remotes[i].fetch_url);
+ len += iremote.fetch_url_len;
+ iremote.send_url_len = strlen(remotes[i].send_url);
+ len += iremote.send_url_len;
wbuf = imsg_create(ibuf, GOT_IMSG_GITCONFIG_REMOTE, 0, 0, len);
if (wbuf == NULL)
ibuf_free(wbuf);
return err;
}
- if (imsg_add(wbuf, remotes[i].url, iremote.url_len) == -1) {
+ if (imsg_add(wbuf, remotes[i].fetch_url, iremote.fetch_url_len) == -1) {
err = got_error_from_errno(
"imsg_add GITCONFIG_REMOTE");
ibuf_free(wbuf);
return err;
}
+ if (imsg_add(wbuf, remotes[i].send_url, iremote.send_url_len) == -1) {
+ err = got_error_from_errno(
+ "imsg_add GITCONFIG_REMOTE");
+ ibuf_free(wbuf);
+ return err;
+ }
wbuf->fd = -1;
imsg_close(ibuf, wbuf);
*end = '\0';
remotes[i].name = name;
- remotes[i].url = got_gitconfig_get_str(gitconfig,
+ remotes[i].fetch_url = got_gitconfig_get_str(gitconfig,
node->field, "url");
- if (remotes[i].url == NULL) {
+ if (remotes[i].fetch_url == NULL) {
err = got_error(GOT_ERR_GITCONFIG_SYNTAX);
goto done;
}
+ remotes[i].send_url = got_gitconfig_get_str(gitconfig,
+ node->field, "pushurl");
+ if (remotes[i].send_url == NULL)
+ remotes[i].send_url = got_gitconfig_get_str(gitconfig,
+ node->field, "url");
+ if (remotes[i].send_url == NULL) {
+ err = got_error(GOT_ERR_GITCONFIG_SYNTAX);
+ goto done;
+ }
+
remotes[i].mirror_references = 0;
mirror = got_gitconfig_get_str(gitconfig, node->field,
"mirror");
blob - d2b3b15299aad1d02917abf96a7496072e5c4af3
blob + 87b6e325e90f1a5df5293fea97f21d0e0ec8ecdd
--- libexec/got-read-gotconfig/got-read-gotconfig.c
+++ libexec/got-read-gotconfig/got-read-gotconfig.c
}
static const struct got_error *
-make_repo_url(char **url, struct gotconfig_remote_repo *repo)
+make_fetch_url(char **url, struct gotconfig_remote_repo *repo)
{
const struct got_error *err = NULL;
char *s = NULL, *p = NULL;
+ const char *protocol, *server, *repo_path;
+ int port;
*url = NULL;
- if (asprintf(&s, "%s://", repo->protocol) == -1)
+ if (repo->fetch_config && repo->fetch_config->protocol)
+ protocol = repo->fetch_config->protocol;
+ else
+ protocol = repo->protocol;
+ if (protocol == NULL)
+ return got_error_fmt(GOT_ERR_PARSE_CONFIG,
+ "fetch protocol required for remote repository \"%s\"",
+ repo->name);
+ if (asprintf(&s, "%s://", protocol) == -1)
return got_error_from_errno("asprintf");
- if (repo->server) {
- p = s;
- s = NULL;
- if (asprintf(&s, "%s%s", p, repo->server) == -1) {
- err = got_error_from_errno("asprintf");
- goto done;
- }
- free(p);
- p = NULL;
+ if (repo->fetch_config && repo->fetch_config->server)
+ server = repo->fetch_config->server;
+ else
+ server = repo->server;
+ if (server == NULL)
+ return got_error_fmt(GOT_ERR_PARSE_CONFIG,
+ "fetch server required for remote repository \"%s\"",
+ repo->name);
+ p = s;
+ s = NULL;
+ if (asprintf(&s, "%s%s", p, server) == -1) {
+ err = got_error_from_errno("asprintf");
+ goto done;
}
+ free(p);
+ p = NULL;
- if (repo->port) {
+ if (repo->fetch_config && repo->fetch_config->server)
+ port = repo->fetch_config->port;
+ else
+ port = repo->port;
+ if (port) {
p = s;
s = NULL;
if (asprintf(&s, "%s:%d", p, repo->port) == -1) {
p = NULL;
}
- if (repo->repository) {
- char *repo_path = repo->repository;
- while (repo_path[0] == '/')
- repo_path++;
+ if (repo->fetch_config && repo->fetch_config->repository)
+ repo_path = repo->fetch_config->repository;
+ else
+ repo_path = repo->repository;
+ if (repo_path == NULL)
+ return got_error_fmt(GOT_ERR_PARSE_CONFIG,
+ "fetch repository path required for remote "
+ "repository \"%s\"", repo->name);
+
+ while (repo_path[0] == '/')
+ repo_path++;
+ p = s;
+ s = NULL;
+ if (asprintf(&s, "%s/%s", p, repo_path) == -1) {
+ err = got_error_from_errno("asprintf");
+ goto done;
+ }
+ free(p);
+ p = NULL;
+
+ got_path_strip_trailing_slashes(s);
+done:
+ if (err) {
+ free(s);
+ free(p);
+ } else
+ *url = s;
+ return err;
+}
+
+static const struct got_error *
+make_send_url(char **url, struct gotconfig_remote_repo *repo)
+{
+ const struct got_error *err = NULL;
+ char *s = NULL, *p = NULL;
+ const char *protocol, *server, *repo_path;
+ int port;
+
+ *url = NULL;
+
+ if (repo->send_config && repo->send_config->protocol)
+ protocol = repo->send_config->protocol;
+ else
+ protocol = repo->protocol;
+ if (protocol == NULL)
+ return got_error_fmt(GOT_ERR_PARSE_CONFIG,
+ "send protocol required for remote repository \"%s\"",
+ repo->name);
+ if (asprintf(&s, "%s://", protocol) == -1)
+ return got_error_from_errno("asprintf");
+
+ if (repo->send_config && repo->send_config->server)
+ server = repo->send_config->server;
+ else
+ server = repo->server;
+ if (server == NULL)
+ return got_error_fmt(GOT_ERR_PARSE_CONFIG,
+ "send server required for remote repository \"%s\"",
+ repo->name);
+ p = s;
+ s = NULL;
+ if (asprintf(&s, "%s%s", p, server) == -1) {
+ err = got_error_from_errno("asprintf");
+ goto done;
+ }
+ free(p);
+ p = NULL;
+
+ if (repo->send_config && repo->send_config->server)
+ port = repo->send_config->port;
+ else
+ port = repo->port;
+ if (port) {
p = s;
s = NULL;
- if (asprintf(&s, "%s/%s", p, repo_path) == -1) {
+ if (asprintf(&s, "%s:%d", p, repo->port) == -1) {
err = got_error_from_errno("asprintf");
goto done;
}
p = NULL;
}
+ if (repo->send_config && repo->send_config->repository)
+ repo_path = repo->send_config->repository;
+ else
+ repo_path = repo->repository;
+ if (repo_path == NULL)
+ return got_error_fmt(GOT_ERR_PARSE_CONFIG,
+ "send repository path required for remote "
+ "repository \"%s\"", repo->name);
+
+ while (repo_path[0] == '/')
+ repo_path++;
+ p = s;
+ s = NULL;
+ if (asprintf(&s, "%s/%s", p, repo_path) == -1) {
+ err = got_error_from_errno("asprintf");
+ goto done;
+ }
+ free(p);
+ p = NULL;
+
got_path_strip_trailing_slashes(s);
done:
if (err) {
const struct got_error *err = NULL;
struct got_imsg_remotes iremotes;
struct gotconfig_remote_repo *repo;
- char *url = NULL;
+ char *fetch_url = NULL, *send_url = NULL;
iremotes.nremotes = nremotes;
if (imsg_compose(ibuf, GOT_IMSG_GOTCONFIG_REMOTES, 0, 0, -1,
struct ibuf *wbuf;
struct node_branch *branch;
struct node_ref *ref;
- int nbranches = 0, nrefs = 0;
+ int nfetch_branches = 0, nsend_branches = 0, nfetch_refs = 0;
- branch = repo->branch;
- while (branch) {
- branch = branch->next;
- nbranches++;
+ if (repo->fetch_config && repo->fetch_config->branch) {
+ branch = repo->fetch_config->branch;
+ while (branch) {
+ branch = branch->next;
+ nfetch_branches++;
+ }
+ } else {
+ branch = repo->branch;
+ while (branch) {
+ branch = branch->next;
+ nfetch_branches++;
+ }
}
- ref = repo->ref;
+ if (repo->send_config && repo->send_config->branch) {
+ branch = repo->send_config->branch;
+ while (branch) {
+ branch = branch->next;
+ nsend_branches++;
+ }
+ } else {
+ branch = repo->branch;
+ while (branch) {
+ branch = branch->next;
+ nsend_branches++;
+ }
+ }
+
+ ref = repo->fetch_ref;
while (ref) {
ref = ref->next;
- nrefs++;
+ nfetch_refs++;
}
- iremote.nbranches = nbranches;
- iremote.nrefs = nrefs;
+ iremote.nfetch_branches = nfetch_branches;
+ iremote.nsend_branches = nsend_branches;
+ iremote.nfetch_refs = nfetch_refs;
iremote.mirror_references = repo->mirror_references;
iremote.fetch_all_branches = repo->fetch_all_branches;
iremote.name_len = strlen(repo->name);
len += iremote.name_len;
- err = make_repo_url(&url, repo);
+ err = make_fetch_url(&fetch_url, repo);
if (err)
break;
- iremote.url_len = strlen(url);
- len += iremote.url_len;
+ iremote.fetch_url_len = strlen(fetch_url);
+ len += iremote.fetch_url_len;
+
+ err = make_send_url(&send_url, repo);
+ if (err)
+ break;
+ iremote.send_url_len = strlen(send_url);
+ len += iremote.send_url_len;
wbuf = imsg_create(ibuf, GOT_IMSG_GOTCONFIG_REMOTE, 0, 0, len);
if (wbuf == NULL) {
ibuf_free(wbuf);
break;
}
- if (imsg_add(wbuf, url, iremote.url_len) == -1) {
+ if (imsg_add(wbuf, fetch_url, iremote.fetch_url_len) == -1) {
err = got_error_from_errno(
"imsg_add GOTCONFIG_REMOTE");
ibuf_free(wbuf);
break;
}
+ if (imsg_add(wbuf, send_url, iremote.send_url_len) == -1) {
+ err = got_error_from_errno(
+ "imsg_add GOTCONFIG_REMOTE");
+ ibuf_free(wbuf);
+ break;
+ }
wbuf->fd = -1;
imsg_close(ibuf, wbuf);
if (err)
break;
- free(url);
- url = NULL;
+ free(fetch_url);
+ fetch_url = NULL;
+ free(send_url);
+ send_url = NULL;
- branch = repo->branch;
- while (branch) {
- err = send_gotconfig_str(ibuf, branch->branch_name);
- if (err)
- break;
- branch = branch->next;
+ if (repo->fetch_config && repo->fetch_config->branch) {
+ branch = repo->fetch_config->branch;
+ while (branch) {
+ err = send_gotconfig_str(ibuf,
+ branch->branch_name);
+ if (err)
+ break;
+ branch = branch->next;
+ }
+ } else {
+ branch = repo->branch;
+ while (branch) {
+ err = send_gotconfig_str(ibuf,
+ branch->branch_name);
+ if (err)
+ break;
+ branch = branch->next;
+ }
}
- ref = repo->ref;
+ if (repo->send_config && repo->send_config->branch) {
+ branch = repo->send_config->branch;
+ while (branch) {
+ err = send_gotconfig_str(ibuf,
+ branch->branch_name);
+ if (err)
+ break;
+ branch = branch->next;
+ }
+ } else {
+ branch = repo->branch;
+ while (branch) {
+ err = send_gotconfig_str(ibuf,
+ branch->branch_name);
+ if (err)
+ break;
+ branch = branch->next;
+ }
+ }
+
+ ref = repo->fetch_ref;
while (ref) {
err = send_gotconfig_str(ibuf, ref->ref_name);
if (err)
}
}
- free(url);
+ free(fetch_url);
+ free(send_url);
return err;
}
blob - 1ce83bbcfa6c33daba6da2f078860f3a41659d38
blob + 1ce499222101a45de399bd433825c767df869d91
--- libexec/got-read-gotconfig/gotconfig.h
+++ libexec/got-read-gotconfig/gotconfig.h
int mirror_references;
int fetch_all_branches;
struct node_branch *branch;
- struct node_ref *ref;
+ struct node_ref *fetch_ref;
struct fetch_config *fetch_config;
struct send_config *send_config;
};
blob - 842552aef596457405a11618bb92b1586d2d094c
blob + db321a515c3fb30904d91781a67ae7dd6d1b462c
--- libexec/got-read-gotconfig/parse.y
+++ libexec/got-read-gotconfig/parse.y
remote->branch = $2;
}
| REFERENCE ref {
- remote->ref = $2;
+ remote->fetch_ref = $2;
}
| FETCH {
static const struct got_error* error;
blob - b7603c982431e0c17ae7aeb27a58df3481304608
blob + 2c2112b0a45b7a3317cd276452aa270633f87995
--- regress/cmdline/send.sh
+++ regress/cmdline/send.sh
diff -u $testroot/stdout.expected $testroot/stdout
fi
test_done "$testroot" "$ret"
+}
+
+test_send_and_fetch_config() {
+ local testroot=`test_init send_fetch_conf`
+ local testurl=ssh://127.0.0.1/$testroot
+ local commit_id=`git_show_head $testroot/repo`
+
+ 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
+
+ got tag -r $testroot/repo -m '1.0' 1.0 >/dev/null
+ tag_id=`got ref -r $testroot/repo -l | grep "^refs/tags/1.0" \
+ | tr -d ' ' | cut -d: -f2`
+
+ cp -R $testroot/repo-clone $testroot/repo-clone2
+ got tag -r $testroot/repo-clone2 -m '2.0' 2.0 >/dev/null
+ tag_id2=`got ref -r $testroot/repo-clone2 -l | grep "^refs/tags/2.0" \
+ | tr -d ' ' | cut -d: -f2`
+
+ cat > $testroot/repo/.git/got.conf <<EOF
+remote "origin" {
+ protocol ssh
+ server 127.0.0.1
+ send {
+ repository "$testroot/repo-clone"
+ }
+ fetch {
+ repository "$testroot/repo-clone2"
+ }
}
+EOF
+ got ref -l -r $testroot/repo > $testroot/stdout
+ if [ "$ret" != "0" ]; then
+ echo "got ref command failed unexpectedly" >&2
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+ echo "HEAD: refs/heads/master" > $testroot/stdout.expected
+ echo "refs/heads/master: $commit_id" >> $testroot/stdout.expected
+ echo "refs/tags/1.0: $tag_id" >> $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
+ # fetch tag 2.0 from repo-clone2
+ got fetch -q -r $testroot/repo > $testroot/stdout
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ echo "got fetch command failed unexpectedly" >&2
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ got ref -l -r $testroot/repo > $testroot/stdout
+ if [ "$ret" != "0" ]; then
+ echo "got ref command failed unexpectedly" >&2
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ echo "HEAD: refs/heads/master" > $testroot/stdout.expected
+ echo "refs/heads/master: $commit_id" >> $testroot/stdout.expected
+ echo "refs/remotes/origin/HEAD: refs/remotes/origin/master" \
+ >> $testroot/stdout.expected
+ echo "refs/remotes/origin/master: $commit_id" \
+ >> $testroot/stdout.expected
+ echo "refs/tags/1.0: $tag_id" >> $testroot/stdout.expected
+ echo "refs/tags/2.0: $tag_id2" >> $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
+
+ # send tag 1.0 to repo-clone
+ got send -q -r $testroot/repo -t 1.0 > $testroot/stdout
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ echo "got send command failed unexpectedly" >&2
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ got ref -l -r $testroot/repo-clone > $testroot/stdout
+ if [ "$ret" != "0" ]; then
+ echo "got ref command failed unexpectedly" >&2
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ echo "HEAD: refs/heads/master" > $testroot/stdout.expected
+ echo "refs/heads/master: $commit_id" >> $testroot/stdout.expected
+ echo "refs/remotes/origin/HEAD: refs/remotes/origin/master" \
+ >> $testroot/stdout.expected
+ echo "refs/remotes/origin/master: $commit_id" \
+ >> $testroot/stdout.expected
+ echo "refs/tags/1.0: $tag_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"
+}
+
test_parseargs "$@"
run_test test_send_basic
run_test test_send_rebase_required
run_test test_send_new_branch
run_test test_send_all_branches
run_test test_send_to_empty_repo
+run_test test_send_and_fetch_config