summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/checkout.c2
-rw-r--r--src/diff.c23
-rw-r--r--src/index.c11
-rw-r--r--src/status.c17
-rw-r--r--src/submodule.c7
5 files changed, 42 insertions, 18 deletions
diff --git a/src/checkout.c b/src/checkout.c
index 76edc6a72..94968e378 100644
--- a/src/checkout.c
+++ b/src/checkout.c
@@ -1837,7 +1837,7 @@ static int checkout_data_init(
} else {
/* otherwise, grab and reload the index */
if ((error = git_repository_index(&data->index, data->repo)) < 0 ||
- (error = git_index_read(data->index)) < 0)
+ (error = git_index_read(data->index, false)) < 0)
goto cleanup;
/* cannot checkout if unresolved conflicts exist */
diff --git a/src/diff.c b/src/diff.c
index b1f64e6a3..d1ff04b52 100644
--- a/src/diff.c
+++ b/src/diff.c
@@ -1184,6 +1184,17 @@ int git_diff_tree_to_tree(
return error;
}
+static int diff_load_index(git_index **index, git_repository *repo)
+{
+ int error = git_repository_index__weakptr(index, repo);
+
+ /* reload the repository index when user did not pass one in */
+ if (!error && git_index_read(*index, true) < 0)
+ giterr_clear();
+
+ return error;
+}
+
int git_diff_tree_to_index(
git_diff **diff,
git_repository *repo,
@@ -1196,7 +1207,7 @@ int git_diff_tree_to_index(
assert(diff && repo);
- if (!index && (error = git_repository_index__weakptr(&index, repo)) < 0)
+ if (!index && (error = diff_load_index(&index, repo)) < 0)
return error;
if (index->ignore_case) {
@@ -1239,7 +1250,7 @@ int git_diff_index_to_workdir(
assert(diff && repo);
- if (!index && (error = git_repository_index__weakptr(&index, repo)) < 0)
+ if (!index && (error = diff_load_index(&index, repo)) < 0)
return error;
DIFF_FROM_ITERATORS(
@@ -1278,11 +1289,15 @@ int git_diff_tree_to_workdir_with_index(
{
int error = 0;
git_diff *d1 = NULL, *d2 = NULL;
+ git_index *index = NULL;
assert(diff && repo);
- if (!(error = git_diff_tree_to_index(&d1, repo, old_tree, NULL, opts)) &&
- !(error = git_diff_index_to_workdir(&d2, repo, NULL, opts)))
+ if ((error = diff_load_index(&index, repo)) < 0)
+ return error;
+
+ if (!(error = git_diff_tree_to_index(&d1, repo, old_tree, index, opts)) &&
+ !(error = git_diff_index_to_workdir(&d2, repo, index, opts)))
error = git_diff_merge(d1, d2);
git_diff_free(d2);
diff --git a/src/index.c b/src/index.c
index 5cdd40aaa..19de43d29 100644
--- a/src/index.c
+++ b/src/index.c
@@ -349,7 +349,7 @@ int git_index_open(git_index **index_out, const char *index_path)
*index_out = index;
GIT_REFCOUNT_INC(index);
- return (index_path != NULL) ? git_index_read(index) : 0;
+ return (index_path != NULL) ? git_index_read(index, false) : 0;
}
int git_index_new(git_index **out)
@@ -451,11 +451,11 @@ unsigned int git_index_caps(const git_index *index)
(index->no_symlinks ? GIT_INDEXCAP_NO_SYMLINKS : 0));
}
-int git_index_read(git_index *index)
+int git_index_read(git_index *index, int only_if_changed)
{
int error = 0, updated;
git_buf buffer = GIT_BUF_INIT;
- git_futils_filestamp stamp = {0};
+ git_futils_filestamp stamp = index->stamp;
if (!index->index_file_path)
return create_index_error(-1,
@@ -464,12 +464,13 @@ int git_index_read(git_index *index)
index->on_disk = git_path_exists(index->index_file_path);
if (!index->on_disk) {
- git_index_clear(index);
+ if (!only_if_changed)
+ git_index_clear(index);
return 0;
}
updated = git_futils_filestamp_check(&stamp, index->index_file_path);
- if (updated <= 0)
+ if (updated < 0 || (only_if_changed && !updated))
return updated;
error = git_futils_readbuffer(&buffer, index->index_file_path);
diff --git a/src/status.c b/src/status.c
index 2b84794b5..74bccf7a1 100644
--- a/src/status.c
+++ b/src/status.c
@@ -251,12 +251,17 @@ int git_status_list_new(
return error;
/* if there is no HEAD, that's okay - we'll make an empty iterator */
- if (((error = git_repository_head_tree(&head, repo)) < 0) &&
- error != GIT_ENOTFOUND && error != GIT_EUNBORNBRANCH) {
- git_index_free(index); /* release index */
- return error;
+ if ((error = git_repository_head_tree(&head, repo)) < 0) {
+ if (error != GIT_ENOTFOUND && error != GIT_EUNBORNBRANCH)
+ goto done;
+ giterr_clear();
}
+ /* refresh index from disk unless prevented */
+ if ((flags & GIT_STATUS_OPT_NO_REFRESH) == 0 &&
+ git_index_read(index, true) < 0)
+ giterr_clear();
+
status = git_status_list_alloc(index);
GITERR_CHECK_ALLOC(status);
@@ -291,7 +296,7 @@ int git_status_list_new(
if (show != GIT_STATUS_SHOW_WORKDIR_ONLY) {
if ((error = git_diff_tree_to_index(
- &status->head2idx, repo, head, NULL, &diffopt)) < 0)
+ &status->head2idx, repo, head, index, &diffopt)) < 0)
goto done;
if ((flags & GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX) != 0 &&
@@ -301,7 +306,7 @@ int git_status_list_new(
if (show != GIT_STATUS_SHOW_INDEX_ONLY) {
if ((error = git_diff_index_to_workdir(
- &status->idx2wd, repo, NULL, &diffopt)) < 0)
+ &status->idx2wd, repo, index, &diffopt)) < 0)
goto done;
if ((flags & GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR) != 0 &&
diff --git a/src/submodule.c b/src/submodule.c
index 18d80f0a9..586494fed 100644
--- a/src/submodule.c
+++ b/src/submodule.c
@@ -1527,6 +1527,7 @@ static void submodule_get_wd_status(
const git_oid *wd_oid =
(sm->flags & GIT_SUBMODULE_STATUS__WD_OID_VALID) ? &sm->wd_oid : NULL;
git_tree *sm_head = NULL;
+ git_index *index = NULL;
git_diff_options opt = GIT_DIFF_OPTIONS_INIT;
git_diff *diff;
@@ -1558,12 +1559,14 @@ static void submodule_get_wd_status(
if (ign == GIT_SUBMODULE_IGNORE_NONE)
opt.flags |= GIT_DIFF_INCLUDE_UNTRACKED;
+ (void)git_repository_index__weakptr(&index, sm_repo);
+
/* if we don't have an unborn head, check diff with index */
if (git_repository_head_tree(&sm_head, sm_repo) < 0)
giterr_clear();
else {
/* perform head to index diff on submodule */
- if (git_diff_tree_to_index(&diff, sm_repo, sm_head, NULL, &opt) < 0)
+ if (git_diff_tree_to_index(&diff, sm_repo, sm_head, index, &opt) < 0)
giterr_clear();
else {
if (git_diff_num_deltas(diff) > 0)
@@ -1576,7 +1579,7 @@ static void submodule_get_wd_status(
}
/* perform index-to-workdir diff on submodule */
- if (git_diff_index_to_workdir(&diff, sm_repo, NULL, &opt) < 0)
+ if (git_diff_index_to_workdir(&diff, sm_repo, index, &opt) < 0)
giterr_clear();
else {
size_t untracked =