Re: [PATCH v4 05/27] Make git_path() aware of file relocation in $GIT_DIR

2014-03-02 Thread Eric Sunshine
On Sat, Mar 1, 2014 at 7:12 AM, Nguyễn Thái Ngọc Duy pclo...@gmail.com wrote:
 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

All callers are not is unusually difficult to understand. Changing
it to Callers are not simplifies.

 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

(for example, there's... reads a bit better.

 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

I guess you mean it should return /foo/bar/abc.

 for the two remaining env variables.

 git rev-parse --git-path is the wrapper for script use.

 Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
 ---
  Documentation/git-rev-parse.txt |  5 +
  builtin/rev-parse.c |  7 +++
  cache.h |  1 +
  environment.c   |  9 ++--
  path.c  | 46 
 +
  t/t0060-path-utils.sh   | 19 +
  6 files changed, 85 insertions(+), 2 deletions(-)

 diff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt
 index 0d2cdcd..33e4e90 100644
 --- a/Documentation/git-rev-parse.txt
 +++ b/Documentation/git-rev-parse.txt
 @@ -232,6 +232,11 @@ print a message to stderr and exit with nonzero status.
 repository.  If path is a gitfile then the resolved path
 to the real repository is printed.

 +--git-path path::
 +   Resolve $GIT_DIR/path and takes other path relocation
 +   variables such as $GIT_OBJECT_DIRECTORY,
 +   $GIT_INDEX_FILE... into account.

Would it help to add a quick illustration here?

For example, if GIT_OBJECT_DIRECTORY is /foo/bar,
then git rev-parse --git-path objects/abc returns /foo/bar/abc.

  --show-cdup::
 When the command is invoked from a subdirectory, show the
 path of the top-level directory relative to the current
 diff --git a/path.c b/path.c
 index ccd7228..e020530 100644
 --- a/path.c
 +++ b/path.c
 @@ -60,13 +60,59 @@ char *mksnpath(char *buf, size_t n, const char *fmt, ...)
 return cleanup_path(buf);
  }

  static void do_git_path(struct strbuf *buf, const char *fmt, va_list args)
  {
 const char *git_dir = get_git_dir();
 +   int gitdir_len;
 strbuf_addstr(buf, git_dir);

Maybe simplify by dropping git_dir and invoking strbuf_addstr(buf,
get_git_dir())?

 if (buf-len  !is_dir_sep(buf-buf[buf-len - 1]))
 strbuf_addch(buf, '/');
 +   gitdir_len = buf-len;
 strbuf_vaddf(buf, fmt, args);
 +   adjust_git_path(buf, gitdir_len);
 strbuf_cleanup_path(buf);
  }

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 05/27] Make git_path() aware of file relocation in $GIT_DIR

2014-03-01 Thread Nguyễn Thái Ngọc Duy
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.

git rev-parse --git-path is the wrapper for script use.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 Documentation/git-rev-parse.txt |  5 +
 builtin/rev-parse.c |  7 +++
 cache.h |  1 +
 environment.c   |  9 ++--
 path.c  | 46 +
 t/t0060-path-utils.sh   | 19 +
 6 files changed, 85 insertions(+), 2 deletions(-)

diff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt
index 0d2cdcd..33e4e90 100644
--- a/Documentation/git-rev-parse.txt
+++ b/Documentation/git-rev-parse.txt
@@ -232,6 +232,11 @@ print a message to stderr and exit with nonzero status.
repository.  If path is a gitfile then the resolved path
to the real repository is printed.
 
+--git-path path::
+   Resolve $GIT_DIR/path and takes other path relocation
+   variables such as $GIT_OBJECT_DIRECTORY,
+   $GIT_INDEX_FILE... into account.
+
 --show-cdup::
When the command is invoked from a subdirectory, show the
path of the top-level directory relative to the current
diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c
index aaeb611..e50bc65 100644
--- a/builtin/rev-parse.c
+++ b/builtin/rev-parse.c
@@ -518,6 +518,13 @@ int cmd_rev_parse(int argc, const char **argv, const char 
*prefix)
for (i = 1; i  argc; i++) {
const char *arg = argv[i];
 
+   if (!strcmp(arg, --git-path)) {
+   if (!argv[i + 1])
+   die(--git-path requires an argument);
+   puts(git_path(%s, argv[i + 1]));
+   i++;
+   continue;
+   }
if (as_is) {
if (show_file(arg, output_prefix)  as_is  2)
verify_filename(prefix, arg, 0);
diff --git a/cache.h b/cache.h
index 8d3697e..6c08e4a 100644
--- a/cache.h
+++ b/cache.h
@@ -585,6 +585,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 4a3437d..f513479 100644
--- a/environment.c
+++ b/environment.c
@@ -82,6 +82,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.
@@ -137,15 +138,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 ccd7228..e020530 100644
--- a/path.c
+++ b/path.c
@@ -60,13 +60,59 @@ 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');
+}
+
+/* $buf =~ m|$dir/+$file| but without regex */
+static int is_dir_file(const char *buf, const char *dir, const char *file)
+{
+   int len = strlen(dir);
+   if (strncmp(buf, dir, len) || !is_dir_sep(buf[len]))
+   return 0;
+   while (is_dir_sep(buf[len]))
+   len++;
+   return