{"thread":{"id":"35343","subject":"Access different NAMESPACE of remote repo from client side","startedAt":"2013-11-15T08:19:17Z","lastAt":"2013-11-16T09:13:30Z","messageCount":6,"participants":["Jiang Xin","Sitaram Chamarty"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"230664","messageId":"CANYiYbGiXkBQdXMGbcGV6WjtG82ax6z94TMatP2ZTQ54=KgMjg@mail.gmail.com","threadId":"35343","inReplyTo":null,"subject":"Access different NAMESPACE of remote repo from client side","fromName":"Jiang Xin","fromEmail":"worldhello.net@gmail.com","sentAt":"2013-11-15T08:19:17Z","receivedAt":"2013-11-15T08:19:17Z","isPatch":false,"sender":{"key":"worldhello.net@gmail.com","avatar":"https://avatars.githubusercontent.com/u/183860?v=4"},"body":"GIT_NAMESPACE is designed to be used mainly on the server side, that\nthe server can serve multiple git repositories while share one single\nrepository storage using different GIT_NAMESPACE settings.\n\nSince we know that one remote repository hosts multiple namespaces,\ncan we handle different namespaces in one local repository? Or can\nwe access the proper namespace of the remote repository without\ncomplicated server settings?\n\nAt least there are three solutions for ssh protocol: pass namespace\nthrough environment, pass namespace in URL, or pass namespace from\nthe proper settings of remote.<name>.receivepack and\nremote.<name>.uploadpack.\n\nSolution 1: passing the namespace through environment.\n\n 1. Set '/etc/sshd_config' in the server side as the following,\n    so that the ssh server can accept GIT_NAMESPACE environment.\n\n        AcceptEnv LANG LC_* GIT_NAMESPACE\n\n 2. In the client side, When connect to ssh server, must send the\n    GIT_NAMESPACE environment. This can be done with a remote-ext\n    url:\n\n        $ git remote add foo \\\n          'ext::ssh -o SendEnv=GIT_NAMESPACE git@server %S 'path/to/repo.git'\n\nThen the remote \"foo\" is GIT_NAMESPACE aware, but when operate on\nthis remote, must provide proper \"--namespace\" option.\n\n    $ git --namespace=foo push foo master\n    $ git --namespace=foo fetch foo\n    $ git --namespace=foo ls-remote foo\n    $ git --namespace=foo remote prune foo\n    $ git --namespace=foo archive --remote foo HEAD\n\nBut provide a \"--namespace\" option is error-prone, but we may invent\n\"remote.<name>.namespace\" or something to set GIT_NAMESPACE\nautomatically when push to or fetch from remote server.\n\nSolution 2: passing the namespace in URL.\n\nAgain use remote-ext style URL to access remote repository:\n\n    $ git remote add foo \\\n        'ext::ssh git@server git --namespace foo %s path/to/repo.git'\n\n    $ git remote add bar \\\n        'ext::ssh git@server git --namespace bar %s path/to/repo.git'\n\nBut if the remote server use a limit shell (such as git-shell or\ngitolite), the above URLs won't work. This is because these git\nspecific shell (git-shell or gitolite) do not like options.\n\nSolution 3: use custom receivepack and uploadpack. e.g.\n\n    [remote \"foo\"]\n        url = ssh://git@server/path/to/repo.git\n        receivepack = git --namespace foo receive-pack\n        uploadpack = git --namespace foo upload-pack\n        fetch = +refs/heads/*:refs/remotes/foo/*\n\n    [remote \"bar\"]\n        url = ssh://git@server/path/to/repo.git\n        receivepack = git --namespace bar receive-pack\n        uploadpack = git --namespace bar upload-pack\n        fetch = +refs/heads/*:refs/remotes/foo/*\n\nJust like solution 2, these settings won't work without a patched\ngit-shell or gitolite.\n\nI will send a patch in next email to address the latter two cases.\n\n\n-- \nJiang Xin\n"},{"id":"230668","messageId":"0469850db334fb22b7cf15848897c7e1b1a8b291.1384508792.git.worldhello.net@gmail.com","threadId":"35343","inReplyTo":"CANYiYbGiXkBQdXMGbcGV6WjtG82ax6z94TMatP2ZTQ54=KgMjg@mail.gmail.com","subject":"[PATCH] shell: allow git command with --namespace option","fromName":"Jiang Xin","fromEmail":"worldhello.net@gmail.com","sentAt":"2013-11-15T09:49:40Z","receivedAt":"2013-11-15T09:49:40Z","isPatch":true,"sender":{"key":"worldhello.net@gmail.com","avatar":"https://avatars.githubusercontent.com/u/183860?v=4"},"body":"GIT_NAMESPACE is designed to be used mainly on the server side, that\nthe server can serve multiple git repositories while share one single\nrepository storage using different GIT_NAMESPACE settings.\n\nSince we know that one remote repository hosts multiple namespaces,\ncan we handle different namespaces in one local repository? Or can\nwe access the proper namespace of the remote repository without\ncomplicated server settings?\n\nWe can access namespace of remote repository using a proper formated\nURL or with the help of settings of \"remote.<name>.receivepack\" and\n\"remote.<name>.uploadpack\". E.g.\n\nUse remote-ext style URL to access specific namespace of the remote:\n\n    $ git remote add foo \\\n        'ext::ssh git@server git --namespace foo %s path/to/repo.git'\n\n    $ git remote add bar \\\n        'ext::ssh git@server git --namespace bar %s path/to/repo.git'\n\nOr set \"remote.<name>.receivepack\" and \"remote.<name>.uploadpack\".\n\n    [remote \"foo\"]\n        url = ssh://git@server/path/to/repo.git\n        receivepack = git --namespace foo receive-pack\n        uploadpack = git --namespace foo upload-pack\n        fetch = +refs/heads/*:refs/remotes/foo/*\n\n    [remote \"bar\"]\n        url = ssh://git@server/path/to/repo.git\n        receivepack = git --namespace bar receive-pack\n        uploadpack = git --namespace bar upload-pack\n        fetch = +refs/heads/*:refs/remotes/foo/*\n\nBut if the remote ssh server use a limit shell (such as git-shell\nor gitolite), the above URLs won't work. This is because these git\nspecific shell (git-shell or gitolite) do not like options.\n\nThis patch makes git-shell aware of the \"--namespace\" option.\n\nSigned-off-by: Jiang Xin <worldhello.net@gmail.com>\n---\n shell.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++-\n 1 file changed, 46 insertions(+), 1 deletion(-)\n\ndiff --git a/shell.c b/shell.c\nindex 66350b2..a619577 100644\n--- a/shell.c\n+++ b/shell.c\n@@ -25,6 +25,50 @@ static int do_generic_cmd(const char *me, char *arg)\n \treturn execv_git_cmd(my_argv);\n }\n \n+static int do_git_with_opts_cmd(const char *me, char *arg)\n+{\n+\tconst char *allowed_cmds[] = {\n+\t\t\"receive-pack\",\n+\t\t\"upload-pack\",\n+\t\t\"upload-archive\",\n+\t\tNULL,\n+\t};\n+\tconst char **user_argv, **p;\n+\tconst char *cmd = NULL;\n+\tint count;\n+\n+\tcount = split_cmdline(arg, &user_argv);\n+\tif (count < 0) {\n+\t\tdie (\"Invalid command format '%s'\\n\", arg);\n+\t}\n+\n+\tif (count == 3 && !strncmp(\"--namespace=\", *user_argv, 12)) {\n+\t\tcmd = user_argv[1];\n+\t\tp = user_argv + 2;\n+\t} else if (count == 4 && !strcmp(\"--namespace\", *user_argv)) {\n+\t\tcmd = user_argv[2];\n+\t\tp = user_argv + 3;\n+\t} else {\n+\t\tcmd = user_argv[0];\n+\t\tp = user_argv + 1;\n+\t}\n+\n+\tif (cmd) {\n+\t\t/* last arg is path of repository */\n+\t\tif (!*p || *(p+1))\n+\t\t\tdie(\"bad argument\");\n+\n+\t\tfor (p = allowed_cmds; *p; p++) {\n+\t\t\tif (strcmp(*p, cmd))\n+\t\t\t\tcontinue;\n+\t\t\tsetup_path();\n+\t\t\treturn execv_git_cmd(user_argv);\n+\t\t}\n+\t}\n+\n+\tdie(\"bad command\");\n+}\n+\n static int do_cvs_cmd(const char *me, char *arg)\n {\n \tconst char *cvsserver_argv[3] = {\n@@ -138,6 +182,7 @@ static struct commands {\n \t{ \"git-receive-pack\", do_generic_cmd },\n \t{ \"git-upload-pack\", do_generic_cmd },\n \t{ \"git-upload-archive\", do_generic_cmd },\n+\t{ \"git\", do_git_with_opts_cmd },\n \t{ \"cvs\", do_cvs_cmd },\n \t{ NULL },\n };\n@@ -185,7 +230,7 @@ int main(int argc, char **argv)\n \t}\n \n \tprog = xstrdup(argv[2]);\n-\tif (!strncmp(prog, \"git\", 3) && isspace(prog[3]))\n+\tif (!strncmp(prog, \"git\", 3) && isspace(prog[3]) && isalpha(prog[4]))\n \t\t/* Accept \"git foo\" as if the caller said \"git-foo\". */\n \t\tprog[3] = '-';\n \n-- \n1.8.5.rc2.2.g0469850\n"},{"id":"230680","messageId":"52862EEE.8010800@gmail.com","threadId":"35343","inReplyTo":"CANYiYbGiXkBQdXMGbcGV6WjtG82ax6z94TMatP2ZTQ54=KgMjg@mail.gmail.com","subject":"Re: Access different NAMESPACE of remote repo from client side","fromName":"Sitaram Chamarty","fromEmail":"sitaramc@gmail.com","sentAt":"2013-11-15T14:25:50Z","receivedAt":"2013-11-15T14:25:50Z","isPatch":false,"sender":{"key":"sitaramc@gmail.com","avatar":"https://avatars.githubusercontent.com/u/43316?v=4"},"body":"On 11/15/2013 01:49 PM, Jiang Xin wrote:\n> GIT_NAMESPACE is designed to be used mainly on the server side, that\n> the server can serve multiple git repositories while share one single\n> repository storage using different GIT_NAMESPACE settings.\n> \n> Since we know that one remote repository hosts multiple namespaces,\n> can we handle different namespaces in one local repository? Or can\n> we access the proper namespace of the remote repository without\n> complicated server settings?\n> \n> At least there are three solutions for ssh protocol: pass namespace\n> through environment, pass namespace in URL, or pass namespace from\n> the proper settings of remote.<name>.receivepack and\n> remote.<name>.uploadpack.\n> \n> Solution 1: passing the namespace through environment.\n> \n>  1. Set '/etc/sshd_config' in the server side as the following,\n>     so that the ssh server can accept GIT_NAMESPACE environment.\n> \n>         AcceptEnv LANG LC_* GIT_NAMESPACE\n> \n>  2. In the client side, When connect to ssh server, must send the\n>     GIT_NAMESPACE environment. This can be done with a remote-ext\n>     url:\n> \n>         $ git remote add foo \\\n>           'ext::ssh -o SendEnv=GIT_NAMESPACE git@server %S 'path/to/repo.git'\n> \n> Then the remote \"foo\" is GIT_NAMESPACE aware, but when operate on\n> this remote, must provide proper \"--namespace\" option.\n> \n>     $ git --namespace=foo push foo master\n>     $ git --namespace=foo fetch foo\n>     $ git --namespace=foo ls-remote foo\n>     $ git --namespace=foo remote prune foo\n>     $ git --namespace=foo archive --remote foo HEAD\n> \n> But provide a \"--namespace\" option is error-prone, but we may invent\n> \"remote.<name>.namespace\" or something to set GIT_NAMESPACE\n> automatically when push to or fetch from remote server.\n> \n> Solution 2: passing the namespace in URL.\n> \n> Again use remote-ext style URL to access remote repository:\n> \n>     $ git remote add foo \\\n>         'ext::ssh git@server git --namespace foo %s path/to/repo.git'\n> \n>     $ git remote add bar \\\n>         'ext::ssh git@server git --namespace bar %s path/to/repo.git'\n> \n> But if the remote server use a limit shell (such as git-shell or\n> gitolite), the above URLs won't work. This is because these git\n> specific shell (git-shell or gitolite) do not like options.\n> \n> Solution 3: use custom receivepack and uploadpack. e.g.\n> \n>     [remote \"foo\"]\n>         url = ssh://git@server/path/to/repo.git\n>         receivepack = git --namespace foo receive-pack\n>         uploadpack = git --namespace foo upload-pack\n>         fetch = +refs/heads/*:refs/remotes/foo/*\n> \n>     [remote \"bar\"]\n>         url = ssh://git@server/path/to/repo.git\n>         receivepack = git --namespace bar receive-pack\n>         uploadpack = git --namespace bar upload-pack\n>         fetch = +refs/heads/*:refs/remotes/foo/*\n> \n> Just like solution 2, these settings won't work without a patched\n> git-shell or gitolite.\n\nGitolite has a namespaces branch that handles namespaces as described in\nhttp://gitolite.com/gitolite/namespaces.html\n\nBriefly, it recognises that you can have a \"main\" repo off of which\nseveral developer might want to hang their logical repos.\n\nIt also recognises that the actual names of the logical repos will\nfollow some pattern that may include the name of the developer also, and\nprovides a way to derive the name of the physical repo from the logical\none.\n\nThere is an example or two in that link.\n"},{"id":"230681","messageId":"52863410.9090508@gmail.com","threadId":"35343","inReplyTo":"52862EEE.8010800@gmail.com","subject":"Re: Access different NAMESPACE of remote repo from client side","fromName":"Sitaram Chamarty","fromEmail":"sitaramc@gmail.com","sentAt":"2013-11-15T14:47:44Z","receivedAt":"2013-11-15T14:47:44Z","isPatch":false,"sender":{"key":"sitaramc@gmail.com","avatar":"https://avatars.githubusercontent.com/u/43316?v=4"},"body":"On 11/15/2013 07:55 PM, Sitaram Chamarty wrote:\n> On 11/15/2013 01:49 PM, Jiang Xin wrote:\n>> GIT_NAMESPACE is designed to be used mainly on the server side, that\n>> the server can serve multiple git repositories while share one single\n>> repository storage using different GIT_NAMESPACE settings.\n>>\n>> Since we know that one remote repository hosts multiple namespaces,\n>> can we handle different namespaces in one local repository? Or can\n>> we access the proper namespace of the remote repository without\n>> complicated server settings?\n>>\n>> At least there are three solutions for ssh protocol: pass namespace\n>> through environment, pass namespace in URL, or pass namespace from\n>> the proper settings of remote.<name>.receivepack and\n>> remote.<name>.uploadpack.\n>>\n>> Solution 1: passing the namespace through environment.\n>>\n>>  1. Set '/etc/sshd_config' in the server side as the following,\n>>     so that the ssh server can accept GIT_NAMESPACE environment.\n>>\n>>         AcceptEnv LANG LC_* GIT_NAMESPACE\n>>\n>>  2. In the client side, When connect to ssh server, must send the\n>>     GIT_NAMESPACE environment. This can be done with a remote-ext\n>>     url:\n>>\n>>         $ git remote add foo \\\n>>           'ext::ssh -o SendEnv=GIT_NAMESPACE git@server %S 'path/to/repo.git'\n>>\n>> Then the remote \"foo\" is GIT_NAMESPACE aware, but when operate on\n>> this remote, must provide proper \"--namespace\" option.\n>>\n>>     $ git --namespace=foo push foo master\n>>     $ git --namespace=foo fetch foo\n>>     $ git --namespace=foo ls-remote foo\n>>     $ git --namespace=foo remote prune foo\n>>     $ git --namespace=foo archive --remote foo HEAD\n>>\n>> But provide a \"--namespace\" option is error-prone, but we may invent\n>> \"remote.<name>.namespace\" or something to set GIT_NAMESPACE\n>> automatically when push to or fetch from remote server.\n>>\n>> Solution 2: passing the namespace in URL.\n>>\n>> Again use remote-ext style URL to access remote repository:\n>>\n>>     $ git remote add foo \\\n>>         'ext::ssh git@server git --namespace foo %s path/to/repo.git'\n>>\n>>     $ git remote add bar \\\n>>         'ext::ssh git@server git --namespace bar %s path/to/repo.git'\n>>\n>> But if the remote server use a limit shell (such as git-shell or\n>> gitolite), the above URLs won't work. This is because these git\n>> specific shell (git-shell or gitolite) do not like options.\n>>\n>> Solution 3: use custom receivepack and uploadpack. e.g.\n>>\n>>     [remote \"foo\"]\n>>         url = ssh://git@server/path/to/repo.git\n>>         receivepack = git --namespace foo receive-pack\n>>         uploadpack = git --namespace foo upload-pack\n>>         fetch = +refs/heads/*:refs/remotes/foo/*\n>>\n>>     [remote \"bar\"]\n>>         url = ssh://git@server/path/to/repo.git\n>>         receivepack = git --namespace bar receive-pack\n>>         uploadpack = git --namespace bar upload-pack\n>>         fetch = +refs/heads/*:refs/remotes/foo/*\n>>\n>> Just like solution 2, these settings won't work without a patched\n>> git-shell or gitolite.\n> \n> Gitolite has a namespaces branch that handles namespaces as described in\n> http://gitolite.com/gitolite/namespaces.html\n> \n> Briefly, it recognises that you can have a \"main\" repo off of which\n> several developer might want to hang their logical repos.\n> \n> It also recognises that the actual names of the logical repos will\n> follow some pattern that may include the name of the developer also, and\n> provides a way to derive the name of the physical repo from the logical\n> one.\n> \n> There is an example or two in that link.\n\nI should add that the Gitolite model is: the user doesn't need to know\nabout namespaces, because namespaces are just things that the server\nadmin is setting up for his own reasons...\n\n...typically because he anticipates several dozens of people cloning the\nsame repo into their namespace and so he expects to save a lot of disk\ndoing this).\n\nSo in this model we don't really need anything on the client side.\n"},{"id":"230697","messageId":"CANYiYbHzHEFLshU8r-m=0CUo7JTu-iyv1W4N291hX8+r1BYY-w@mail.gmail.com","threadId":"35343","inReplyTo":"52863410.9090508@gmail.com","subject":"Re: Access different NAMESPACE of remote repo from client side","fromName":"Jiang Xin","fromEmail":"worldhello.net@gmail.com","sentAt":"2013-11-16T08:00:18Z","receivedAt":"2013-11-16T08:00:18Z","isPatch":false,"sender":{"key":"worldhello.net@gmail.com","avatar":"https://avatars.githubusercontent.com/u/183860?v=4"},"body":"2013/11/15 Sitaram Chamarty <sitaramc@gmail.com>:\n> On 11/15/2013 07:55 PM, Sitaram Chamarty wrote:\n>> On 11/15/2013 01:49 PM, Jiang Xin wrote:\n>>> Just like solution 2, these settings won't work without a patched\n>>> git-shell or gitolite.\n>>\n>> Gitolite has a namespaces branch that handles namespaces as described in\n>> http://gitolite.com/gitolite/namespaces.html\n>>\n>> Briefly, it recognises that you can have a \"main\" repo off of which\n>> several developer might want to hang their logical repos.\n>>\n>> It also recognises that the actual names of the logical repos will\n>> follow some pattern that may include the name of the developer also, and\n>> provides a way to derive the name of the physical repo from the logical\n>> one.\n>>\n>> There is an example or two in that link.\n\nI use gitolite everyday, and thank you for inventing it. I use gitolite v2 for\na long time, and migrated to v3 recently. Thank you for pointing out\nthere is a \"namespace\" feature branch, and I love the implementation\nvery much, it is so easy to map logical repos to one physical repo.\n\n>\n> I should add that the Gitolite model is: the user doesn't need to know\n> about namespaces, because namespaces are just things that the server\n> admin is setting up for his own reasons...\n>\n\nI want to say something that git-namespace is sometimes significant\nfor normal user not only for admin.\n\nSome of my repos are managed by Topgit. With the help of topgit,\ndependance of the topic branch (usually named as \"t/feature-name\")\nare tracked by file \".topdeps\" and a special ref named as\n\"refs/top-bases/t/feature-name\". So there are many topic branches\nand many useful special refs.\n\nEvery time when I want to update all topic branches to the new\nupstream version, just before run \"tg update\", I want to take a\nsnapshoot of all branches and refs. Clone is heavy, so I want to use\nlight-weight namespace.\n\nIf the server is out of my control, it would be nice to let the user pass\nnamespace to the server from client side.\n\nIndeed, I patched gitolite first as the follows, than I find out git-shell\nneeds to be patched too.\n\n\ndiff --git a/src/gitolite-shell b/src/gitolite-shell\nindex 7a27cc0..1c957da 100755\n--- a/src/gitolite-shell\n+++ b/src/gitolite-shell\n@@ -101,7 +101,7 @@ sub main {\n     my $user = $ENV{GL_USER} = shift @ARGV;\n\n     # set up the repo and the attempted access\n-    my ( $verb, $repo ) = parse_soc();    # returns only for git commands\n+    my ( $verb, $option, $repo ) = parse_soc();    # returns only for\ngit commands\n     sanity($repo);\n     $ENV{GL_REPO} = $repo;\n     my $aa = ( $verb =~ 'upload' ? 'R' : 'W' );\n@@ -135,7 +135,11 @@ sub main {\n         _system( \"git\", \"http-backend\" );\n     } else {\n         my $repodir = \"'$rc{GL_REPO_BASE}/$repo.git'\";\n-        _system( \"git\", \"shell\", \"-c\", \"$verb $repodir\" );\n+        my $cmd = $verb;\n+        if ($option) {\n+            $cmd =~ s/^(git)[- ](.*)$/$1 $option $2/;\n+        }\n+        _system( \"git\", \"shell\", \"-c\", \"$cmd $repodir\" );\n     }\n     trigger( 'POST_GIT', $repo, $user, $aa, 'any', $verb );\n }\n@@ -146,13 +150,24 @@ sub parse_soc {\n     my $soc = $ENV{SSH_ORIGINAL_COMMAND};\n     $soc ||= 'info';\n\n-    my $git_commands = \"git-upload-pack|git-receive-pack|git-upload-archive\";\n-    if ( $soc =~ m(^($git_commands) '/?(.*?)(?:\\.git(\\d)?)?'$) ) {\n-        my ( $verb, $repo, $trace_level ) = ( $1, $2, $3 );\n+    my $git_commands = \"upload-pack|receive-pack|upload-archive\";\n+    my ( $verb, $option, $repo, $trace_level );\n+    if ( $soc =~\nm(^git\\s+(?:(--namespace)(?:=|\\s+)(\\S+)\\s+)?(\\S+)\\s+'/?(.*?)(?:\\.git(\\d)?)?'$)\n) {\n+        $option = \"$1=$2\";\n+        $verb = \"git-$3\";\n+        $repo = $4;\n+        $trace_level = $5;\n+    } elsif ( $soc =~ m(^git[- ]($git_commands) '/?(.*?)(?:\\.git(\\d)?)?'$) ) {\n+        $verb = \"git-$1\";\n+        $repo = $2;\n+        $trace_level = $3;\n+    }\n+\n+    if ($verb) {\n         $ENV{D} = $trace_level if $trace_level;\n         _die \"invalid repo name: '$repo'\" if $repo !~ $REPONAME_PATT;\n         trace( 2, \"git command\", $soc );\n-        return ( $verb, $repo );\n+        return ( $verb, $option, $repo );\n     }\n\n     # after this we should not return; caller expects us to handle it all here\n\n\n\n-- \nJiang Xin\n"},{"id":"230698","messageId":"5287373A.8030604@gmail.com","threadId":"35343","inReplyTo":"CANYiYbHzHEFLshU8r-m=0CUo7JTu-iyv1W4N291hX8+r1BYY-w@mail.gmail.com","subject":"Re: Access different NAMESPACE of remote repo from client side","fromName":"Sitaram Chamarty","fromEmail":"sitaramc@gmail.com","sentAt":"2013-11-16T09:13:30Z","receivedAt":"2013-11-16T09:13:30Z","isPatch":false,"sender":{"key":"sitaramc@gmail.com","avatar":"https://avatars.githubusercontent.com/u/43316?v=4"},"body":"On 11/16/2013 01:30 PM, Jiang Xin wrote:\n> 2013/11/15 Sitaram Chamarty <sitaramc@gmail.com>:\n>> On 11/15/2013 07:55 PM, Sitaram Chamarty wrote:\n\n[snip]\n\n>> I should add that the Gitolite model is: the user doesn't need to know\n>> about namespaces, because namespaces are just things that the server\n>> admin is setting up for his own reasons...\n>>\n> \n> I want to say something that git-namespace is sometimes significant\n> for normal user not only for admin.\n\nSure.  I only meant in the model that I wrote that branch for.\n\nBut consider a slight change of syntax:\n\n    repo dev/CREATOR/..*\n        C   =   @team\n        RW+ =   CREATOR\n        R   =   @all\n        option namespace.pattern-1 = dev/%/%/NS/* is @1/@3 in @2\n\nLet's say linux and git are parent repos already created (maybe earlier\nin the conf).\n\nThis conf will let you use URLs like\n\n    dev/u1/git/NS/bar   (becomes namespace u1/bar in git)\n    dev/u2/git/NS/baz   (becomes namespace u2/baz in git)\n\nYeah it looks like a kludge, but all I wanted to do was to show you that\nit's not entirely true to say the client cannot control the namespace!\n"}]}