From 30ca07a249744e57163c02250fca420cea364299 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sat, 31 Mar 2007 23:09:02 -0700 Subject: _GIT_INDEX_OUTPUT: allow plumbing to output to an alternative index file. When defined, this allows plumbing commands that update the index (add, apply, checkout-index, merge-recursive, mv, read-tree, rm, update-index, and write-tree) to write their resulting index to an alternative index file while holding a lock to the original index file. With this, git-commit that jumps the index does not have to make an extra copy of the index file, and more importantly, it can do the update while holding the lock on the index. However, I think the interface to let an environment variable specify the output is a mistake, as shown in the documentation. If a curious user has the environment variable set to something other than the file GIT_INDEX_FILE points at, almost everything will break. This should instead be a command line parameter to tell these plumbing commands to write the result in the named file, to prevent stupid mistakes. Signed-off-by: Junio C Hamano --- git-commit.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'git-commit.sh') diff --git a/git-commit.sh b/git-commit.sh index 292cf967e3..20c0dc806f 100755 --- a/git-commit.sh +++ b/git-commit.sh @@ -370,8 +370,8 @@ t,) # the same way. if test -z "$initial_commit" then - cp "$THIS_INDEX" "$TMP_INDEX" - GIT_INDEX_FILE="$TMP_INDEX" git-read-tree -i -m HEAD + _GIT_INDEX_OUTPUT="$TMP_INDEX" \ + GIT_INDEX_FILE="$THIS_INDEX" git-read-tree -i -m HEAD else rm -f "$TMP_INDEX" fi || exit -- cgit v1.3 From 5e7f56ac33f7a5583f9fa4e0b6088709fea7a6f8 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sat, 31 Mar 2007 23:27:41 -0700 Subject: git-read-tree --index-output= This corrects the interface mistake of the previous one, and gives a command line parameter to the only plumbing command that currently needs it: "git-read-tree". We can add the calls to set_alternate_index_output() to other plumbing commands that update the index if/when needed. Signed-off-by: Junio C Hamano --- Documentation/git-read-tree.txt | 14 +++++++++++++- Documentation/git.txt | 8 -------- builtin-read-tree.c | 7 ++++++- cache.h | 2 +- git-commit.sh | 4 ++-- lockfile.c | 11 ++++++++--- 6 files changed, 30 insertions(+), 16 deletions(-) (limited to 'git-commit.sh') diff --git a/Documentation/git-read-tree.txt b/Documentation/git-read-tree.txt index 0ff2890c7f..019c8bef7a 100644 --- a/Documentation/git-read-tree.txt +++ b/Documentation/git-read-tree.txt @@ -8,7 +8,7 @@ git-read-tree - Reads tree information into the index SYNOPSIS -------- -'git-read-tree' ( | [[-m [--aggressive] | --reset | --prefix=] [-u | -i]] [--exclude-per-directory=] [ []]) +'git-read-tree' ( | [[-m [--aggressive] | --reset | --prefix=] [-u | -i]] [--exclude-per-directory=] [--index-output=] [ []]) DESCRIPTION @@ -86,6 +86,18 @@ OPTIONS file (usually '.gitignore') and allows such an untracked but explicitly ignored file to be overwritten. +--index-output=:: + Instead of writing the results out to `$GIT_INDEX_FILE`, + write the resulting index in the named file. While the + command is operating, the original index file is locked + with the same mechanism as usual. The file must allow + to be rename(2)ed into from a temporary file that is + created next to the usual index file; typically this + means it needs to be on the same filesystem as the index + file itself, and you need write permission to the + directories the index file and index output file are + located in. + :: The id of the tree object(s) to be read/merged. diff --git a/Documentation/git.txt b/Documentation/git.txt index 8fa1a0a588..9defc33273 100644 --- a/Documentation/git.txt +++ b/Documentation/git.txt @@ -315,14 +315,6 @@ git so take care if using Cogito etc. index file. If not specified, the default of `$GIT_DIR/index` is used. -'_GIT_INDEX_OUTPUT':: - When this environment is defined, plumbing level - commands that update the index writes the resulting - index to this file, instead of `$GIT_INDEX_FILE` (or its - default `$GIT_DIR/index`). This is solely meant to be - used by Porcelain to drive low-level plumbing. Defining - this in user's environment is always an error. - 'GIT_OBJECT_DIRECTORY':: If the object storage directory is specified via this environment variable then the sha1 directories are created diff --git a/builtin-read-tree.c b/builtin-read-tree.c index 87048f82ee..213bd93c7f 100644 --- a/builtin-read-tree.c +++ b/builtin-read-tree.c @@ -84,7 +84,7 @@ static void prime_cache_tree(void) } -static const char read_tree_usage[] = "git-read-tree ( | [[-m [--aggressive] | --reset | --prefix=] [-u | -i]] [--exclude-per-directory=] [ []])"; +static const char read_tree_usage[] = "git-read-tree ( | [[-m [--aggressive] | --reset | --prefix=] [-u | -i]] [--exclude-per-directory=] [--index-output=] [ []])"; static struct lock_file lock_file; @@ -128,6 +128,11 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix) continue; } + if (!prefixcmp(arg, "--index-output=")) { + set_alternate_index_output(arg + 15); + continue; + } + /* "--prefix=/" means keep the current index * entries and put the entries from the tree under the * given subdirectory. diff --git a/cache.h b/cache.h index 59a05c1a45..592331f706 100644 --- a/cache.h +++ b/cache.h @@ -147,7 +147,6 @@ enum object_type { #define DEFAULT_GIT_DIR_ENVIRONMENT ".git" #define DB_ENVIRONMENT "GIT_OBJECT_DIRECTORY" #define INDEX_ENVIRONMENT "GIT_INDEX_FILE" -#define INDEX_OUTPUT_ENVIRONMENT "_GIT_INDEX_OUTPUT" #define GRAFT_ENVIRONMENT "GIT_GRAFT_FILE" #define TEMPLATE_DIR_ENVIRONMENT "GIT_TEMPLATE_DIR" #define CONFIG_ENVIRONMENT "GIT_CONFIG" @@ -216,6 +215,7 @@ extern int commit_lock_file(struct lock_file *); extern int hold_locked_index(struct lock_file *, int); extern int commit_locked_index(struct lock_file *); +extern void set_alternate_index_output(const char *); extern void rollback_lock_file(struct lock_file *); extern int delete_ref(const char *, unsigned char *sha1); diff --git a/git-commit.sh b/git-commit.sh index 20c0dc806f..9e0959aec0 100755 --- a/git-commit.sh +++ b/git-commit.sh @@ -370,8 +370,8 @@ t,) # the same way. if test -z "$initial_commit" then - _GIT_INDEX_OUTPUT="$TMP_INDEX" \ - GIT_INDEX_FILE="$THIS_INDEX" git-read-tree -i -m HEAD + GIT_INDEX_FILE="$THIS_INDEX" \ + git-read-tree --index-output="$TMP_INDEX" -i -m HEAD else rm -f "$TMP_INDEX" fi || exit diff --git a/lockfile.c b/lockfile.c index 2023ebb6ff..bed6b21daf 100644 --- a/lockfile.c +++ b/lockfile.c @@ -4,6 +4,7 @@ #include "cache.h" static struct lock_file *lock_file_list; +static const char *alternate_index_output; static void remove_lock_file(void) { @@ -70,11 +71,15 @@ int hold_locked_index(struct lock_file *lk, int die_on_error) return hold_lock_file_for_update(lk, get_index_file(), die_on_error); } +void set_alternate_index_output(const char *name) +{ + alternate_index_output = name; +} + int commit_locked_index(struct lock_file *lk) { - char *output = getenv(INDEX_OUTPUT_ENVIRONMENT); - if (output && *output) { - int result = rename(lk->filename, output); + if (alternate_index_output) { + int result = rename(lk->filename, alternate_index_output); lk->filename[0] = 0; return result; } -- cgit v1.3