From: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
To: git@vger.kernel.org
Cc: "Jonathan Niedier" <jrnieder@gmail.com>,
"Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
Subject: [PATCH/POC 1/7] Make git_path() beware of file relocation in $GIT_DIR
Date: Wed, 11 Dec 2013 21:15:27 +0700 [thread overview]
Message-ID: <1386771333-32574-2-git-send-email-pclouds@gmail.com> (raw)
In-Reply-To: <1386771333-32574-1-git-send-email-pclouds@gmail.com>
We allow the user to relocate certain paths out of $GIT_DIR via
environment variables, e.g. GIT_OBJECT_DIRECTORY, GIT_INDEX_FILE and
GIT_GRAFT_FILE. All callers are not supposed to use git_path() or
git_pathdup() to get those paths. Instead they must use
get_object_directory(), get_index_file() and get_graft_file()
respectively. This is inconvenient and could be missed in review
(there's git_path("objects/info/alternates") somewhere in
sha1_file.c).
This patch makes git_path() and git_pathdup() understand those
environment variables. So if you set GIT_OBJECT_DIRECTORY to /foo/bar,
git_path("objects/abc") should return /tmp/bar/abc. The same is done
for the two remaining env variables.
XXX trim consecutive slashes
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
cache.h | 1 +
environment.c | 9 +++++++--
path.c | 35 ++++++++++++++++++++++++++++++++---
t/t0060-path-utils.sh | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
test-path-utils.c | 7 +++++++
5 files changed, 95 insertions(+), 5 deletions(-)
diff --git a/cache.h b/cache.h
index ce377e1..cdafbd7 100644
--- a/cache.h
+++ b/cache.h
@@ -584,6 +584,7 @@ extern int fsync_object_files;
extern int core_preload_index;
extern int core_apply_sparse_checkout;
extern int precomposed_unicode;
+extern int git_db_env, git_index_env, git_graft_env;
/*
* The character that begins a commented line in user-editable file
diff --git a/environment.c b/environment.c
index 0a15349..1d74dde 100644
--- a/environment.c
+++ b/environment.c
@@ -81,6 +81,7 @@ static size_t namespace_len;
static const char *git_dir;
static char *git_object_dir, *git_index_file, *git_graft_file;
+int git_db_env, git_index_env, git_graft_env;
/*
* Repository-local GIT_* environment variables; see cache.h for details.
@@ -134,15 +135,19 @@ static void setup_git_env(void)
if (!git_object_dir) {
git_object_dir = xmalloc(strlen(git_dir) + 9);
sprintf(git_object_dir, "%s/objects", git_dir);
- }
+ } else
+ git_db_env = 1;
git_index_file = getenv(INDEX_ENVIRONMENT);
if (!git_index_file) {
git_index_file = xmalloc(strlen(git_dir) + 7);
sprintf(git_index_file, "%s/index", git_dir);
- }
+ } else
+ git_index_env = 1;
git_graft_file = getenv(GRAFT_ENVIRONMENT);
if (!git_graft_file)
git_graft_file = git_pathdup("info/grafts");
+ else
+ git_graft_env = 1;
if (getenv(NO_REPLACE_OBJECTS_ENVIRONMENT))
read_replace_refs = 0;
namespace = expand_namespace(getenv(GIT_NAMESPACE_ENVIRONMENT));
diff --git a/path.c b/path.c
index 24594c4..eda9176 100644
--- a/path.c
+++ b/path.c
@@ -49,10 +49,38 @@ char *mksnpath(char *buf, size_t n, const char *fmt, ...)
return cleanup_path(buf);
}
+static int dir_prefix(const char *buf, const char *dir)
+{
+ int len = strlen(dir);
+ return !strncmp(buf, dir, len) &&
+ (is_dir_sep(buf[len]) || buf[len] == '\0');
+}
+
+static void replace_dir(char *buf, int len, const char *newdir)
+{
+ int newlen = strlen(newdir);
+ int buflen = strlen(buf);
+ memmove(buf + newlen + 1, buf + len, buflen - len + 1);
+ memcpy(buf, newdir, newlen);
+ buf[newlen] = '/';
+}
+
+static void adjust_git_path(char *buf, int git_dir_len)
+{
+ /* XXX buffer overflow */
+ char *base = buf + git_dir_len;
+ if (git_graft_env && !strcmp(base, "info/grafts"))
+ strcpy(buf, get_graft_file());
+ else if (git_index_env && !strcmp(base, "index"))
+ strcpy(buf, get_index_file());
+ else if (git_db_env && dir_prefix(base, "objects"))
+ replace_dir(buf, git_dir_len + 7, get_object_directory());
+}
+
static char *vsnpath(char *buf, size_t n, const char *fmt, va_list args)
{
const char *git_dir = get_git_dir();
- size_t len;
+ size_t len, total_len;
len = strlen(git_dir);
if (n < len + 1)
@@ -60,9 +88,10 @@ static char *vsnpath(char *buf, size_t n, const char *fmt, va_list args)
memcpy(buf, git_dir, len);
if (len && !is_dir_sep(git_dir[len-1]))
buf[len++] = '/';
- len += vsnprintf(buf + len, n - len, fmt, args);
- if (len >= n)
+ total_len = len + vsnprintf(buf + len, n - len, fmt, args);
+ if (total_len >= n)
goto bad;
+ adjust_git_path(buf, len);
return cleanup_path(buf);
bad:
strlcpy(buf, bad_path, n);
diff --git a/t/t0060-path-utils.sh b/t/t0060-path-utils.sh
index 07c10c8..7ad2730 100755
--- a/t/t0060-path-utils.sh
+++ b/t/t0060-path-utils.sh
@@ -223,4 +223,52 @@ relative_path "<null>" "<empty>" ./
relative_path "<null>" "<null>" ./
relative_path "<null>" /foo/a/b ./
+test_expect_success 'git_path info/grafts without GIT_GRAFT_FILE' '
+ test-path-utils git_path info/grafts >actual1 &&
+ echo .git/info/grafts >expect1 &&
+ test_cmp expect1 actual1
+'
+
+test_expect_success 'git_path info/grafts with GIT_GRAFT_FILE' '
+ GIT_GRAFT_FILE=foo test-path-utils git_path info/grafts >actual2 &&
+ echo foo >expect2 &&
+ test_cmp expect2 actual2
+'
+
+test_expect_success 'git_path index' '
+ GIT_INDEX_FILE=foo test-path-utils git_path index >actual &&
+ echo foo >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success 'git_path index/foo' '
+ GIT_INDEX_FILE=foo test-path-utils git_path index/foo >actual &&
+ echo .git/index/foo >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success 'git_path index2' '
+ GIT_INDEX_FILE=foo test-path-utils git_path index2 >actual &&
+ echo .git/index2 >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success 'git_path objects' '
+ GIT_OBJECT_DIRECTORY=foo test-path-utils git_path objects >actual &&
+ echo foo/ >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success 'git_path objects/foo' '
+ GIT_OBJECT_DIRECTORY=foo test-path-utils git_path objects/foo >actual &&
+ echo foo//foo >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success 'git_path objects2' '
+ GIT_OBJECT_DIRECTORY=foo test-path-utils git_path objects2 >actual &&
+ echo .git/objects2 >expect &&
+ test_cmp expect actual
+'
+
test_done
diff --git a/test-path-utils.c b/test-path-utils.c
index 3dd3744..55e4fe0 100644
--- a/test-path-utils.c
+++ b/test-path-utils.c
@@ -135,6 +135,13 @@ int main(int argc, char **argv)
return 0;
}
+ if (argc == 3 && !strcmp(argv[1], "git_path")) {
+ int nongit_ok = 0;
+ setup_git_directory_gently(&nongit_ok);
+ puts(git_path("%s", argv[2]));
+ return 0;
+ }
+
fprintf(stderr, "%s: unknown function name: %s\n", argv[0],
argv[1] ? argv[1] : "(there was none)");
return 1;
--
1.8.5.1.77.g42c48fa
next prev parent reply other threads:[~2013-12-11 14:11 UTC|newest]
Thread overview: 49+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-12-11 14:15 [PATCH/POC 0/7] Support multiple worktrees Nguyễn Thái Ngọc Duy
2013-12-11 14:15 ` Nguyễn Thái Ngọc Duy [this message]
2013-12-13 16:30 ` [PATCH/POC 1/7] Make git_path() beware of file relocation in $GIT_DIR Junio C Hamano
2013-12-11 14:15 ` [PATCH/POC 2/7] Add new environment variable $GIT_SUPER_DIR Nguyễn Thái Ngọc Duy
2013-12-13 18:12 ` Junio C Hamano
2013-12-14 1:11 ` Duy Nguyen
2013-12-14 19:43 ` Junio C Hamano
2013-12-11 14:15 ` [PATCH/POC 3/7] setup.c: add split-repo support to .git files Nguyễn Thái Ngọc Duy
2013-12-13 18:30 ` Junio C Hamano
2013-12-13 20:43 ` Jonathan Nieder
2013-12-14 1:28 ` Duy Nguyen
2013-12-23 3:38 ` Duy Nguyen
2013-12-11 14:15 ` [PATCH/POC 4/7] setup.c: add split-repo support to is_git_directory() Nguyễn Thái Ngọc Duy
2013-12-11 14:15 ` [PATCH/POC 5/7] setup.c: reduce cleanup sites in setup_explicit_git_dir() Nguyễn Thái Ngọc Duy
2013-12-11 14:15 ` [PATCH/POC 6/7] setup.c: add split-repo support to setup_git_directory* Nguyễn Thái Ngọc Duy
2013-12-11 14:15 ` [PATCH/POC 7/7] init: add --split-repo with the same functionality as git-new-workdir Nguyễn Thái Ngọc Duy
2013-12-14 10:54 ` [PATCH v2 00/21] Support multiple worktrees Nguyễn Thái Ngọc Duy
2013-12-14 10:54 ` [PATCH v2 01/21] path.c: avoid PATH_MAX as buffer size from get_pathname() Nguyễn Thái Ngọc Duy
2013-12-15 8:35 ` Torsten Bögershausen
2013-12-15 9:02 ` Duy Nguyen
2013-12-15 9:33 ` Antoine Pelisse
2013-12-14 10:54 ` [PATCH v2 02/21] path.c: rename vsnpath() to git_vsnpath() Nguyễn Thái Ngọc Duy
2013-12-14 20:23 ` Ramsay Jones
2013-12-15 2:25 ` Duy Nguyen
2013-12-15 21:13 ` Ramsay Jones
2013-12-16 7:21 ` Duy Nguyen
2013-12-16 17:11 ` Jonathan Nieder
2013-12-16 20:16 ` Junio C Hamano
2013-12-16 22:59 ` Ramsay Jones
2013-12-14 10:54 ` [PATCH v2 03/21] path.c: move git_path() closer to similar functions git_pathdup() Nguyễn Thái Ngọc Duy
2013-12-14 10:54 ` [PATCH v2 04/21] Make git_path() aware of file relocation in $GIT_DIR Nguyễn Thái Ngọc Duy
2013-12-14 10:54 ` [PATCH v2 05/21] reflog: use avoid constructing .lock path with git_path Nguyễn Thái Ngọc Duy
2013-12-14 10:54 ` [PATCH v2 06/21] fast-import: use git_path() for accessing .git dir instead of get_git_dir() Nguyễn Thái Ngọc Duy
2013-12-14 10:54 ` [PATCH v2 07/21] Add new environment variable $GIT_SUPER_DIR Nguyễn Thái Ngọc Duy
2013-12-14 10:54 ` [PATCH v2 08/21] setup.c: refactor path manipulation out of read_gitfile() Nguyễn Thái Ngọc Duy
2013-12-14 10:54 ` [PATCH v2 09/21] setup.c: add split-repo support to .git files Nguyễn Thái Ngọc Duy
2013-12-14 10:54 ` [PATCH v2 10/21] setup.c: add split-repo support to is_git_directory() Nguyễn Thái Ngọc Duy
2013-12-14 10:54 ` [PATCH v2 11/21] setup.c: reduce cleanup sites in setup_explicit_git_dir() Nguyễn Thái Ngọc Duy
2013-12-14 10:54 ` [PATCH v2 12/21] environment.c: support super .git file specified by $GIT_DIR Nguyễn Thái Ngọc Duy
2013-12-14 10:54 ` [PATCH v2 13/21] setup: support $GIT_SUPER_DIR as well as super .git files Nguyễn Thái Ngọc Duy
2013-12-14 10:55 ` [PATCH v2 14/21] checkout: support checking out into a new working directory Nguyễn Thái Ngọc Duy
2013-12-14 10:55 ` [PATCH v2 15/21] checkout: clean up half-prepared directories in --to mode Nguyễn Thái Ngọc Duy
2013-12-14 10:55 ` [PATCH v2 16/21] setup.c: keep track of the .git file location if read Nguyễn Thái Ngọc Duy
2013-12-14 10:55 ` [PATCH v2 17/21] prune: strategies for split repositories Nguyễn Thái Ngọc Duy
2013-12-14 10:55 ` [PATCH v2 18/21] refs: adjust reflog path for repos/<id>/HEAD Nguyễn Thái Ngọc Duy
2013-12-14 10:55 ` [PATCH v2 19/21] refs: detach split repos' HEAD when the linked ref is updated/deleted Nguyễn Thái Ngọc Duy
2013-12-14 10:55 ` [PATCH v2 20/21] refs.c: refactor do_head_ref(... to do_one_head_ref("HEAD", Nguyễn Thái Ngọc Duy
2013-12-14 10:55 ` [PATCH v2 21/21] revision: include repos/../HEAD in --all Nguyễn Thái Ngọc Duy
2013-12-15 2:29 ` [PATCH v2 00/21] Support multiple worktrees Duy Nguyen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1386771333-32574-2-git-send-email-pclouds@gmail.com \
--to=pclouds@gmail.com \
--cc=git@vger.kernel.org \
--cc=jrnieder@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).