{"thread":{"id":"22614","subject":"[PATCH 2/5] init-db, rev-parse --git-dir: do not append redundant slash","startedAt":"2010-02-11T14:43:18Z","lastAt":"2010-02-12T16:00:14Z","messageCount":10,"participants":["Nguyễn Thái Ngọc Duy","Johannes Sixt","João Carlos Mendes Luís"],"isPatch":true,"patchVersion":1,"patchTotal":5},"messages":[{"id":"134229","messageId":"1265899403-15904-1-git-send-email-pclouds@gmail.com","threadId":"22614","inReplyTo":null,"subject":"[PATCH 0/5 v2] Worktree/Gitdir at root directory","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2010-02-11T14:43:18Z","receivedAt":"2010-02-11T14:43:18Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"So here we go again. Changes are:\n\n - Support DOS drives as root path (Thanks Hannes)\n - Fix one \"broken\" test that I was too lazy to do last time\n - t1509-root-worktree.sh will refuse to run under root permission\n\nI did not test it on Windows, so an Ack from someone who actually tests it on Windows\nis really appreciated.\n\nNguyễn Thái Ngọc Duy (5):\n  make_absolute_path(): Do not append redundant slash\n  init-db, rev-parse --git-dir: do not append redundant slash\n  Add is_root_path()\n  Support working directory located at root\n  Add test for using Git at root directory\n\n abspath.c                 |    5 +-\n builtin-init-db.c         |    9 +-\n builtin-rev-parse.c       |    4 +-\n git-compat-util.h         |   11 ++\n setup.c                   |   13 ++-\n t/t1509-root-worktree.sh  |  249 +++++++++++++++++++++++++++++++++++++++++++++\n t/t1509/excludes          |   14 +++\n t/t1509/prepare-chroot.sh |   38 +++++++\n 8 files changed, 332 insertions(+), 11 deletions(-)\n create mode 100755 t/t1509-root-worktree.sh\n create mode 100644 t/t1509/excludes\n create mode 100755 t/t1509/prepare-chroot.sh\n"},{"id":"134230","messageId":"1265899403-15904-2-git-send-email-pclouds@gmail.com","threadId":"22614","inReplyTo":"1265899403-15904-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 1/5] make_absolute_path(): Do not append redundant slash","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2010-02-11T14:43:19Z","receivedAt":"2010-02-11T14:43:19Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"When concatenating two paths, if the first one already have '/', do\nnot put another '/' in between the two paths.\n\nUsually this is not the case as getcwd() won't return '/foo/bar/',\nexcept when you are standing at root, then it will return '/'.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n abspath.c |    5 +++--\n 1 files changed, 3 insertions(+), 2 deletions(-)\n\ndiff --git a/abspath.c b/abspath.c\nindex b88122c..c91a29c 100644\n--- a/abspath.c\n+++ b/abspath.c\n@@ -54,8 +54,9 @@ const char *make_absolute_path(const char *path)\n \t\t\tif (len + strlen(last_elem) + 2 > PATH_MAX)\n \t\t\t\tdie (\"Too long path name: '%s/%s'\",\n \t\t\t\t\t\tbuf, last_elem);\n-\t\t\tbuf[len] = '/';\n-\t\t\tstrcpy(buf + len + 1, last_elem);\n+\t\t\tif (len && buf[len-1] != '/')\n+\t\t\t\tbuf[len++] = '/';\n+\t\t\tstrcpy(buf + len, last_elem);\n \t\t\tfree(last_elem);\n \t\t\tlast_elem = NULL;\n \t\t}\n-- \n1.7.0.rc2.182.g3adef\n"},{"id":"134227","messageId":"1265899403-15904-3-git-send-email-pclouds@gmail.com","threadId":"22614","inReplyTo":"1265899403-15904-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 2/5] init-db, rev-parse --git-dir: do not append redundant slash","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2010-02-11T14:43:20Z","receivedAt":"2010-02-11T14:43:20Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"If git_dir already has the trailing slash, don't put another one\nbefore .git. This only happens when git_dir is '/' or 'C:/'\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin-init-db.c   |    9 ++++++---\n builtin-rev-parse.c |    4 +++-\n 2 files changed, 9 insertions(+), 4 deletions(-)\n\ndiff --git a/builtin-init-db.c b/builtin-init-db.c\nindex dd84cae..aae7a4d 100644\n--- a/builtin-init-db.c\n+++ b/builtin-init-db.c\n@@ -331,11 +331,14 @@ int init_db(const char *template_dir, unsigned int flags)\n \t\tgit_config_set(\"receive.denyNonFastforwards\", \"true\");\n \t}\n \n-\tif (!(flags & INIT_DB_QUIET))\n-\t\tprintf(\"%s%s Git repository in %s/\\n\",\n+\tif (!(flags & INIT_DB_QUIET)) {\n+\t\tconst char *git_dir = get_git_dir();\n+\t\tint len = strlen(git_dir);\n+\t\tprintf(\"%s%s Git repository in %s%s\\n\",\n \t\t       reinit ? \"Reinitialized existing\" : \"Initialized empty\",\n \t\t       shared_repository ? \" shared\" : \"\",\n-\t\t       get_git_dir());\n+\t\t       git_dir, len && git_dir[len-1] != '/' ? \"/\" : \"\");\n+\t}\n \n \treturn 0;\n }\ndiff --git a/builtin-rev-parse.c b/builtin-rev-parse.c\nindex a8c5043..88bad9a 100644\n--- a/builtin-rev-parse.c\n+++ b/builtin-rev-parse.c\n@@ -637,6 +637,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)\n \t\t\tif (!strcmp(arg, \"--git-dir\")) {\n \t\t\t\tconst char *gitdir = getenv(GIT_DIR_ENVIRONMENT);\n \t\t\t\tstatic char cwd[PATH_MAX];\n+\t\t\t\tint len;\n \t\t\t\tif (gitdir) {\n \t\t\t\t\tputs(gitdir);\n \t\t\t\t\tcontinue;\n@@ -647,7 +648,8 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)\n \t\t\t\t}\n \t\t\t\tif (!getcwd(cwd, PATH_MAX))\n \t\t\t\t\tdie_errno(\"unable to get current working directory\");\n-\t\t\t\tprintf(\"%s/.git\\n\", cwd);\n+\t\t\t\tlen = strlen(cwd);\n+\t\t\t\tprintf(\"%s%s.git\\n\", cwd, len && cwd[len-1] != '/' ? \"/\" : \"\");\n \t\t\t\tcontinue;\n \t\t\t}\n \t\t\tif (!strcmp(arg, \"--is-inside-git-dir\")) {\n-- \n1.7.0.rc2.182.g3adef\n"},{"id":"134231","messageId":"1265899403-15904-4-git-send-email-pclouds@gmail.com","threadId":"22614","inReplyTo":"1265899403-15904-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 3/5] Add is_root_path()","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2010-02-11T14:43:21Z","receivedAt":"2010-02-11T14:43:21Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"This function returns the length of the root part of a path, or zero if\nthere is no root.\n\n\"The root part\" is the leading slash on Linux/Unix, or 'C:/' on Windows.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n ... and can be extended to recognize \"//machine/share/\" as a root part?\n\n git-compat-util.h |   11 +++++++++++\n 1 files changed, 11 insertions(+), 0 deletions(-)\n\ndiff --git a/git-compat-util.h b/git-compat-util.h\nindex a3c4537..4d0398d 100644\n--- a/git-compat-util.h\n+++ b/git-compat-util.h\n@@ -210,6 +210,17 @@ static inline const char *skip_prefix(const char *str, const char *prefix)\n \treturn strncmp(str, prefix, len) ? NULL : str + len;\n }\n \n+/* path must be canonical */\n+static inline int is_root_path(const char *path)\n+{\n+\tint len = 0;\n+\tif (has_dos_drive_prefix(path))\n+\t\tlen += 2;\n+\tif (is_dir_sep(path[len]))\n+\t\tlen++;\n+\treturn len;\n+}\n+\n #if defined(NO_MMAP) || defined(USE_WIN32_MMAP)\n \n #ifndef PROT_READ\n-- \n1.7.0.rc2.182.g3adef\n"},{"id":"134232","messageId":"1265899403-15904-5-git-send-email-pclouds@gmail.com","threadId":"22614","inReplyTo":"1265899403-15904-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 4/5] Support working directory located at root","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2010-02-11T14:43:22Z","receivedAt":"2010-02-11T14:43:22Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Git should work regardless where the working directory is located,\neven at root. This patch fixes two places where it assumes working\ndirectory always have parent directory.\n\nIn setup_git_directory_gently(), when Git goes up to root and finds\n.git there, it happily sets worktree to \"\" instead of \"/\".\n\nIn prefix_path(), loosen the outside repo check a little bit. Usually\nwhen a path XXX is inside worktree /foo, it must be either \"/foo\", or\n\"/foo/...\". When worktree is simply \"/\", we can safely ignore the\ncheck: we have a slash at the beginning already.\n\nNot related to worktree, but also set gitdir correctly if a bare repo\nis placed (insanely?) at root.\n\nThanks João Carlos Mendes Luís for pointing out this problem.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n setup.c |   13 ++++++++-----\n 1 files changed, 8 insertions(+), 5 deletions(-)\n\ndiff --git a/setup.c b/setup.c\nindex b38cbee..cdad176 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -18,14 +18,15 @@ const char *prefix_path(const char *prefix, int len, const char *path)\n \tif (normalize_path_copy(sanitized, sanitized))\n \t\tgoto error_out;\n \tif (is_absolute_path(orig)) {\n-\t\tsize_t len, total;\n+\t\tsize_t root_len, len, total;\n \t\tconst char *work_tree = get_git_work_tree();\n \t\tif (!work_tree)\n \t\t\tgoto error_out;\n \t\tlen = strlen(work_tree);\n+\t\troot_len = is_root_path(work_tree);\n \t\ttotal = strlen(sanitized) + 1;\n \t\tif (strncmp(sanitized, work_tree, len) ||\n-\t\t    (sanitized[len] != '\\0' && sanitized[len] != '/')) {\n+\t\t    (len > root_len && sanitized[len] != '\\0' && sanitized[len] != '/')) {\n \t\terror_out:\n \t\t\tdie(\"'%s' is outside repository\", orig);\n \t\t}\n@@ -321,7 +322,7 @@ const char *setup_git_directory_gently(int *nongit_ok)\n \tstatic char cwd[PATH_MAX+1];\n \tconst char *gitdirenv;\n \tconst char *gitfile_dir;\n-\tint len, offset, ceil_offset;\n+\tint len, offset, ceil_offset, root_len;\n \n \t/*\n \t * Let's assume that we are in a git repository.\n@@ -403,7 +404,8 @@ const char *setup_git_directory_gently(int *nongit_ok)\n \t\t\tif (!work_tree_env)\n \t\t\t\tinside_work_tree = 0;\n \t\t\tif (offset != len) {\n-\t\t\t\tcwd[offset] = '\\0';\n+\t\t\t\troot_len = is_root_path(cwd);\n+\t\t\t\tcwd[offset > root_len ? offset : root_len] = '\\0';\n \t\t\t\tset_git_dir(cwd);\n \t\t\t} else\n \t\t\t\tset_git_dir(\".\");\n@@ -427,7 +429,8 @@ const char *setup_git_directory_gently(int *nongit_ok)\n \tinside_git_dir = 0;\n \tif (!work_tree_env)\n \t\tinside_work_tree = 1;\n-\tgit_work_tree_cfg = xstrndup(cwd, offset);\n+\troot_len = is_root_path(cwd);\n+\tgit_work_tree_cfg = xstrndup(cwd, offset > root_len ? offset : root_len);\n \tif (check_repository_format_gently(nongit_ok))\n \t\treturn NULL;\n \tif (offset == len)\n-- \n1.7.0.rc2.182.g3adef\n"},{"id":"134228","messageId":"1265899403-15904-6-git-send-email-pclouds@gmail.com","threadId":"22614","inReplyTo":"1265899403-15904-1-git-send-email-pclouds@gmail.com","subject":"[PATCH 5/5] Add test for using Git at root directory","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2010-02-11T14:43:23Z","receivedAt":"2010-02-11T14:43:23Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"This kind of test requires a throw-away root filesystem so that it can\nplay on. If you have such a system, go ahead, \"chmod 777 /\" and run\nthis test manually. Because this is a dangerous test, you are required\nto set an env variable, and not to use root to run it.\n\nScript prepare-root.sh may help you set up a chroot environment with\nGit test suite inside. You will need Linux, static linked busybox,\nrsync and root permission to use it.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n t/t1509-root-worktree.sh  |  249 +++++++++++++++++++++++++++++++++++++++++++++\n t/t1509/excludes          |   14 +++\n t/t1509/prepare-chroot.sh |   38 +++++++\n 3 files changed, 301 insertions(+), 0 deletions(-)\n create mode 100755 t/t1509-root-worktree.sh\n create mode 100644 t/t1509/excludes\n create mode 100755 t/t1509/prepare-chroot.sh\n\ndiff --git a/t/t1509-root-worktree.sh b/t/t1509-root-worktree.sh\nnew file mode 100755\nindex 0000000..5322a3b\n--- /dev/null\n+++ b/t/t1509-root-worktree.sh\n@@ -0,0 +1,249 @@\n+#!/bin/sh\n+\n+test_description='Test Git when git repository is located at root\n+\n+This test requires write access in root. Do not bother if you do not\n+have a throwaway chroot or VM.\n+\n+Script t1509/prepare-chroot.sh may help you setup chroot, then you\n+can chroot in and execute this test from there.\n+'\n+\n+. ./test-lib.sh\n+\n+test_cmp_val() {\n+\techo \"$1\" > expected\n+\techo \"$2\" > result\n+\ttest_cmp expected result\n+}\n+\n+test_vars() {\n+\ttest_expect_success \"$1: gitdir\" '\n+\t\ttest_cmp_val \"'\"$2\"'\" \"$(git rev-parse --git-dir)\"\n+\t'\n+\n+\ttest_expect_success \"$1: worktree\" '\n+\t\ttest_cmp_val \"'\"$3\"'\" \"$(git rev-parse --show-toplevel)\"\n+\t'\n+\n+\ttest_expect_success \"$1: prefix\" '\n+\t\ttest_cmp_val \"'\"$4\"'\" \"$(git rev-parse --show-prefix)\"\n+\t'\n+}\n+\n+test_foobar_root() {\n+\ttest_expect_success 'add relative' '\n+\t\ttest -z \"$(cd / && git ls-files)\" &&\n+\t\tgit add foo/foome &&\n+\t\tgit add foo/bar/barme &&\n+\t\tgit add me &&\n+\t\t( cd / && git ls-files --stage ) > result &&\n+\t\ttest_cmp /ls.expected result &&\n+\t\trm \"$(git rev-parse --git-dir)/index\"\n+\t'\n+\n+\ttest_expect_success 'add absolute' '\n+\t\ttest -z \"$(cd / && git ls-files)\" &&\n+\t\tgit add /foo/foome &&\n+\t\tgit add /foo/bar/barme &&\n+\t\tgit add /me &&\n+\t\t( cd / && git ls-files --stage ) > result &&\n+\t\ttest_cmp /ls.expected result &&\n+\t\trm \"$(git rev-parse --git-dir)/index\"\n+\t'\n+\n+}\n+\n+test_foobar_foo() {\n+\ttest_expect_success 'add relative' '\n+\t\ttest -z \"$(cd / && git ls-files)\" &&\n+\t\tgit add foome &&\n+\t\tgit add bar/barme &&\n+\t\tgit add ../me &&\n+\t\t( cd / && git ls-files --stage ) > result &&\n+\t\ttest_cmp /ls.expected result &&\n+\t\trm \"$(git rev-parse --git-dir)/index\"\n+\t'\n+\n+\ttest_expect_success 'add absolute' '\n+\t\ttest -z \"$(cd / && git ls-files)\" &&\n+\t\tgit add /foo/foome &&\n+\t\tgit add /foo/bar/barme &&\n+\t\tgit add /me &&\n+\t\t( cd / && git ls-files --stage ) > result &&\n+\t\ttest_cmp /ls.expected result &&\n+\t\trm \"$(git rev-parse --git-dir)/index\"\n+\t'\n+}\n+\n+test_foobar_foobar() {\n+\ttest_expect_success 'add relative' '\n+\t\ttest -z \"$(cd / && git ls-files)\" &&\n+\t\tgit add ../foome &&\n+\t\tgit add barme &&\n+\t\tgit add ../../me &&\n+\t\t( cd / && git ls-files --stage ) > result &&\n+\t\ttest_cmp /ls.expected result &&\n+\t\trm \"$(git rev-parse --git-dir)/index\"\n+\t'\n+\n+\ttest_expect_success 'add absolute' '\n+\t\ttest -z \"$(cd / && git ls-files)\" &&\n+\t\tgit add /foo/foome &&\n+\t\tgit add /foo/bar/barme &&\n+\t\tgit add /me &&\n+\t\t( cd / && git ls-files --stage ) > result &&\n+\t\ttest_cmp /ls.expected result &&\n+\t\trm \"$(git rev-parse --git-dir)/index\"\n+\t'\n+}\n+\n+if ! test_have_prereq POSIXPERM || ! [ -w / ]; then\n+\tsay \"Dangerous test skipped. Read this test if you want to execute it\"\n+\ttest_done\n+fi\n+\n+if [ \"$IKNOWWHATIAMDOING\" != \"YES\" ]; then\n+\tsay \"You must set env var IKNOWWHATIAMDOING=YES in order to run this test\"\n+\ttest_done\n+fi\n+\n+if [ \"$UID\" = 0 ]; then\n+\tsay \"No you can't run this with root\"\n+\ttest_done\n+fi\n+\n+ONE_SHA1=d00491fd7e5bb6fa28c517a0bb32b8b506539d4d\n+\n+test_expect_success 'setup' '\n+\trm -rf /foo\n+\tmkdir /foo &&\n+\tmkdir /foo/bar &&\n+\techo 1 > /foo/foome &&\n+\techo 1 > /foo/bar/barme &&\n+\techo 1 > /me\n+'\n+\n+say \"GIT_DIR absolute, GIT_WORK_TREE set\"\n+\n+test_expect_success 'go to /' 'cd /'\n+\n+cat >ls.expected <<EOF\n+100644 $ONE_SHA1 0\tfoo/bar/barme\n+100644 $ONE_SHA1 0\tfoo/foome\n+100644 $ONE_SHA1 0\tme\n+EOF\n+\n+export GIT_DIR=\"$TRASH_DIRECTORY/.git\"\n+export GIT_WORK_TREE=/\n+\n+test_vars 'abs gitdir, root' \"$GIT_DIR\" \"/\" \"\"\n+test_foobar_root\n+\n+test_expect_success 'go to /foo' 'cd /foo'\n+\n+test_vars 'abs gitdir, foo' \"$GIT_DIR\" \"/\" \"foo/\"\n+test_foobar_foo\n+\n+test_expect_success 'go to /foo/bar' 'cd /foo/bar'\n+\n+test_vars 'abs gitdir, foo/bar' \"$GIT_DIR\" \"/\" \"foo/bar/\"\n+test_foobar_foobar\n+\n+say \"GIT_DIR relative, GIT_WORK_TREE set\"\n+\n+test_expect_success 'go to /' 'cd /'\n+\n+export GIT_DIR=\"$(echo $TRASH_DIRECTORY|sed 's,^/,,')/.git\"\n+export GIT_WORK_TREE=/\n+\n+test_vars 'rel gitdir, root' \"$GIT_DIR\" \"/\" \"\"\n+test_foobar_root\n+\n+test_expect_success 'go to /foo' 'cd /foo'\n+\n+export GIT_DIR=\"../$TRASH_DIRECTORY/.git\"\n+export GIT_WORK_TREE=/\n+\n+test_vars 'rel gitdir, foo' \"$TRASH_DIRECTORY/.git\" \"/\" \"foo/\"\n+test_foobar_foo\n+\n+test_expect_success 'go to /foo/bar' 'cd /foo/bar'\n+\n+export GIT_DIR=\"../../$TRASH_DIRECTORY/.git\"\n+export GIT_WORK_TREE=/\n+\n+test_vars 'rel gitdir, foo/bar' \"$TRASH_DIRECTORY/.git\" \"/\" \"foo/bar/\"\n+test_foobar_foobar\n+\n+say \"GIT_DIR relative, GIT_WORK_TREE relative\"\n+\n+test_expect_success 'go to /' 'cd /'\n+\n+export GIT_DIR=\"$(echo $TRASH_DIRECTORY|sed 's,^/,,')/.git\"\n+export GIT_WORK_TREE=.\n+\n+test_vars 'rel gitdir, root' \"$GIT_DIR\" \"/\" \"\"\n+test_foobar_root\n+\n+test_expect_success 'go to /' 'cd /foo'\n+\n+export GIT_DIR=\"../$TRASH_DIRECTORY/.git\"\n+export GIT_WORK_TREE=..\n+\n+test_vars 'rel gitdir, foo' \"$TRASH_DIRECTORY/.git\" \"/\" \"foo/\"\n+test_foobar_foo\n+\n+test_expect_success 'go to /foo/bar' 'cd /foo/bar'\n+\n+export GIT_DIR=\"../../$TRASH_DIRECTORY/.git\"\n+export GIT_WORK_TREE=../..\n+\n+test_vars 'rel gitdir, foo/bar' \"$TRASH_DIRECTORY/.git\" \"/\" \"foo/bar/\"\n+test_foobar_foobar\n+\n+say \".git at root\"\n+\n+unset GIT_DIR\n+unset GIT_WORK_TREE\n+\n+test_expect_success 'go to /' 'cd /'\n+test_expect_success 'setup' '\n+\trm -rf /.git\n+\techo \"Initialized empty Git repository in /.git/\" > expected &&\n+\tgit init > result &&\n+\ttest_cmp expected result\n+'\n+\n+test_vars 'auto gitdir, root' \".git\" \"/\" \"\"\n+test_foobar_root\n+\n+test_expect_success 'go to /foo' 'cd /foo'\n+test_vars 'auto gitdir, foo' \"/.git\" \"/\" \"foo/\"\n+test_foobar_foo\n+\n+test_expect_success 'go to /foo/bar' 'cd /foo/bar'\n+test_vars 'auto gitdir, foo/bar' \"/.git\" \"/\" \"foo/bar/\"\n+test_foobar_foobar\n+\n+test_expect_success 'cleanup' 'rm -rf /.git'\n+\n+say \"auto bare gitdir\"\n+\n+# DESTROYYYYY!!!!!\n+test_expect_success 'setup' '\n+\trm -rf /refs /objects /info /hooks\n+\trm /*\n+\tcd / &&\n+\techo \"Initialized empty Git repository in /\" > expected &&\n+\tgit init --bare > result &&\n+\ttest_cmp expected result\n+'\n+\n+test_vars 'auto gitdir, root' \".\" \"\" \"\"\n+\n+test_expect_success 'go to /foo' 'cd /foo'\n+\n+test_vars 'auto gitdir, root' \"/\" \"\" \"\"\n+\n+test_done\ndiff --git a/t/t1509/excludes b/t/t1509/excludes\nnew file mode 100644\nindex 0000000..d4d21d3\n--- /dev/null\n+++ b/t/t1509/excludes\n@@ -0,0 +1,14 @@\n+*.o\n+*~\n+*.bak\n+*.c\n+*.h\n+.git\n+contrib\n+Documentation\n+git-gui\n+gitk-git\n+gitweb\n+t/t4013\n+t/t5100\n+t/t5515\ndiff --git a/t/t1509/prepare-chroot.sh b/t/t1509/prepare-chroot.sh\nnew file mode 100755\nindex 0000000..407f2d2\n--- /dev/null\n+++ b/t/t1509/prepare-chroot.sh\n@@ -0,0 +1,38 @@\n+#!/bin/sh\n+\n+die() {\n+\techo >&2 \"$@\"\n+\texit 1\n+}\n+\n+xmkdir() {\n+\twhile [ -n \"$1\" ]; do\n+\t\t[ -d \"$1\" ] || mkdir \"$1\" || die \"Unable to mkdir $1\"\n+\t\tshift\n+\tdone\n+}\n+\n+R=\"$1\"\n+\n+[ -n \"$R\" ] || die \"Usage: prepare-chroot.sh <root>\"\n+[ -x git ] || die \"This script needs to be executed at git source code's top directory\"\n+[ -x /bin/busybox ] || die \"You need busybox\"\n+\n+xmkdir \"$R\" \"$R/bin\" \"$R/etc\" \"$R/lib\" \"$R/dev\"\n+[ -c \"$R/dev/null\" ] || die \"/dev/null is missing. Do mknod $R/dev/null c 1 3 && chmod 666 $R/dev/null\"\n+echo \"root:x:0:0:root:/:/bin/sh\" > \"$R/etc/passwd\"\n+echo \"$(id -nu):x:$(id -u):$(id -g)::$(pwd)/t:/bin/sh\" >> \"$R/etc/passwd\"\n+echo \"root::0:root\" > \"$R/etc/group\"\n+echo \"$(id -ng)::$(id -g):$(id -nu)\" >> \"$R/etc/group\"\n+\n+[ -x \"$R/bin/busybox\" ] || cp /bin/busybox \"$R/bin/busybox\"\n+[ -x \"$R/bin/sh\" ] || ln -s /bin/busybox \"$R/bin/sh\"\n+[ -x \"$R/bin/su\" ] || ln -s /bin/busybox \"$R/bin/su\"\n+\n+mkdir -p \"$R$(pwd)\"\n+rsync --exclude-from t/t1509/excludes -Ha . \"$R$(pwd)\"\n+ldd git | grep '=> /' | sed 's,.* => *\\([^ ]*\\) .*,\\1,' | while read i; do\n+\tmkdir -p \"$R$(dirname $i)\"\n+\tcp \"$i\" \"$R/$i\"\n+done\n+echo \"Execute this in root: 'chroot $R /bin/su - $(id -nu)'\"\n-- \n1.7.0.rc2.182.g3adef\n"},{"id":"134310","messageId":"4B75294B.8080205@kdbg.org","threadId":"22614","inReplyTo":"1265899403-15904-4-git-send-email-pclouds@gmail.com","subject":"Re: [PATCH 3/5] Add is_root_path()","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2010-02-12T10:11:23Z","receivedAt":"2010-02-12T10:11:23Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Nguyễn Thái Ngọc Duy schrieb:\n> This function returns the length of the root part of a path, or zero if\n> there is no root.\n\nThat is, the function primarily doesn't act as a predicate, and in fact \nyou never use it as such.\n\nI just noticed that this function is identical to offset_1st_component() \nin sha1_file.c.\n\n> --- a/git-compat-util.h\n> +++ b/git-compat-util.h\n> @@ -210,6 +210,17 @@ static inline const char *skip_prefix(const char *str, const char *prefix)\n>  \treturn strncmp(str, prefix, len) ? NULL : str + len;\n>  }\n>  \n> +/* path must be canonical */\n> +static inline int is_root_path(const char *path)\n> +{\n> +\tint len = 0;\n> +\tif (has_dos_drive_prefix(path))\n> +\t\tlen += 2;\n> +\tif (is_dir_sep(path[len]))\n> +\t\tlen++;\n> +\treturn len;\n> +}\n> +\n>  #if defined(NO_MMAP) || defined(USE_WIN32_MMAP)\n\nThis is not a good location for this function because on Windows we get \nwarnings about implicitly defined function isalpha() (which is hidden in \nthe macro has_dos_drive_prefix).\n\nI suggest to move offset_1st_component() to path.c, which would not be \ninlined anymore.\n\n-- Hannes\n"},{"id":"134311","messageId":"4B752BA1.9080105@kdbg.org","threadId":"22614","inReplyTo":"1265899403-15904-1-git-send-email-pclouds@gmail.com","subject":"Re: [PATCH 0/5 v2] Worktree/Gitdir at root directory","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2010-02-12T10:21:21Z","receivedAt":"2010-02-12T10:21:21Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Nguyễn Thái Ngọc Duy schrieb:\n> So here we go again. Changes are:\n> \n>  - Support DOS drives as root path (Thanks Hannes)\n>  - Fix one \"broken\" test that I was too lazy to do last time\n>  - t1509-root-worktree.sh will refuse to run under root permission\n> \n> I did not test it on Windows, so an Ack from someone who actually tests it on Windows\n> is really appreciated.\n\nI don't see any regressions in may tests on Windows, but I actually don't \nknow what to test (the chroot test doesn't work on Windows). I did test on \nthe root of a partition\n\n    T:\\> git init\n    T:\\> cd foo\n    T:\\foo> git add bar\n\nand it works as expected.\n\nYou should address my comments to 3/5, please.\n\n-- Hannes\n"},{"id":"134338","messageId":"4B755229.6000502@jonny.eng.br","threadId":"22614","inReplyTo":"4B752BA1.9080105@kdbg.org","subject":"Re: [PATCH 0/5 v2] Worktree/Gitdir at root directory","fromName":"João Carlos Mendes Luís","fromEmail":"jonny@jonny.eng.br","sentAt":"2010-02-12T13:05:45Z","receivedAt":"2010-02-12T13:05:45Z","isPatch":true,"sender":{"key":"jonny@jonny.eng.br","avatar":"https://gravatar.com/avatar/08e8bcb8e66e4b12bd5d62d2ada030ff3bb15f4a4ca230cc47f90d6218121fbe?d=mp&s=160"},"body":"\n\nJohannes Sixt wrote:\n> Nguyễn Thái Ngọc Duy schrieb:\n>> So here we go again. Changes are:\n>>\n>>  - Support DOS drives as root path (Thanks Hannes)\n>>  - Fix one \"broken\" test that I was too lazy to do last time\n>>  - t1509-root-worktree.sh will refuse to run under root permission\n>>\n>> I did not test it on Windows, so an Ack from someone who actually \n>> tests it on Windows\n>> is really appreciated.\n>\n> I don't see any regressions in may tests on Windows, but I actually \n> don't know what to test (the chroot test doesn't work on Windows). I \n> did test on the root of a partition\n>\n>    T:\\> git init\n>    T:\\> cd foo\n>    T:\\foo> git add bar\n>\n> and it works as expected.\n\nBeware: My first proposed patch \"worked\" at this level, but failed \ncompletely when I wanted to commit.   Try more operations just to be sure.\n\nThe auto test routines include a ram-disk creation, for windows case, \nbut I'm not sure how portable this would be.\n"},{"id":"134349","messageId":"4B757B0E.4010402@kdbg.org","threadId":"22614","inReplyTo":"4B755229.6000502@jonny.eng.br","subject":"Re: [PATCH 0/5 v2] Worktree/Gitdir at root directory","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2010-02-12T16:00:14Z","receivedAt":"2010-02-12T16:00:14Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"João Carlos Mendes Luís schrieb:\n> Johannes Sixt wrote:\n>> I don't see any regressions in may tests on Windows, but I actually \n>> don't know what to test (the chroot test doesn't work on Windows). I \n>> did test on the root of a partition\n>>\n>>    T:\\> git init\n>>    T:\\> cd foo\n>>    T:\\foo> git add bar\n>>\n>> and it works as expected.\n> \n> Beware: My first proposed patch \"worked\" at this level, but failed \n> completely when I wanted to commit.   Try more operations just to be sure.\n\nI tried commit, fetch, checkout, and they work as expected.\n\n-- Hannes\n"}]}