_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 <junkio@cox.net>
This commit is contained in:
parent
89815cab95
commit
30ca07a249
@ -315,6 +315,14 @@ 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
|
||||
|
@ -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");
|
||||
}
|
||||
|
||||
|
@ -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");
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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");
|
||||
}
|
||||
|
||||
|
@ -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");
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
5
cache.h
5
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);
|
||||
|
||||
|
@ -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
|
||||
|
17
lockfile.c
17
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])
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user