Skip to content

Commit ba2d451

Browse files
committed
Merge branch 'tg/stash-refresh-index'
"git stash" learned to write refreshed index back to disk. * tg/stash-refresh-index: stash: make sure to write refreshed cache merge: use refresh_and_write_cache factor out refresh_and_write_cache function
2 parents c90b652 + 34933d0 commit ba2d451

File tree

6 files changed

+67
-28
lines changed

6 files changed

+67
-28
lines changed

builtin/am.c

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1071,19 +1071,6 @@ static const char *msgnum(const struct am_state *state)
10711071
return sb.buf;
10721072
}
10731073

1074-
/**
1075-
* Refresh and write index.
1076-
*/
1077-
static void refresh_and_write_cache(void)
1078-
{
1079-
struct lock_file lock_file = LOCK_INIT;
1080-
1081-
hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);
1082-
refresh_cache(REFRESH_QUIET);
1083-
if (write_locked_index(&the_index, &lock_file, COMMIT_LOCK))
1084-
die(_("unable to write index file"));
1085-
}
1086-
10871074
/**
10881075
* Dies with a user-friendly message on how to proceed after resolving the
10891076
* problem. This message can be overridden with state->resolvemsg.
@@ -1705,7 +1692,8 @@ static void am_run(struct am_state *state, int resume)
17051692

17061693
unlink(am_path(state, "dirtyindex"));
17071694

1708-
refresh_and_write_cache();
1695+
if (refresh_and_write_cache(REFRESH_QUIET, 0, 0) < 0)
1696+
die(_("unable to write index file"));
17091697

17101698
if (repo_index_has_changes(the_repository, NULL, &sb)) {
17111699
write_state_bool(state, "dirtyindex", 1);

builtin/merge.c

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -688,16 +688,13 @@ static int try_merge_strategy(const char *strategy, struct commit_list *common,
688688
struct commit_list *remoteheads,
689689
struct commit *head)
690690
{
691-
struct lock_file lock = LOCK_INIT;
692691
const char *head_arg = "HEAD";
693692

694-
hold_locked_index(&lock, LOCK_DIE_ON_ERROR);
695-
refresh_cache(REFRESH_QUIET);
696-
if (write_locked_index(&the_index, &lock,
697-
COMMIT_LOCK | SKIP_IF_UNCHANGED))
693+
if (refresh_and_write_cache(REFRESH_QUIET, SKIP_IF_UNCHANGED, 0) < 0)
698694
return error(_("Unable to write index."));
699695

700696
if (!strcmp(strategy, "recursive") || !strcmp(strategy, "subtree")) {
697+
struct lock_file lock = LOCK_INIT;
701698
int clean, x;
702699
struct commit *result;
703700
struct commit_list *reversed = NULL;
@@ -872,12 +869,8 @@ static int merge_trivial(struct commit *head, struct commit_list *remoteheads)
872869
{
873870
struct object_id result_tree, result_commit;
874871
struct commit_list *parents, **pptr = &parents;
875-
struct lock_file lock = LOCK_INIT;
876872

877-
hold_locked_index(&lock, LOCK_DIE_ON_ERROR);
878-
refresh_cache(REFRESH_QUIET);
879-
if (write_locked_index(&the_index, &lock,
880-
COMMIT_LOCK | SKIP_IF_UNCHANGED))
873+
if (refresh_and_write_cache(REFRESH_QUIET, SKIP_IF_UNCHANGED, 0) < 0)
881874
return error(_("Unable to write index."));
882875

883876
write_tree_trivial(&result_tree);

builtin/stash.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ static int do_apply_stash(const char *prefix, struct stash_info *info,
396396
const struct object_id *bases[1];
397397

398398
read_cache_preload(NULL);
399-
if (refresh_cache(REFRESH_QUIET))
399+
if (refresh_and_write_cache(REFRESH_QUIET, 0, 0))
400400
return -1;
401401

402402
if (write_cache_as_tree(&c_tree, 0, NULL))
@@ -485,7 +485,7 @@ static int do_apply_stash(const char *prefix, struct stash_info *info,
485485
}
486486

487487
if (quiet) {
488-
if (refresh_cache(REFRESH_QUIET))
488+
if (refresh_and_write_cache(REFRESH_QUIET, 0, 0))
489489
warning("could not refresh index");
490490
} else {
491491
struct child_process cp = CHILD_PROCESS_INIT;
@@ -1129,7 +1129,10 @@ static int do_create_stash(const struct pathspec *ps, struct strbuf *stash_msg_b
11291129
prepare_fallback_ident("git stash", "git@stash");
11301130

11311131
read_cache_preload(NULL);
1132-
refresh_cache(REFRESH_QUIET);
1132+
if (refresh_and_write_cache(REFRESH_QUIET, 0, 0) < 0) {
1133+
ret = -1;
1134+
goto done;
1135+
}
11331136

11341137
if (get_oid("HEAD", &info->b_commit)) {
11351138
if (!quiet)
@@ -1290,7 +1293,7 @@ static int do_push_stash(const struct pathspec *ps, const char *stash_msg, int q
12901293
free(ps_matched);
12911294
}
12921295

1293-
if (refresh_cache(REFRESH_QUIET)) {
1296+
if (refresh_and_write_cache(REFRESH_QUIET, 0, 0)) {
12941297
ret = -1;
12951298
goto done;
12961299
}

cache.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,7 @@ extern struct index_state the_index;
414414
#define add_file_to_cache(path, flags) add_file_to_index(&the_index, (path), (flags))
415415
#define chmod_cache_entry(ce, flip) chmod_index_entry(&the_index, (ce), (flip))
416416
#define refresh_cache(flags) refresh_index(&the_index, (flags), NULL, NULL, NULL)
417+
#define refresh_and_write_cache(refresh_flags, write_flags, gentle) repo_refresh_and_write_index(the_repository, (refresh_flags), (write_flags), (gentle), NULL, NULL, NULL)
417418
#define ce_match_stat(ce, st, options) ie_match_stat(&the_index, (ce), (st), (options))
418419
#define ce_modified(ce, st, options) ie_modified(&the_index, (ce), (st), (options))
419420
#define cache_dir_exists(name, namelen) index_dir_exists(&the_index, (name), (namelen))
@@ -834,6 +835,23 @@ void fill_stat_cache_info(struct index_state *istate, struct cache_entry *ce, st
834835
#define REFRESH_IN_PORCELAIN 0x0020 /* user friendly output, not "needs update" */
835836
#define REFRESH_PROGRESS 0x0040 /* show progress bar if stderr is tty */
836837
int refresh_index(struct index_state *, unsigned int flags, const struct pathspec *pathspec, char *seen, const char *header_msg);
838+
/*
839+
* Refresh the index and write it to disk.
840+
*
841+
* 'refresh_flags' is passed directly to 'refresh_index()', while
842+
* 'COMMIT_LOCK | write_flags' is passed to 'write_locked_index()', so
843+
* the lockfile is always either committed or rolled back.
844+
*
845+
* If 'gentle' is passed, errors locking the index are ignored.
846+
*
847+
* Return 1 if refreshing the index returns an error, -1 if writing
848+
* the index to disk fails, 0 on success.
849+
*
850+
* Note that if refreshing the index returns an error, we still write
851+
* out the index (unless locking fails).
852+
*/
853+
int repo_refresh_and_write_index(struct repository*, unsigned int refresh_flags, unsigned int write_flags, int gentle, const struct pathspec *, char *seen, const char *header_msg);
854+
837855
struct cache_entry *refresh_cache_entry(struct index_state *, struct cache_entry *, unsigned int);
838856

