* [PATCH 1/2] _GIT_INDEX_OUTPUT: allow plumbing to output to an alternative index file.
2007-04-01 6:27 ` [PATCH 0/2] Alternate index output file Junio C Hamano
@ 2007-04-01 6:29 ` Junio C Hamano
2007-04-01 6:29 ` [PATCH 2/2] git-read-tree --index-output=<file> Junio C Hamano
2007-04-01 16:08 ` [PATCH 0/2] Alternate index output file Linus Torvalds
2 siblings, 0 replies; 7+ messages in thread
From: Junio C Hamano @ 2007-04-01 6:29 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
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 perform 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 <junkio@cox.net>
---
Documentation/git.txt | 9 +++++++++
builtin-add.c | 4 ++--
builtin-apply.c | 6 +++---
builtin-checkout-index.c | 7 ++-----
builtin-mv.c | 4 ++--
builtin-read-tree.c | 4 ++--
builtin-rm.c | 4 ++--
builtin-update-index.c | 4 ++--
builtin-write-tree.c | 2 +-
cache.h | 5 +++++
git-commit.sh | 4 ++--
lockfile.c | 17 +++++++++++++++++
merge-recursive.c | 4 ++--
13 files changed, 51 insertions(+), 23 deletions(-)
diff --git a/Documentation/git.txt b/Documentation/git.txt
index dceacfa..bc025d6 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -311,6 +311,15 @@ 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 the usual
+ `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. Do not use it.
+
'GIT_OBJECT_DIRECTORY'::
If the object storage directory is specified via this
environment variable then the sha1 directories are created
diff --git a/builtin-add.c b/builtin-add.c
index 9fcf514..54422d8 100644
--- a/builtin-add.c
+++ b/builtin-add.c
@@ -133,7 +133,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
git_config(git_add_config);
- newfd = hold_lock_file_for_update(&lock_file, get_index_file(), 1);
+ newfd = hold_locked_index(&lock_file, 1);
for (i = 1; i < argc; i++) {
const char *arg = argv[i];
@@ -209,7 +209,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
if (active_cache_changed) {
if (write_cache(newfd, active_cache, active_nr) ||
- close(newfd) || commit_lock_file(&lock_file))
+ close(newfd) || commit_locked_index(&lock_file))
die("Unable to write new index file");
}
diff --git a/builtin-apply.c b/builtin-apply.c
index 27a182b..12011c1 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -2664,8 +2664,8 @@ static int apply_patch(int fd, const char *filename, int inaccurate_eof)
write_index = check_index && apply;
if (write_index && newfd < 0)
- newfd = hold_lock_file_for_update(&lock_file,
- get_index_file(), 1);
+ newfd = hold_locked_index(&lock_file, 1);
+
if (check_index) {
if (read_cache() < 0)
die("unable to read index file");
@@ -2872,7 +2872,7 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix)
if (write_index) {
if (write_cache(newfd, active_cache, active_nr) ||
- close(newfd) || commit_lock_file(&lock_file))
+ close(newfd) || commit_locked_index(&lock_file))
die("Unable to write new index file");
}
diff --git a/builtin-checkout-index.c b/builtin-checkout-index.c
index afe4b0e..8460f97 100644
--- a/builtin-checkout-index.c
+++ b/builtin-checkout-index.c
@@ -202,10 +202,7 @@ int cmd_checkout_index(int argc, const char **argv, const char *prefix)
if (!strcmp(arg, "-u") || !strcmp(arg, "--index")) {
state.refresh_cache = 1;
if (newfd < 0)
- newfd = hold_lock_file_for_update
- (&lock_file, get_index_file(), 1);
- if (newfd < 0)
- die("cannot open index.lock file.");
+ newfd = hold_locked_index(&lock_file, 1);
continue;
}
if (!strcmp(arg, "-z")) {
@@ -302,7 +299,7 @@ int cmd_checkout_index(int argc, const char **argv, const char *prefix)
if (0 <= newfd &&
(write_cache(newfd, active_cache, active_nr) ||
- close(newfd) || commit_lock_file(&lock_file)))
+ close(newfd) || commit_locked_index(&lock_file)))
die("Unable to write new index file");
return 0;
}
diff --git a/builtin-mv.c b/builtin-mv.c
index 737af35..820aca1 100644
--- a/builtin-mv.c
+++ b/builtin-mv.c
@@ -77,7 +77,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
git_config(git_default_config);
- newfd = hold_lock_file_for_update(&lock_file, get_index_file(), 1);
+ newfd = hold_locked_index(&lock_file, 1);
if (read_cache() < 0)
die("index file corrupt");
@@ -285,7 +285,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
if (active_cache_changed) {
if (write_cache(newfd, active_cache, active_nr) ||
close(newfd) ||
- commit_lock_file(&lock_file))
+ commit_locked_index(&lock_file))
die("Unable to write new index file");
}
}
diff --git a/builtin-read-tree.c b/builtin-read-tree.c
index 793eae0..87048f8 100644
--- a/builtin-read-tree.c
+++ b/builtin-read-tree.c
@@ -100,7 +100,7 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
setup_git_directory();
git_config(git_default_config);
- newfd = hold_lock_file_for_update(&lock_file, get_index_file(), 1);
+ newfd = hold_locked_index(&lock_file, 1);
git_config(git_default_config);
@@ -267,7 +267,7 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
}
if (write_cache(newfd, active_cache, active_nr) ||
- close(newfd) || commit_lock_file(&lock_file))
+ close(newfd) || commit_locked_index(&lock_file))
die("unable to write new index file");
return 0;
}
diff --git a/builtin-rm.c b/builtin-rm.c
index bf42003..8a0738f 100644
--- a/builtin-rm.c
+++ b/builtin-rm.c
@@ -110,7 +110,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
git_config(git_default_config);
- newfd = hold_lock_file_for_update(&lock_file, get_index_file(), 1);
+ newfd = hold_locked_index(&lock_file, 1);
if (read_cache() < 0)
die("index file corrupt");
@@ -220,7 +220,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
if (active_cache_changed) {
if (write_cache(newfd, active_cache, active_nr) ||
- close(newfd) || commit_lock_file(&lock_file))
+ close(newfd) || commit_locked_index(&lock_file))
die("Unable to write new index file");
}
diff --git a/builtin-update-index.c b/builtin-update-index.c
index 71cef63..84993d7 100644
--- a/builtin-update-index.c
+++ b/builtin-update-index.c
@@ -495,7 +495,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
/* We can't free this memory, it becomes part of a linked list parsed atexit() */
lock_file = xcalloc(1, sizeof(struct lock_file));
- newfd = hold_lock_file_for_update(lock_file, get_index_file(), 0);
+ newfd = hold_locked_index(lock_file, 0);
if (newfd < 0)
lock_error = errno;
@@ -661,7 +661,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
get_index_file(), strerror(lock_error));
}
if (write_cache(newfd, active_cache, active_nr) ||
- close(newfd) || commit_lock_file(lock_file))
+ close(newfd) || commit_locked_index(lock_file))
die("Unable to write new index file");
}
diff --git a/builtin-write-tree.c b/builtin-write-tree.c
index 90fc1cf..c88bbd1 100644
--- a/builtin-write-tree.c
+++ b/builtin-write-tree.c
@@ -18,7 +18,7 @@ int write_tree(unsigned char *sha1, int missing_ok, const char *prefix)
/* We can't free this memory, it becomes part of a linked list parsed atexit() */
struct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file));
- newfd = hold_lock_file_for_update(lock_file, get_index_file(), 0);
+ newfd = hold_locked_index(lock_file, 1);
entries = read_cache();
if (entries < 0)
diff --git a/cache.h b/cache.h
index 384b260..59a05c1 100644
--- a/cache.h
+++ b/cache.h
@@ -147,6 +147,7 @@ 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"
@@ -212,6 +213,10 @@ struct lock_file {
};
extern int hold_lock_file_for_update(struct lock_file *, const char *path, int);
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 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 292cf96..20c0dc8 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
diff --git a/lockfile.c b/lockfile.c
index 4824f4d..2023ebb 100644
--- a/lockfile.c
+++ b/lockfile.c
@@ -65,6 +65,23 @@ int commit_lock_file(struct lock_file *lk)
return i;
}
+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);
+}
+
+int commit_locked_index(struct lock_file *lk)
+{
+ char *output = getenv(INDEX_OUTPUT_ENVIRONMENT);
+ if (output && *output) {
+ int result = rename(lk->filename, output);
+ lk->filename[0] = 0;
+ return result;
+ }
+ else
+ return commit_lock_file(lk);
+}
+
void rollback_lock_file(struct lock_file *lk)
{
if (lk->filename[0])
diff --git a/merge-recursive.c b/merge-recursive.c
index e1aebd7..f46aaae 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -1378,7 +1378,7 @@ int main(int argc, char *argv[])
if (show(3))
printf("Merging %s with %s\n", branch1, branch2);
- index_fd = hold_lock_file_for_update(lock, get_index_file(), 1);
+ index_fd = hold_locked_index(lock, 1);
for (i = 0; i < bases_count; i++) {
struct commit *ancestor = get_ref(bases[i]);
@@ -1388,7 +1388,7 @@ int main(int argc, char *argv[])
if (active_cache_changed &&
(write_cache(index_fd, active_cache, active_nr) ||
- close(index_fd) || commit_lock_file(lock)))
+ close(index_fd) || commit_locked_index(lock)))
die ("unable to write %s", get_index_file());
return clean ? 0: 1;
--
1.5.1.rc3.26.g4f01
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH 2/2] git-read-tree --index-output=<file>
2007-04-01 6:27 ` [PATCH 0/2] Alternate index output file Junio C Hamano
2007-04-01 6:29 ` [PATCH 1/2] _GIT_INDEX_OUTPUT: allow plumbing to output to an alternative index file Junio C Hamano
@ 2007-04-01 6:29 ` Junio C Hamano
2007-04-01 16:08 ` [PATCH 0/2] Alternate index output file Linus Torvalds
2 siblings, 0 replies; 7+ messages in thread
From: Junio C Hamano @ 2007-04-01 6:29 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
This corrects the interface mistake of the previous one, and
give a command line parameter to the only plumbing command that
currently needs it, "read-tree".
We can add the set_alternate_index_output() to other plumbing
commands that update the index if/when needed.
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
Documentation/git-read-tree.txt | 14 +++++++++++++-
Documentation/git.txt | 9 ---------
builtin-read-tree.c | 7 ++++++-
cache.h | 2 +-
git-commit.sh | 4 ++--
lockfile.c | 11 ++++++++---
6 files changed, 30 insertions(+), 17 deletions(-)
diff --git a/Documentation/git-read-tree.txt b/Documentation/git-read-tree.txt
index 0ff2890..69f2223 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' (<tree-ish> | [[-m [--aggressive] | --reset | --prefix=<prefix>] [-u | -i]] [--exclude-per-directory=<gitignore>] <tree-ish1> [<tree-ish2> [<tree-ish3>]])
+'git-read-tree' (<tree-ish> | [[-m [--aggressive] | --reset | --prefix=<prefix>] [-u | -i]] [--exclude-per-directory=<gitignore>] [--index-output=<file>] <tree-ish1> [<tree-ish2> [<tree-ish3>]])
DESCRIPTION
@@ -86,6 +86,18 @@ OPTIONS
file (usually '.gitignore') and allows such an untracked
but explicitly ignored file to be overwritten.
+--index-output=<file>::
+ Instead of writing the results out to `$GIT_INDEX_FILE`,
+ place the resulting index to the named file. While the
+ command is operating, the original index file is locked
+ with the same mechanism as usual. The file must be
+ 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 in the same filesystem as the index
+ file itself, and you need write permission to the
+ directory the index file and index output file is
+ located in.
+
<tree-ish#>::
The id of the tree object(s) to be read/merged.
diff --git a/Documentation/git.txt b/Documentation/git.txt
index bc025d6..dceacfa 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -311,15 +311,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 the usual
- `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. Do not use it.
-
'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 87048f8..213bd93 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 (<sha> | [[-m [--aggressive] | --reset | --prefix=<prefix>] [-u | -i]] [--exclude-per-directory=<gitignore>] <sha1> [<sha2> [<sha3>]])";
+static const char read_tree_usage[] = "git-read-tree (<sha> | [[-m [--aggressive] | --reset | --prefix=<prefix>] [-u | -i]] [--exclude-per-directory=<gitignore>] [--index-output=<file>] <sha1> [<sha2> [<sha3>]])";
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=<subdirectory>/" 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 59a05c1..592331f 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 20c0dc8..9e0959a 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 2023ebb..bed6b21 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;
}
--
1.5.1.rc3.26.g4f01
^ permalink raw reply related [flat|nested] 7+ messages in thread