summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin von Zweigbergk <martinvonz@gmail.com>2013-01-15 05:47:41 (GMT)
committerJunio C Hamano <gitster@pobox.com>2013-01-15 17:38:07 (GMT)
commitb7099a06e8ffe61a06d3e32632e832e59f23bd4d (patch)
tree2b9e45c3cb0877af2a167b785279429108ba7416
parent352f58a57ba3050adbdc2dcdcd3839e584f1431b (diff)
downloadgit-b7099a06e8ffe61a06d3e32632e832e59f23bd4d.zip
git-b7099a06e8ffe61a06d3e32632e832e59f23bd4d.tar.gz
git-b7099a06e8ffe61a06d3e32632e832e59f23bd4d.tar.bz2
reset --keep: only write index file once
"git reset --keep" calls reset_index_file() twice, first doing a two-way merge to the target revision, updating the index and worktree, and then resetting the index. After each call, we write the index file. In the unlikely event that the second call to reset_index_file() fails, the index will have been merged to the target revision, but HEAD will not be updated, leaving the user with a dirty index. By moving the locking, writing and committing out of reset_index_file() and into the caller, we can avoid writing the index twice, thereby making the sure we don't end up in the half-way reset state. As a bonus, we speed up "git reset --keep" a little on the linux-2.6 repo (best of five, warm cache): Before After real 0m0.315s 0m0.296s user 0m0.290s 0m0.280s sys 0m0.020s 0m0.010s Signed-off-by: Martin von Zweigbergk <martinvonz@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--builtin/reset.c21
1 files changed, 10 insertions, 11 deletions
diff --git a/builtin/reset.c b/builtin/reset.c
index 4e34195..7c440ad 100644
--- a/builtin/reset.c
+++ b/builtin/reset.c
@@ -38,14 +38,12 @@ static inline int is_merge(void)
return !access(git_path("MERGE_HEAD"), F_OK);
}
-static int reset_index_file(const unsigned char *sha1, int reset_type, int quiet)
+static int reset_index(const unsigned char *sha1, int reset_type, int quiet)
{
int nr = 1;
- int newfd;
struct tree_desc desc[2];
struct tree *tree;
struct unpack_trees_options opts;
- struct lock_file *lock = xcalloc(1, sizeof(struct lock_file));
memset(&opts, 0, sizeof(opts));
opts.head_idx = 1;
@@ -67,8 +65,6 @@ static int reset_index_file(const unsigned char *sha1, int reset_type, int quiet
opts.reset = 1;
}
- newfd = hold_locked_index(lock, 1);
-
read_cache_unmerged();
if (reset_type == KEEP) {
@@ -91,10 +87,6 @@ static int reset_index_file(const unsigned char *sha1, int reset_type, int quiet
prime_cache_tree(&active_cache_tree, tree);
}
- if (write_cache(newfd, active_cache, active_nr) ||
- commit_locked_index(lock))
- return error(_("Could not write new index file."));
-
return 0;
}
@@ -341,9 +333,16 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
die_if_unmerged_cache(reset_type);
if (reset_type != SOFT) {
- int err = reset_index_file(sha1, reset_type, quiet);
+ struct lock_file *lock = xcalloc(1, sizeof(struct lock_file));
+ int newfd = hold_locked_index(lock, 1);
+ int err = reset_index(sha1, reset_type, quiet);
if (reset_type == KEEP && !err)
- err = reset_index_file(sha1, MIXED, quiet);
+ err = reset_index(sha1, MIXED, quiet);
+ if (!err &&
+ (write_cache(newfd, active_cache, active_nr) ||
+ commit_locked_index(lock))) {
+ err = error(_("Could not write new index file."));
+ }
if (err)
die(_("Could not reset index file to revision '%s'."), rev);
}