839857
void set_alternate_index_output(const char *);

read-cache.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1472,6 +1472,27 @@ static void show_file(const char * fmt, const char * name, int in_porcelain,
14721472
printf(fmt, name);
14731473
}
14741474

1475+
int repo_refresh_and_write_index(struct repository *repo,
1476+
unsigned int refresh_flags,
1477+
unsigned int write_flags,
1478+
int gentle,
1479+
const struct pathspec *pathspec,
1480+
char *seen, const char *header_msg)
1481+
{
1482+
struct lock_file lock_file = LOCK_INIT;
1483+
int fd, ret = 0;
1484+
1485+
fd = repo_hold_locked_index(repo, &lock_file, 0);
1486+
if (!gentle && fd < 0)
1487+
return -1;
1488+
if (refresh_index(repo->index, refresh_flags, pathspec, seen, header_msg))
1489+
ret = 1;
1490+
if (0 <= fd && write_locked_index(repo->index, &lock_file, COMMIT_LOCK | write_flags))
1491+
ret = -1;
1492+
return ret;
1493+
}
1494+
1495+
14751496
int refresh_index(struct index_state *istate, unsigned int flags,
14761497
const struct pathspec *pathspec,
14771498
char *seen, const char *header_msg)

t/t3903-stash.sh

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1253,4 +1253,20 @@ test_expect_success 'stash --keep-index with file deleted in index does not resu
12531253
test_path_is_missing to-remove
12541254
'
12551255

1256+
test_expect_success 'stash apply should succeed with unmodified file' '
1257+
echo base >file &&
1258+
git add file &&
1259+
git commit -m base &&
1260+
1261+
# now stash a modification
1262+
echo modified >file &&
1263+
git stash &&
1264+
1265+
# make the file stat dirty
1266+
cp file other &&
1267+
mv other file &&
1268+
1269+
git stash apply
1270+
'
1271+
12561272
test_done

0 commit comments

Comments
 (0)