* [PATCH 1/4] Fix prefix handling in ref iteration functions
2011-06-07 18:21 ` Jamey Sharp
@ 2011-06-07 18:21 ` Jamey Sharp
2011-06-07 18:21 ` [PATCH 2/4] Add infrastructure for ref namespaces Jamey Sharp
` (3 subsequent siblings)
4 siblings, 0 replies; 17+ messages in thread
From: Jamey Sharp @ 2011-06-07 18:21 UTC (permalink / raw)
To: Junio C Hamano
Cc: Shawn O. Pearce, Johannes Schindelin, Jeff King, Jakub Narebski,
git, Josh Triplett
From: Josh Triplett <josh@joshtriplett.org>
The do_for_each_ref iteration function accepts a prefix and a trim, and
checks for the prefix on each ref before passing in that ref; it also
supports trimming off part of the ref before passing it. However,
do_for_each_ref used trim as the length of the prefix to check, ignoring
the actual length of the prefix. Switch to using prefixcmp, checking
the entire length of the prefix string, to properly support a trim value
different than the length of the prefix.
Several callers passed a prefix of "refs/" to filter out everything
outside of refs/, but a trim of 0 to avoid trimming off the "refs/"; the
trim of 0 meant that the filter of "refs/" no longer applied. Change
these callers to pass an empty prefix instead, to avoid changing the
existing behavior. Various callers count on this lack of filtering,
such as receive-pack which uses add_extra_ref to add alternates as refs
named ".have"; adding filtering would break that, causing
t5501-fetch-push-alternates.sh to fail. That lack of filtering doesn't
currently have any other effect, since the loose ref functions can never
supply refs outside of "refs/", and packed-refs will not normally
include such refs unless manually edited.
Commit by Josh Triplett and Jamey Sharp.
Signed-off-by: Josh Triplett <josh@joshtriplett.org>
Signed-off-by: Jamey Sharp <jamey@minilop.net>
---
refs.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/refs.c b/refs.c
index e3c0511..858cf92 100644
--- a/refs.c
+++ b/refs.c
@@ -584,7 +584,7 @@ int read_ref(const char *ref, unsigned char *sha1)
static int do_one_ref(const char *base, each_ref_fn fn, int trim,
int flags, void *cb_data, struct ref_list *entry)
{
- if (strncmp(base, entry->name, trim))
+ if (prefixcmp(entry->name, base))
return 0;
if (!(flags & DO_FOR_EACH_INCLUDE_BROKEN)) {
@@ -728,12 +728,12 @@ int head_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data)
int for_each_ref(each_ref_fn fn, void *cb_data)
{
- return do_for_each_ref(NULL, "refs/", fn, 0, 0, cb_data);
+ return do_for_each_ref(NULL, "", fn, 0, 0, cb_data);
}
int for_each_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data)
{
- return do_for_each_ref(submodule, "refs/", fn, 0, 0, cb_data);
+ return do_for_each_ref(submodule, "", fn, 0, 0, cb_data);
}
int for_each_ref_in(const char *prefix, each_ref_fn fn, void *cb_data)
@@ -819,7 +819,7 @@ int for_each_glob_ref(each_ref_fn fn, const char *pattern, void *cb_data)
int for_each_rawref(each_ref_fn fn, void *cb_data)
{
- return do_for_each_ref(NULL, "refs/", fn, 0,
+ return do_for_each_ref(NULL, "", fn, 0,
DO_FOR_EACH_INCLUDE_BROKEN, cb_data);
}
--
1.7.5.3
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 2/4] Add infrastructure for ref namespaces
2011-06-07 18:21 ` Jamey Sharp
2011-06-07 18:21 ` [PATCH 1/4] Fix prefix handling in ref iteration functions Jamey Sharp
@ 2011-06-07 18:21 ` Jamey Sharp
2011-06-07 19:12 ` Bert Wesarg
2011-06-07 18:21 ` [PATCH 3/4] Support ref namespaces for remote repositories via upload-pack and receive-pack Jamey Sharp
` (2 subsequent siblings)
4 siblings, 1 reply; 17+ messages in thread
From: Jamey Sharp @ 2011-06-07 18:21 UTC (permalink / raw)
To: Junio C Hamano
Cc: Shawn O. Pearce, Johannes Schindelin, Jeff King, Jakub Narebski,
git, Josh Triplett
From: Josh Triplett <josh@joshtriplett.org>
Add support for dividing the refs of a single repository into multiple
namespaces, each of which can have its own branches, tags, and HEAD.
Git can expose each namespace as an independent repository to pull from
and push to, while sharing the object store, and exposing all the refs
to operations such as git-gc.
Storing multiple repositories as namespaces of a single repository
avoids storing duplicate copies of the same objects, such as when
storing multiple branches of the same source. The alternates mechanism
provides similar support for avoiding duplicates, but alternates do not
prevent duplication between new objects added to the repositories
without ongoing maintenance, while namespaces do.
To specify a namespace, set the GIT_NAMESPACE environment variable to
the namespace. For each ref namespace, git stores the corresponding
refs in a directory under refs/namespaces/. For example,
GIT_NAMESPACE=foo will store refs under refs/namespaces/foo/. You can
also specify namespaces via the --namespace option to git.
Note that namespaces which include a / will expand to a hierarchy of
namespaces; for example, GIT_NAMESPACE=foo/bar will store refs under
refs/namespaces/foo/refs/namespaces/bar/. This makes paths in
GIT_NAMESPACE behave hierarchically, so that cloning with
GIT_NAMESPACE=foo/bar produces the same result as cloning with
GIT_NAMESPACE=foo and cloning from that repo with GIT_NAMESPACE=bar. It
also avoids ambiguity with strange namespace paths such as
foo/refs/heads/, which could otherwise generate directory/file conflicts
within the refs directory.
This adds the infrastructure for ref namespaces: handling the
GIT_NAMESPACE environment variable and --namespace option, and iterating
over refs in a namespace. Subsequent commits use this infrastructure to
implement the user-visible support for ref namespaces.
Commit by Josh Triplett and Jamey Sharp.
Signed-off-by: Josh Triplett <josh@joshtriplett.org>
Signed-off-by: Jamey Sharp <jamey@minilop.net>
---
cache.h | 3 ++
contrib/completion/git-completion.bash | 1 +
environment.c | 41 ++++++++++++++++++++++++++++++++
git.c | 18 ++++++++++++-
refs.c | 25 +++++++++++++++++++
refs.h | 3 ++
6 files changed, 89 insertions(+), 2 deletions(-)
diff --git a/cache.h b/cache.h
index e11cf6a..b256a94 100644
--- a/cache.h
+++ b/cache.h
@@ -379,6 +379,7 @@ static inline enum object_type object_type(unsigned int mode)
}
#define GIT_DIR_ENVIRONMENT "GIT_DIR"
+#define GIT_NAMESPACE_ENVIRONMENT "GIT_NAMESPACE"
#define GIT_WORK_TREE_ENVIRONMENT "GIT_WORK_TREE"
#define DEFAULT_GIT_DIR_ENVIRONMENT ".git"
#define DB_ENVIRONMENT "GIT_OBJECT_DIRECTORY"
@@ -419,6 +420,8 @@ extern char *get_object_directory(void);
extern char *get_index_file(void);
extern char *get_graft_file(void);
extern int set_git_dir(const char *path);
+extern const char *get_git_namespace(void);
+extern const char *strip_namespace(const char *namespaced_ref);
extern const char *get_git_work_tree(void);
extern const char *read_gitfile_gently(const char *path);
extern void set_git_work_tree(const char *tree);
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index b36290f..b10a1ec 100755
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -2640,6 +2640,7 @@ _git ()
--exec-path
--html-path
--work-tree=
+ --namespace=
--help
"
;;
diff --git a/environment.c b/environment.c
index 94d58fd..aad274b 100644
--- a/environment.c
+++ b/environment.c
@@ -8,6 +8,7 @@
* are.
*/
#include "cache.h"
+#include "refs.h"
char git_default_email[MAX_GITNAME];
char git_default_name[MAX_GITNAME];
@@ -65,6 +66,9 @@ int core_preload_index = 0;
char *git_work_tree_cfg;
static char *work_tree;
+static const char *namespace;
+static size_t namespace_len;
+
static const char *git_dir;
static char *git_object_dir, *git_index_file, *git_graft_file;
@@ -86,6 +90,27 @@ const char * const local_repo_env[LOCAL_REPO_ENV_SIZE + 1] = {
NULL
};
+static char *expand_namespace(const char *raw_namespace)
+{
+ struct strbuf buf = STRBUF_INIT;
+ struct strbuf **components, **c;
+
+ if (!raw_namespace || !*raw_namespace)
+ return xstrdup("");
+
+ strbuf_addstr(&buf, raw_namespace);
+ components = strbuf_split(&buf, '/');
+ strbuf_reset(&buf);
+ for (c = components; *c; c++)
+ if (strcmp((*c)->buf, "/") != 0)
+ strbuf_addf(&buf, "refs/namespaces/%s", (*c)->buf);
+ strbuf_list_free(components);
+ if (check_ref_format(buf.buf) != CHECK_REF_FORMAT_OK)
+ die("bad git namespace path \"%s\"", raw_namespace);
+ strbuf_addch(&buf, '/');
+ return strbuf_detach(&buf, NULL);
+}
+
static void setup_git_env(void)
{
git_dir = getenv(GIT_DIR_ENVIRONMENT);
@@ -111,6 +136,8 @@ static void setup_git_env(void)
git_graft_file = git_pathdup("info/grafts");
if (getenv(NO_REPLACE_OBJECTS_ENVIRONMENT))
read_replace_refs = 0;
+ namespace = expand_namespace(getenv(GIT_NAMESPACE_ENVIRONMENT));
+ namespace_len = strlen(namespace);
}
int is_bare_repository(void)
@@ -131,6 +158,20 @@ const char *get_git_dir(void)
return git_dir;
}
+const char *get_git_namespace(void)
+{
+ if (!namespace)
+ setup_git_env();
+ return namespace;
+}
+
+const char *strip_namespace(const char *namespaced_ref)
+{
+ if (prefixcmp(namespaced_ref, get_git_namespace()) != 0)
+ return NULL;
+ return namespaced_ref + namespace_len;
+}
+
static int git_work_tree_initialized;
/*
diff --git a/git.c b/git.c
index 89721d4..98cbf7b 100644
--- a/git.c
+++ b/git.c
@@ -7,8 +7,8 @@
const char git_usage_string[] =
"git [--version] [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]\n"
- " [-p|--paginate|--no-pager] [--no-replace-objects]\n"
- " [--bare] [--git-dir=<path>] [--work-tree=<path>]\n"
+ " [-p|--paginate|--no-pager] [--no-replace-objects] [--bare]\n"
+ " [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]\n"
" [-c name=value] [--help]\n"
" <command> [<args>]";
@@ -126,6 +126,20 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)
setenv(GIT_DIR_ENVIRONMENT, cmd + 10, 1);
if (envchanged)
*envchanged = 1;
+ } else if (!strcmp(cmd, "--namespace")) {
+ if (*argc < 2) {
+ fprintf(stderr, "No directory given for --namespace.\n" );
+ usage(git_usage_string);
+ }
+ setenv(GIT_NAMESPACE_ENVIRONMENT, (*argv)[1], 1);
+ if (envchanged)
+ *envchanged = 1;
+ (*argv)++;
+ (*argc)--;
+ } else if (!prefixcmp(cmd, "--namespace=")) {
+ setenv(GIT_NAMESPACE_ENVIRONMENT, cmd + 12, 1);
+ if (envchanged)
+ *envchanged = 1;
} else if (!strcmp(cmd, "--work-tree")) {
if (*argc < 2) {
fprintf(stderr, "No directory given for --work-tree.\n" );
diff --git a/refs.c b/refs.c
index 858cf92..e83bbf8 100644
--- a/refs.c
+++ b/refs.c
@@ -782,6 +782,31 @@ int for_each_replace_ref(each_ref_fn fn, void *cb_data)
return do_for_each_ref(NULL, "refs/replace/", fn, 13, 0, cb_data);
}
+int head_ref_namespaced(each_ref_fn fn, void *cb_data)
+{
+ struct strbuf buf = STRBUF_INIT;
+ int ret = 0;
+ unsigned char sha1[20];
+ int flag;
+
+ strbuf_addf(&buf, "%sHEAD", get_git_namespace());
+ if (resolve_ref(buf.buf, sha1, 1, &flag))
+ ret = fn(buf.buf, sha1, flag, cb_data);
+ strbuf_release(&buf);
+
+ return ret;
+}
+
+int for_each_namespaced_ref(each_ref_fn fn, void *cb_data)
+{
+ struct strbuf buf = STRBUF_INIT;
+ int ret;
+ strbuf_addf(&buf, "%srefs/", get_git_namespace());
+ ret = do_for_each_ref(NULL, buf.buf, fn, 0, 0, cb_data);
+ strbuf_release(&buf);
+ return ret;
+}
+
int for_each_glob_ref_in(each_ref_fn fn, const char *pattern,
const char *prefix, void *cb_data)
{
diff --git a/refs.h b/refs.h
index 5e7a9a5..9a5c9e0 100644
--- a/refs.h
+++ b/refs.h
@@ -36,6 +36,9 @@ extern int for_each_tag_ref_submodule(const char *submodule, each_ref_fn fn, voi
extern int for_each_branch_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data);
extern int for_each_remote_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data);
+extern int head_ref_namespaced(each_ref_fn fn, void *cb_data);
+extern int for_each_namespaced_ref(each_ref_fn fn, void *cb_data);
+
static inline const char *has_glob_specials(const char *pattern)
{
return strpbrk(pattern, "?*[");
--
1.7.5.3
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH 2/4] Add infrastructure for ref namespaces
2011-06-07 18:21 ` [PATCH 2/4] Add infrastructure for ref namespaces Jamey Sharp
@ 2011-06-07 19:12 ` Bert Wesarg
2011-06-07 22:25 ` Josh Triplett
0 siblings, 1 reply; 17+ messages in thread
From: Bert Wesarg @ 2011-06-07 19:12 UTC (permalink / raw)
To: Jamey Sharp
Cc: Junio C Hamano, Shawn O. Pearce, Johannes Schindelin, Jeff King,
Jakub Narebski, git, Josh Triplett
On Tue, Jun 7, 2011 at 20:21, Jamey Sharp <jamey@minilop.net> wrote:
> diff --git a/git.c b/git.c
> index 89721d4..98cbf7b 100644
> --- a/git.c
> +++ b/git.c
> @@ -126,6 +126,20 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)
> setenv(GIT_DIR_ENVIRONMENT, cmd + 10, 1);
> if (envchanged)
> *envchanged = 1;
> + } else if (!strcmp(cmd, "--namespace")) {
> + if (*argc < 2) {
> + fprintf(stderr, "No directory given for --namespace.\n" );
This 'directory' is probably misnamed here.
Bert
> + usage(git_usage_string);
> + }
> + setenv(GIT_NAMESPACE_ENVIRONMENT, (*argv)[1], 1);
> + if (envchanged)
> + *envchanged = 1;
> + (*argv)++;
> + (*argc)--;
> + } else if (!prefixcmp(cmd, "--namespace=")) {
> + setenv(GIT_NAMESPACE_ENVIRONMENT, cmd + 12, 1);
> + if (envchanged)
> + *envchanged = 1;
> } else if (!strcmp(cmd, "--work-tree")) {
> if (*argc < 2) {
> fprintf(stderr, "No directory given for --work-tree.\n" );
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 2/4] Add infrastructure for ref namespaces
2011-06-07 19:12 ` Bert Wesarg
@ 2011-06-07 22:25 ` Josh Triplett
0 siblings, 0 replies; 17+ messages in thread
From: Josh Triplett @ 2011-06-07 22:25 UTC (permalink / raw)
To: Bert Wesarg
Cc: Jamey Sharp, Junio C Hamano, Shawn O. Pearce, Johannes Schindelin,
Jeff King, Jakub Narebski, git
On Tue, Jun 07, 2011 at 09:12:09PM +0200, Bert Wesarg wrote:
> On Tue, Jun 7, 2011 at 20:21, Jamey Sharp <jamey@minilop.net> wrote:
> > diff --git a/git.c b/git.c
> > index 89721d4..98cbf7b 100644
> > --- a/git.c
> > +++ b/git.c
> > @@ -126,6 +126,20 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)
> > setenv(GIT_DIR_ENVIRONMENT, cmd + 10, 1);
> > if (envchanged)
> > *envchanged = 1;
> > + } else if (!strcmp(cmd, "--namespace")) {
> > + if (*argc < 2) {
> > + fprintf(stderr, "No directory given for --namespace.\n" );
>
> This 'directory' is probably misnamed here.
Thanks, will fix.
- Josh Triplett
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH 3/4] Support ref namespaces for remote repositories via upload-pack and receive-pack
2011-06-07 18:21 ` Jamey Sharp
2011-06-07 18:21 ` [PATCH 1/4] Fix prefix handling in ref iteration functions Jamey Sharp
2011-06-07 18:21 ` [PATCH 2/4] Add infrastructure for ref namespaces Jamey Sharp
@ 2011-06-07 18:21 ` Jamey Sharp
2011-06-07 18:21 ` [PATCH 4/4] Add documentation for ref namespaces Jamey Sharp
2011-06-07 18:59 ` What's cooking in git.git (Jun 2011, #01; Sun, 5) Junio C Hamano
4 siblings, 0 replies; 17+ messages in thread
From: Jamey Sharp @ 2011-06-07 18:21 UTC (permalink / raw)
To: Junio C Hamano
Cc: Shawn O. Pearce, Johannes Schindelin, Jeff King, Jakub Narebski,
git, Josh Triplett
From: Josh Triplett <josh@joshtriplett.org>
Change upload-pack and receive-pack to use the namespace-prefixed refs
when working with the repository, and use the unprefixed refs when
talking to the client, maintaining the masquerade. This allows
clone, pull, fetch, and push to work with a suitably configured
GIT_NAMESPACE.
With appropriate configuration, this also allows http-backend to expose
namespaces as multiple repositories with different paths. This only
requires setting GIT_NAMESPACE, which http-backend passes through to
upload-pack and receive-pack.
Commit by Josh Triplett and Jamey Sharp.
Signed-off-by: Josh Triplett <josh@joshtriplett.org>
Signed-off-by: Jamey Sharp <jamey@minilop.net>
---
builtin/receive-pack.c | 34 ++++++++++++++++++++++++++++------
upload-pack.c | 15 ++++++++-------
2 files changed, 36 insertions(+), 13 deletions(-)
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index e1a687a..54dd5d4 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -120,9 +120,14 @@ static int show_ref(const char *path, const unsigned char *sha1, int flag, void
return 0;
}
+static int show_ref_cb(const char *path, const unsigned char *sha1, int flag, void *cb_data)
+{
+ return show_ref(strip_namespace(path), sha1, flag, cb_data);
+}
+
static void write_head_info(void)
{
- for_each_ref(show_ref, NULL);
+ for_each_namespaced_ref(show_ref_cb, NULL);
if (!sent_capabilities)
show_ref("capabilities^{}", null_sha1, 0, NULL);
@@ -333,6 +338,8 @@ static void refuse_unconfigured_deny_delete_current(void)
static const char *update(struct command *cmd)
{
const char *name = cmd->ref_name;
+ struct strbuf namespaced_name_buf = STRBUF_INIT;
+ const char *namespaced_name;
unsigned char *old_sha1 = cmd->old_sha1;
unsigned char *new_sha1 = cmd->new_sha1;
struct ref_lock *lock;
@@ -343,7 +350,10 @@ static const char *update(struct command *cmd)
return "funny refname";
}
- if (is_ref_checked_out(name)) {
+ strbuf_addf(&namespaced_name_buf, "%s%s", get_git_namespace(), name);
+ namespaced_name = strbuf_detach(&namespaced_name_buf, NULL);
+
+ if (is_ref_checked_out(namespaced_name)) {
switch (deny_current_branch) {
case DENY_IGNORE:
break;
@@ -371,7 +381,7 @@ static const char *update(struct command *cmd)
return "deletion prohibited";
}
- if (!strcmp(name, head_name)) {
+ if (!strcmp(namespaced_name, head_name)) {
switch (deny_delete_current) {
case DENY_IGNORE:
break;
@@ -427,14 +437,14 @@ static const char *update(struct command *cmd)
rp_warning("Allowing deletion of corrupt ref.");
old_sha1 = NULL;
}
- if (delete_ref(name, old_sha1, 0)) {
+ if (delete_ref(namespaced_name, old_sha1, 0)) {
rp_error("failed to delete %s", name);
return "failed to delete";
}
return NULL; /* good */
}
else {
- lock = lock_any_ref_for_update(name, old_sha1, 0);
+ lock = lock_any_ref_for_update(namespaced_name, old_sha1, 0);
if (!lock) {
rp_error("failed to lock %s", name);
return "failed to lock";
@@ -491,17 +501,29 @@ static void run_update_post_hook(struct command *commands)
static void check_aliased_update(struct command *cmd, struct string_list *list)
{
+ struct strbuf buf = STRBUF_INIT;
+ const char *dst_name;
struct string_list_item *item;
struct command *dst_cmd;
unsigned char sha1[20];
char cmd_oldh[41], cmd_newh[41], dst_oldh[41], dst_newh[41];
int flag;
- const char *dst_name = resolve_ref(cmd->ref_name, sha1, 0, &flag);
+ strbuf_addf(&buf, "%s%s", get_git_namespace(), cmd->ref_name);
+ dst_name = resolve_ref(buf.buf, sha1, 0, &flag);
+ strbuf_release(&buf);
if (!(flag & REF_ISSYMREF))
return;
+ dst_name = strip_namespace(dst_name);
+ if (!dst_name) {
+ rp_error("refusing update to broken symref '%s'", cmd->ref_name);
+ cmd->skip_update = 1;
+ cmd->error_string = "broken symref";
+ return;
+ }
+
if ((item = string_list_lookup(list, dst_name)) == NULL)
return;
diff --git a/upload-pack.c b/upload-pack.c
index ce5cbbe..267e5b1 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -641,16 +641,17 @@ static int send_ref(const char *refname, const unsigned char *sha1, int flag, vo
" side-band-64k ofs-delta shallow no-progress"
" include-tag multi_ack_detailed";
struct object *o = parse_object(sha1);
+ const char *refname_nons = strip_namespace(refname);
if (!o)
die("git upload-pack: cannot find object %s:", sha1_to_hex(sha1));
if (capabilities)
- packet_write(1, "%s %s%c%s%s\n", sha1_to_hex(sha1), refname,
+ packet_write(1, "%s %s%c%s%s\n", sha1_to_hex(sha1), refname_nons,
0, capabilities,
stateless_rpc ? " no-done" : "");
else
- packet_write(1, "%s %s\n", sha1_to_hex(sha1), refname);
+ packet_write(1, "%s %s\n", sha1_to_hex(sha1), refname_nons);
capabilities = NULL;
if (!(o->flags & OUR_REF)) {
o->flags |= OUR_REF;
@@ -659,7 +660,7 @@ static int send_ref(const char *refname, const unsigned char *sha1, int flag, vo
if (o->type == OBJ_TAG) {
o = deref_tag(o, refname, 0);
if (o)
- packet_write(1, "%s %s^{}\n", sha1_to_hex(o->sha1), refname);
+ packet_write(1, "%s %s^{}\n", sha1_to_hex(o->sha1), refname_nons);
}
return 0;
}
@@ -680,12 +681,12 @@ static void upload_pack(void)
{
if (advertise_refs || !stateless_rpc) {
reset_timeout();
- head_ref(send_ref, NULL);
- for_each_ref(send_ref, NULL);
+ head_ref_namespaced(send_ref, NULL);
+ for_each_namespaced_ref(send_ref, NULL);
packet_flush(1);
} else {
- head_ref(mark_our_ref, NULL);
- for_each_ref(mark_our_ref, NULL);
+ head_ref_namespaced(mark_our_ref, NULL);
+ for_each_namespaced_ref(mark_our_ref, NULL);
}
if (advertise_refs)
return;
--
1.7.5.3
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 4/4] Add documentation for ref namespaces
2011-06-07 18:21 ` Jamey Sharp
` (2 preceding siblings ...)
2011-06-07 18:21 ` [PATCH 3/4] Support ref namespaces for remote repositories via upload-pack and receive-pack Jamey Sharp
@ 2011-06-07 18:21 ` Jamey Sharp
2011-08-23 10:38 ` Ævar Arnfjörð Bjarmason
2011-06-07 18:59 ` What's cooking in git.git (Jun 2011, #01; Sun, 5) Junio C Hamano
4 siblings, 1 reply; 17+ messages in thread
From: Jamey Sharp @ 2011-06-07 18:21 UTC (permalink / raw)
To: Junio C Hamano
Cc: Shawn O. Pearce, Johannes Schindelin, Jeff King, Jakub Narebski,
git, Josh Triplett
From: Josh Triplett <josh@joshtriplett.org>
Document the namespace mechanism in a new gitnamespaces(7) page.
Reference it from receive-pack and upload-pack.
Document the new --namespace option and GIT_NAMESPACE environment
variable in git(1), and reference gitnamespaces(7).
Add a sample Apache configuration to http-backend(1) to support
namespaced repositories, and reference gitnamespaces(7).
Commit by Josh Triplett and Jamey Sharp.
Signed-off-by: Josh Triplett <josh@joshtriplett.org>
Signed-off-by: Jamey Sharp <jamey@minilop.net>
---
Documentation/Makefile | 2 +-
Documentation/git-http-backend.txt | 8 +++
Documentation/git-receive-pack.txt | 2 +-
Documentation/git-upload-pack.txt | 4 ++
Documentation/git.txt | 13 +++++-
Documentation/gitnamespaces.txt | 75 ++++++++++++++++++++++++++++++++
contrib/completion/git-completion.bash | 2 +-
7 files changed, 101 insertions(+), 5 deletions(-)
create mode 100644 Documentation/gitnamespaces.txt
diff --git a/Documentation/Makefile b/Documentation/Makefile
index 36989b7..2004fbe 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -6,7 +6,7 @@ MAN5_TXT=gitattributes.txt gitignore.txt gitmodules.txt githooks.txt \
gitrepository-layout.txt
MAN7_TXT=gitcli.txt gittutorial.txt gittutorial-2.txt \
gitcvs-migration.txt gitcore-tutorial.txt gitglossary.txt \
- gitdiffcore.txt gitrevisions.txt gitworkflows.txt
+ gitdiffcore.txt gitnamespaces.txt gitrevisions.txt gitworkflows.txt
MAN_TXT = $(MAN1_TXT) $(MAN5_TXT) $(MAN7_TXT)
MAN_XML=$(patsubst %.txt,%.xml,$(MAN_TXT))
diff --git a/Documentation/git-http-backend.txt b/Documentation/git-http-backend.txt
index 277d9e1..f4e0741 100644
--- a/Documentation/git-http-backend.txt
+++ b/Documentation/git-http-backend.txt
@@ -119,6 +119,14 @@ ScriptAliasMatch \
ScriptAlias /git/ /var/www/cgi-bin/gitweb.cgi/
----------------------------------------------------------------
++
+To serve multiple repositories from different linkgit:gitnamespaces[7] in a
+single repository:
++
+----------------------------------------------------------------
+SetEnvIf Request_URI "^/git/([^/]*)" GIT_NAMESPACE=$1
+ScriptAliasMatch ^/git/[^/]*(.*) /usr/libexec/git-core/git-http-backend/storage.git$1
+----------------------------------------------------------------
Accelerated static Apache 2.x::
Similar to the above, but Apache can be used to return static
diff --git a/Documentation/git-receive-pack.txt b/Documentation/git-receive-pack.txt
index f34e0ae..3534ba0 100644
--- a/Documentation/git-receive-pack.txt
+++ b/Documentation/git-receive-pack.txt
@@ -149,7 +149,7 @@ if the repository is packed and is served via a dumb transport.
SEE ALSO
--------
-linkgit:git-send-pack[1]
+linkgit:git-send-pack[1], linkgit:gitnamespaces[7]
GIT
---
diff --git a/Documentation/git-upload-pack.txt b/Documentation/git-upload-pack.txt
index 4c0ca9d..61a9a04 100644
--- a/Documentation/git-upload-pack.txt
+++ b/Documentation/git-upload-pack.txt
@@ -33,6 +33,10 @@ OPTIONS
<directory>::
The repository to sync from.
+SEE ALSO
+--------
+linkgit:gitnamespaces[7]
+
GIT
---
Part of the linkgit:git[1] suite
diff --git a/Documentation/git.txt b/Documentation/git.txt
index 5c45446..4cbf741 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -10,8 +10,8 @@ SYNOPSIS
--------
[verse]
'git' [--version] [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
- [-p|--paginate|--no-pager] [--no-replace-objects]
- [--bare] [--git-dir=<path>] [--work-tree=<path>]
+ [-p|--paginate|--no-pager] [--no-replace-objects] [--bare]
+ [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]
[-c <name>=<value>]
[--help] <command> [<args>]
@@ -325,6 +325,11 @@ help ...`.
variable (see core.worktree in linkgit:git-config[1] for a
more detailed discussion).
+--namespace=<path>::
+ Set the git namespace. See linkgit:gitnamespaces[7] for more
+ details. Equivalent to setting the `GIT_NAMESPACE` environment
+ variable.
+
--bare::
Treat the repository as a bare repository. If GIT_DIR
environment is not set, it is set to the current working
@@ -589,6 +594,10 @@ git so take care if using Cogito etc.
This can also be controlled by the '--work-tree' command line
option and the core.worktree configuration variable.
+'GIT_NAMESPACE'::
+ Set the git namespace; see linkgit:gitnamespaces[7] for details.
+ The '--namespace' command-line option also sets this value.
+
'GIT_CEILING_DIRECTORIES'::
This should be a colon-separated list of absolute paths.
If set, it is a list of directories that git should not chdir
diff --git a/Documentation/gitnamespaces.txt b/Documentation/gitnamespaces.txt
new file mode 100644
index 0000000..ed8924e
--- /dev/null
+++ b/Documentation/gitnamespaces.txt
@@ -0,0 +1,75 @@
+gitnamespaces(7)
+================
+
+NAME
+----
+gitnamespaces - Git namespaces
+
+DESCRIPTION
+-----------
+
+Git supports dividing the refs of a single repository into multiple
+namespaces, each of which has its own branches, tags, and HEAD. Git can
+expose each namespace as an independent repository to pull from and push
+to, while sharing the object store, and exposing all the refs to
+operations such as linkgit:git-gc[1].
+
+Storing multiple repositories as namespaces of a single repository
+avoids storing duplicate copies of the same objects, such as when
+storing multiple branches of the same source. The alternates mechanism
+provides similar support for avoiding duplicates, but alternates do not
+prevent duplication between new objects added to the repositories
+without ongoing maintenance, while namespaces do.
+
+To specify a namespace, set the `GIT_NAMESPACE` environment variable to
+the namespace. For each ref namespace, git stores the corresponding
+refs in a directory under `refs/namespaces/`. For example,
+`GIT_NAMESPACE=foo` will store refs under `refs/namespaces/foo/`. You
+can also specify namespaces via the `--namespace` option to
+linkgit:git[1].
+
+Note that namespaces which include a `/` will expand to a hierarchy of
+namespaces; for example, `GIT_NAMESPACE=foo/bar` will store refs under
+`refs/namespaces/foo/refs/namespaces/bar/`. This makes paths in
+`GIT_NAMESPACE` behave hierarchically, so that cloning with
+`GIT_NAMESPACE=foo/bar` produces the same result as cloning with
+`GIT_NAMESPACE=foo` and cloning from that repo with `GIT_NAMESPACE=bar`. It
+also avoids ambiguity with strange namespace paths such as `foo/refs/heads/`,
+which could otherwise generate directory/file conflicts within the `refs`
+directory.
+
+linkgit:git-upload-pack[1] and linkgit:git-receive-pack[1] rewrite the
+names of refs as specified by `GIT_NAMESPACE`. git-upload-pack and
+git-receive-pack will ignore all references outside the specified
+namespace.
+
+The smart HTTP server, linkgit:git-http-backend[1], will pass
+GIT_NAMESPACE through to the backend programs; see
+linkgit:git-http-backend[1] for sample configuration to expose
+repository namespaces as repositories.
+
+For a simple local test, you can use linkgit:git-remote-ext[1]:
+
+----------
+git clone ext::'git --namespace=foo %s /tmp/prefixed.git'
+----------
+
+SECURITY
+--------
+
+Anyone with access to any namespace within a repository can potentially
+access objects from any other namespace stored in the same repository.
+You can't directly say "give me object ABCD" if you don't have a ref to
+it, but you can do some other sneaky things like:
+
+. Claiming to push ABCD, at which point the server will optimize out the
+ need for you to actually send it. Now you have a ref to ABCD and can
+ fetch it (claiming not to have it, of course).
+
+. Requesting other refs, claiming that you have ABCD, at which point the
+ server may generate deltas against ABCD.
+
+None of this causes a problem if you only host public repositories, or
+if everyone who may read one namespace may also read everything in every
+other namespace (for instance, if everyone in an organization has read
+permission to every repository).
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index b10a1ec..ec1c986 100755
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -1469,7 +1469,7 @@ _git_help ()
__gitcomp "$__git_all_commands $(__git_aliases)
attributes cli core-tutorial cvs-migration
diffcore gitk glossary hooks ignore modules
- repository-layout tutorial tutorial-2
+ namespaces repository-layout tutorial tutorial-2
workflows
"
}
--
1.7.5.3
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH 4/4] Add documentation for ref namespaces
2011-06-07 18:21 ` [PATCH 4/4] Add documentation for ref namespaces Jamey Sharp
@ 2011-08-23 10:38 ` Ævar Arnfjörð Bjarmason
2011-08-23 17:19 ` Junio C Hamano
2011-09-16 0:22 ` Re* " Junio C Hamano
0 siblings, 2 replies; 17+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2011-08-23 10:38 UTC (permalink / raw)
To: Jamey Sharp
Cc: Junio C Hamano, Shawn O. Pearce, Johannes Schindelin, Jeff King,
Jakub Narebski, git, Josh Triplett
On Tue, Jun 7, 2011 at 20:21, Jamey Sharp <jamey@minilop.net> wrote:
> Document the namespace mechanism in a new gitnamespaces(7) page.
> Reference it from receive-pack and upload-pack.
This breaks the build on older asciidoc versions, the fix is to do
what I did in f5008f56d5aba06598e1c6272f4f55b4ee4bb016.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 4/4] Add documentation for ref namespaces
2011-08-23 10:38 ` Ævar Arnfjörð Bjarmason
@ 2011-08-23 17:19 ` Junio C Hamano
2011-08-24 12:30 ` Ævar Arnfjörð Bjarmason
2011-09-16 0:22 ` Re* " Junio C Hamano
1 sibling, 1 reply; 17+ messages in thread
From: Junio C Hamano @ 2011-08-23 17:19 UTC (permalink / raw)
To: Ævar Arnfjörð Bjarmason
Cc: Jamey Sharp, Junio C Hamano, Shawn O. Pearce, Johannes Schindelin,
Jeff King, Jakub Narebski, git, Josh Triplett
Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:
> On Tue, Jun 7, 2011 at 20:21, Jamey Sharp <jamey@minilop.net> wrote:
>
>> Document the namespace mechanism in a new gitnamespaces(7) page.
>> Reference it from receive-pack and upload-pack.
>
> This breaks the build on older asciidoc versions, the fix is to do
> what I did in f5008f56d5aba06598e1c6272f4f55b4ee4bb016.
Thanks for a sharp-eye, even though I would have appreciated it even more
if you spotted it while the series was still in 'next'.
Like this?
Documentation/gitnamespaces.txt | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/Documentation/gitnamespaces.txt b/Documentation/gitnamespaces.txt
index ed8924e..6e03946 100644
--- a/Documentation/gitnamespaces.txt
+++ b/Documentation/gitnamespaces.txt
@@ -5,6 +5,11 @@ NAME
----
gitnamespaces - Git namespaces
+SYNOPSIS
+--------
+None (this section is to only please older version of AsciiDoc)
+
+
DESCRIPTION
-----------
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH 4/4] Add documentation for ref namespaces
2011-08-23 17:19 ` Junio C Hamano
@ 2011-08-24 12:30 ` Ævar Arnfjörð Bjarmason
0 siblings, 0 replies; 17+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2011-08-24 12:30 UTC (permalink / raw)
To: Junio C Hamano
Cc: Jamey Sharp, Shawn O. Pearce, Johannes Schindelin, Jeff King,
Jakub Narebski, git, Josh Triplett
On Tue, Aug 23, 2011 at 19:19, Junio C Hamano <gitster@pobox.com> wrote:
> Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:
>
>> On Tue, Jun 7, 2011 at 20:21, Jamey Sharp <jamey@minilop.net> wrote:
>>
>>> Document the namespace mechanism in a new gitnamespaces(7) page.
>>> Reference it from receive-pack and upload-pack.
>>
>> This breaks the build on older asciidoc versions, the fix is to do
>> what I did in f5008f56d5aba06598e1c6272f4f55b4ee4bb016.
>
> Thanks for a sharp-eye, even though I would have appreciated it even more
> if you spotted it while the series was still in 'next'.
That should work. And I very rarely compile things on these old boxes
so I usually don't spot them until they hit master. Sorry.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re* [PATCH 4/4] Add documentation for ref namespaces
2011-08-23 10:38 ` Ævar Arnfjörð Bjarmason
2011-08-23 17:19 ` Junio C Hamano
@ 2011-09-16 0:22 ` Junio C Hamano
2011-09-16 3:40 ` Jamey Sharp
1 sibling, 1 reply; 17+ messages in thread
From: Junio C Hamano @ 2011-09-16 0:22 UTC (permalink / raw)
To: Jamey Sharp
Cc: Ævar Arnfjörð Bjarmason, Shawn O. Pearce,
Johannes Schindelin, Jeff King, Jakub Narebski, git,
Josh Triplett
Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:
> On Tue, Jun 7, 2011 at 20:21, Jamey Sharp <jamey@minilop.net> wrote:
>
>> Document the namespace mechanism in a new gitnamespaces(7) page.
>> Reference it from receive-pack and upload-pack.
>
> This breaks the build on older asciidoc versions, the fix is to do
> what I did in f5008f56d5aba06598e1c6272f4f55b4ee4bb016.
Earlier I sent out a tongue-in-cheek "like this" that had a completely
bogus SYNOPSIS section that is unusable in a released version of Git,
hoping that somebody who _care_ more about the feature that the page
describes would give us a better wording, but unfortunately it never
happened.
So here is a more realistic replacement, so that we won't have to suffer
by complaints from people with older AsciiDoc saying "the release does not
build". If we were to include this in 1.7.7 final, we now need to make
sure we won't to have to hear from people with newer AsciiDoc saying "why
do we have nonsense in SYNOPSIS section", so your help is needed here.
I explicitly avoided saying:
[verse]
export GIT_NAMESPACE=<namespace>
as nothing other than the selected transports seems to pay attention to
this environment variable.
-- >8 --
Subject: [PATCH] Documentation/gitnamespaces.txt: cater to older asciidoc
Older asciidoc (e.g. 8.2.5 on Centos 5.5) is unhappy if a manpage does not
have a SYNOPSIS section. Show a sample (and a possibly bogus) command line
of running two commands that pay attention to this environment variable
with a customized value.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
Documentation/gitnamespaces.txt | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/Documentation/gitnamespaces.txt b/Documentation/gitnamespaces.txt
index ed8924e..c6713cf 100644
--- a/Documentation/gitnamespaces.txt
+++ b/Documentation/gitnamespaces.txt
@@ -5,6 +5,13 @@ NAME
----
gitnamespaces - Git namespaces
+SYNOPSIS
+--------
+[verse]
+GIT_NAMESPACE=<namespace> 'git upload-pack'
+GIT_NAMESPACE=<namespace> 'git receive-pack'
+
+
DESCRIPTION
-----------
--
1.7.7.rc1.3.g559357
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: Re* [PATCH 4/4] Add documentation for ref namespaces
2011-09-16 0:22 ` Re* " Junio C Hamano
@ 2011-09-16 3:40 ` Jamey Sharp
2011-09-16 16:20 ` Junio C Hamano
0 siblings, 1 reply; 17+ messages in thread
From: Jamey Sharp @ 2011-09-16 3:40 UTC (permalink / raw)
To: Junio C Hamano
Cc: Ævar Arnfjörð Bjarmason, Shawn O. Pearce,
Johannes Schindelin, Jeff King, Jakub Narebski, git,
Josh Triplett
[-- Attachment #1: Type: text/plain, Size: 3202 bytes --]
On Thu, Sep 15, 2011 at 05:22:29PM -0700, Junio C Hamano wrote:
> Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:
>
> > On Tue, Jun 7, 2011 at 20:21, Jamey Sharp <jamey@minilop.net> wrote:
> >
> >> Document the namespace mechanism in a new gitnamespaces(7) page.
> >> Reference it from receive-pack and upload-pack.
> >
> > This breaks the build on older asciidoc versions, the fix is to do
> > what I did in f5008f56d5aba06598e1c6272f4f55b4ee4bb016.
>
> Earlier I sent out a tongue-in-cheek "like this" that had a completely
> bogus SYNOPSIS section that is unusable in a released version of Git,
> hoping that somebody who _care_ more about the feature that the page
> describes would give us a better wording, but unfortunately it never
> happened.
I'm afraid your wit was too subtle for me, as I believed your proposal
was serious and would be applied as-is. I assumed AsciiDoc was going to
magically omit the bogus synopsis, somehow. Perhaps it should detect
when people are making fun of it, and ignore them then?
Your rationale for giving a more specific synopsis is sound, although:
1) git http-backend also supports the environment variable because it's
inherited by the underlying upload-pack and receive-pack; and 2) the
environment variable is an alternative to a general git command-line
option. How much detail do you want in a synopsis?
Assuming that you're happy with this level of detail, and that the
AsciiDoc syntax is correct (I'm not familiar enough with it), I'm happy
with the patch you propose---
Reviewed-by: Jamey Sharp <jamey@minilop.net>
> So here is a more realistic replacement, so that we won't have to suffer
> by complaints from people with older AsciiDoc saying "the release does not
> build". If we were to include this in 1.7.7 final, we now need to make
> sure we won't to have to hear from people with newer AsciiDoc saying "why
> do we have nonsense in SYNOPSIS section", so your help is needed here.
>
> I explicitly avoided saying:
>
> [verse]
> export GIT_NAMESPACE=<namespace>
>
> as nothing other than the selected transports seems to pay attention to
> this environment variable.
>
> -- >8 --
> Subject: [PATCH] Documentation/gitnamespaces.txt: cater to older asciidoc
>
> Older asciidoc (e.g. 8.2.5 on Centos 5.5) is unhappy if a manpage does not
> have a SYNOPSIS section. Show a sample (and a possibly bogus) command line
> of running two commands that pay attention to this environment variable
> with a customized value.
>
> Signed-off-by: Junio C Hamano <gitster@pobox.com>
> ---
> Documentation/gitnamespaces.txt | 7 +++++++
> 1 files changed, 7 insertions(+), 0 deletions(-)
>
> diff --git a/Documentation/gitnamespaces.txt b/Documentation/gitnamespaces.txt
> index ed8924e..c6713cf 100644
> --- a/Documentation/gitnamespaces.txt
> +++ b/Documentation/gitnamespaces.txt
> @@ -5,6 +5,13 @@ NAME
> ----
> gitnamespaces - Git namespaces
>
> +SYNOPSIS
> +--------
> +[verse]
> +GIT_NAMESPACE=<namespace> 'git upload-pack'
> +GIT_NAMESPACE=<namespace> 'git receive-pack'
> +
> +
> DESCRIPTION
> -----------
>
> --
> 1.7.7.rc1.3.g559357
>
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: Re* [PATCH 4/4] Add documentation for ref namespaces
2011-09-16 3:40 ` Jamey Sharp
@ 2011-09-16 16:20 ` Junio C Hamano
0 siblings, 0 replies; 17+ messages in thread
From: Junio C Hamano @ 2011-09-16 16:20 UTC (permalink / raw)
To: Jamey Sharp
Cc: Ævar Arnfjörð Bjarmason, Shawn O. Pearce,
Johannes Schindelin, Jeff King, Jakub Narebski, git,
Josh Triplett
Jamey Sharp <jamey@minilop.net> writes:
> Assuming that you're happy with this level of detail, and that the
> AsciiDoc syntax is correct (I'm not familiar enough with it), I'm happy
> with the patch you propose---
>
> Reviewed-by: Jamey Sharp <jamey@minilop.net>
Thanks.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: What's cooking in git.git (Jun 2011, #01; Sun, 5)
2011-06-07 18:21 ` Jamey Sharp
` (3 preceding siblings ...)
2011-06-07 18:21 ` [PATCH 4/4] Add documentation for ref namespaces Jamey Sharp
@ 2011-06-07 18:59 ` Junio C Hamano
4 siblings, 0 replies; 17+ messages in thread
From: Junio C Hamano @ 2011-06-07 18:59 UTC (permalink / raw)
To: Jamey Sharp
Cc: Junio C Hamano, Shawn O. Pearce, Johannes Schindelin, Jeff King,
Jakub Narebski, git, Josh Triplett
Jamey Sharp <jamey@minilop.net> writes:
> So, the suggested change to actually use "refs/" as a filter caused this
> failure. Based on this, we'd tend to suggest that we should go back to
> the version which preserved the existing behavior, to avoid breaking
> assumptions like this; that seems preferable to tracking down all the
> places that would break due to this new ref filtering. Adding that
> filtering and fixing all the resulting breakage seems like an entirely
> separate change.
Thanks, that makes sense.
^ permalink raw reply [flat|nested] 17+ messages in thread