Skip to content

Commit b7099a0

Browse files
martinvonzgitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 352f58a commit b7099a0

File tree

1 file changed

+10
-11
lines changed

1 file changed

+10
-11
lines changed

builtin/reset.c

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,12 @@ static inline int is_merge(void)
3838
return !access(git_path("MERGE_HEAD"), F_OK);
3939
}
4040

41-
static int reset_index_file(const unsigned char *sha1, int reset_type, int quiet)
41+
static int reset_index(const unsigned char *sha1, int reset_type, int quiet)
4242
{
4343
int nr = 1;
44-
int newfd;
4544
struct tree_desc desc[2];
4645
struct tree *tree;
4746
struct unpack_trees_options opts;
48-
struct lock_file *lock = xcalloc(1, sizeof(struct lock_file));
4947

5048
memset(&opts, 0, sizeof(opts));
5149
opts.head_idx = 1;
@@ -67,8 +65,6 @@ static int reset_index_file(const unsigned char *sha1, int reset_type, int quiet
6765
opts.reset = 1;
6866
}
6967

70-
newfd = hold_locked_index(lock, 1);
71-
7268
read_cache_unmerged();
7369

7470
if (reset_type == KEEP) {
@@ -91,10 +87,6 @@ static int reset_index_file(const unsigned char *sha1, int reset_type, int quiet
9187
prime_cache_tree(&active_cache_tree, tree);
9288
}
9389

94-
if (write_cache(newfd, active_cache, active_nr) ||
95-
commit_locked_index(lock))
96-
return error(_("Could not write new index file."));
97-
9890
return 0;
9991
}
10092

@@ -341,9 +333,16 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
341333
die_if_unmerged_cache(reset_type);
342334

343335
if (reset_type != SOFT) {
344-
int err = reset_index_file(sha1, reset_type, quiet);
336+
struct lock_file *lock = xcalloc(1, sizeof(struct lock_file));
337+
int newfd = hold_locked_index(lock, 1);
338+
int err = reset_index(sha1, reset_type, quiet);
345339
if (reset_type == KEEP && !err)
346-
err = reset_index_file(sha1, MIXED, quiet);
340+
err = reset_index(sha1, MIXED, quiet);
341+
if (!err &&
342+
(write_cache(newfd, active_cache, active_nr) ||
343+
commit_locked_index(lock))) {
344+
err = error(_("Could not write new index file."));
345+
}
347346
if (err)
348347
die(_("Could not reset index file to revision '%s'."), rev);
349348
}

0 commit comments

Comments
 (0)