Compared to the previous round this round introduces a gentle flag for refresh_and_write_{index,cache}, which should make this function suitable for use in the Dscho's builtin-add-i series. The latter will have to be I have also pushed this to https://github.com/tgummerer/git tg/stash-refresh-index Range-diff below: 1: 7cc9f5fff4 ! 1: 2a7bebb20f factor out refresh_and_write_cache function @@ Commit message about failing to write the index. However for other callers we're going to convert in subsequent patches we will need this distinction. + Helped-by: Martin Ågren <martin.agren@xxxxxxxxx> + Helped-by: Johannes Schindelin <Johannes.Schindelin@xxxxxx> Signed-off-by: Thomas Gummerer <t.gummerer@xxxxxxxxx> ## builtin/am.c ## @@ builtin/am.c: static void am_run(struct am_state *state, int resume) unlink(am_path(state, "dirtyindex")); - refresh_and_write_cache(); -+ if (refresh_and_write_cache(REFRESH_QUIET, 0) < 0) ++ if (refresh_and_write_cache(REFRESH_QUIET, 0, 0) < 0) + die(_("unable to write index file")); if (repo_index_has_changes(the_repository, NULL, &sb)) { @@ cache.h: extern struct index_state the_index; #define add_file_to_cache(path, flags) add_file_to_index(&the_index, (path), (flags)) #define chmod_cache_entry(ce, flip) chmod_index_entry(&the_index, (ce), (flip)) #define refresh_cache(flags) refresh_index(&the_index, (flags), NULL, NULL, NULL) -+#define refresh_and_write_cache(refresh_flags, write_flags) repo_refresh_and_write_index(the_repository, (refresh_flags), (write_flags), NULL, NULL, NULL) ++#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) #define ce_match_stat(ce, st, options) ie_match_stat(&the_index, (ce), (st), (options)) #define ce_modified(ce, st, options) ie_modified(&the_index, (ce), (st), (options)) #define cache_dir_exists(name, namelen) index_dir_exists(&the_index, (name), (namelen)) @@ cache.h: void fill_stat_cache_info(struct index_state *istate, struct cache_entr + * 'COMMIT_LOCK | write_flags' is passed to 'write_locked_index()', so + * the lockfile is always either committed or rolled back. + * ++ * If 'gentle' is passed, errors locking the index are ignored. ++ * + * Return 1 if refreshing the index returns an error, -1 if writing + * the index to disk fails, 0 on success. + * -+ * Note that if refreshing the index returns an error, we don't write -+ * the result to disk. ++ * Note that if refreshing the index returns an error, we still write ++ * out the result (unless locking failed). + */ -+int repo_refresh_and_write_index(struct repository*, unsigned int refresh_flags, unsigned int write_flags, const struct pathspec *, char *seen, const char *header_msg); ++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); + struct cache_entry *refresh_cache_entry(struct index_state *, struct cache_entry *, unsigned int); @@ read-cache.c: static void show_file(const char * fmt, const char * name, int in_ printf(fmt, name); } -+int repo_refresh_and_write_index(struct repository *repo, ++int repo_refresh_and_write_index(struct repository *repo, + unsigned int refresh_flags, + unsigned int write_flags, ++ int gentle, + const struct pathspec *pathspec, + char *seen, const char *header_msg) +{ + struct lock_file lock_file = LOCK_INIT; ++ int fd, ret = 0; + -+ repo_hold_locked_index(repo, &lock_file, LOCK_DIE_ON_ERROR); -+ if (refresh_index(repo->index, refresh_flags, pathspec, seen, header_msg)) { -+ rollback_lock_file(&lock_file); -+ return 1; -+ } -+ if (write_locked_index(repo->index, &lock_file, COMMIT_LOCK | write_flags)) ++ fd = repo_hold_locked_index(repo, &lock_file, 0); ++ if (!gentle && fd < 0) + return -1; -+ return 0; ++ if (refresh_index(repo->index, refresh_flags, pathspec, seen, header_msg)) ++ ret = 1; ++ if (0 <= fd && write_locked_index(repo->index, &lock_file, COMMIT_LOCK | write_flags)) ++ ret = -1; ++ rollback_lock_file(&lock_file); ++ return ret; +} + + 2: 0367d938b1 ! 2: 555c982eae merge: use refresh_and_write_cache @@ builtin/merge.c: static int try_merge_strategy(const char *strategy, struct comm - refresh_cache(REFRESH_QUIET); - if (write_locked_index(&the_index, &lock, - COMMIT_LOCK | SKIP_IF_UNCHANGED)) -+ if (refresh_and_write_cache(REFRESH_QUIET, SKIP_IF_UNCHANGED) < 0) ++ if (refresh_and_write_cache(REFRESH_QUIET, SKIP_IF_UNCHANGED, 0) < 0) return error(_("Unable to write index.")); if (!strcmp(strategy, "recursive") || !strcmp(strategy, "subtree")) { @@ builtin/merge.c: static int merge_trivial(struct commit *head, struct commit_lis - refresh_cache(REFRESH_QUIET); - if (write_locked_index(&the_index, &lock, - COMMIT_LOCK | SKIP_IF_UNCHANGED)) -+ if (refresh_and_write_cache(REFRESH_QUIET, SKIP_IF_UNCHANGED) < 0) ++ if (refresh_and_write_cache(REFRESH_QUIET, SKIP_IF_UNCHANGED, 0) < 0) return error(_("Unable to write index.")); write_tree_trivial(&result_tree); 3: 8ed3df9fec ! 3: cf74fe6053 stash: make sure to write refreshed cache @@ builtin/stash.c: static int do_apply_stash(const char *prefix, struct stash_info read_cache_preload(NULL); - if (refresh_cache(REFRESH_QUIET)) -+ if (refresh_and_write_cache(REFRESH_QUIET, 0)) ++ if (refresh_and_write_cache(REFRESH_QUIET, 0, 0)) return -1; if (write_cache_as_tree(&c_tree, 0, NULL)) @@ builtin/stash.c: static int do_apply_stash(const char *prefix, struct stash_info if (quiet) { - if (refresh_cache(REFRESH_QUIET)) -+ if (refresh_and_write_cache(REFRESH_QUIET, 0)) ++ if (refresh_and_write_cache(REFRESH_QUIET, 0, 0)) warning("could not refresh index"); } else { struct child_process cp = CHILD_PROCESS_INIT; @@ builtin/stash.c: static int do_create_stash(const struct pathspec *ps, struct st read_cache_preload(NULL); - refresh_cache(REFRESH_QUIET); -+ if (refresh_and_write_cache(REFRESH_QUIET, 0) < 0) { ++ if (refresh_and_write_cache(REFRESH_QUIET, 0, 0) < 0) { + ret = -1; + goto done; + } @@ builtin/stash.c: static int do_push_stash(const struct pathspec *ps, const char } - if (refresh_cache(REFRESH_QUIET)) { -+ if (refresh_and_write_cache(REFRESH_QUIET, 0)) { ++ if (refresh_and_write_cache(REFRESH_QUIET, 0, 0)) { ret = -1; goto done; } Thomas Gummerer (3): factor out refresh_and_write_cache function merge: use refresh_and_write_cache stash: make sure to write refreshed cache builtin/am.c | 16 ++-------------- builtin/merge.c | 13 +++---------- builtin/stash.c | 11 +++++++---- cache.h | 18 ++++++++++++++++++ read-cache.c | 21 +++++++++++++++++++++ t/t3903-stash.sh | 16 ++++++++++++++++ 6 files changed, 67 insertions(+), 28 deletions(-) -- 2.23.0.rc2.194.ge5444969c9