diff options
author | Russell Belfer <rb@github.com> | 2014-04-28 14:34:55 -0700 |
---|---|---|
committer | Russell Belfer <rb@github.com> | 2014-04-28 14:50:49 -0700 |
commit | b4ed1614b2e6ae934c18d1f25f5c3569ea0dc8e5 (patch) | |
tree | a1f51570b31509dffdcb786565596a611480fb2f | |
parent | e94d166e79a1cffb8e7616ecc8abcb1fab2c6950 (diff) | |
download | libgit2-b4ed1614b2e6ae934c18d1f25f5c3569ea0dc8e5.tar.gz |
Lay groundwork for updating stat cache in diff
This reorganized the diff OID calculation to make it easier to
correctly update the stat cache during a diff once the flags to
do so are enabled.
This includes marking the path of a git_index_entry as const so
we can make a "fake" git_index_entry with a "const char *" path
and not get warnings. I was a little surprised at how unobtrusive
this change was, but I think it's probably a good thing.
-rw-r--r-- | include/git2/index.h | 2 | ||||
-rw-r--r-- | src/checkout.c | 3 | ||||
-rw-r--r-- | src/diff.c | 44 | ||||
-rw-r--r-- | src/diff.h | 4 | ||||
-rw-r--r-- | src/index.c | 6 |
5 files changed, 37 insertions, 22 deletions
diff --git a/include/git2/index.h b/include/git2/index.h index 05e58a632..cdb87282c 100644 --- a/include/git2/index.h +++ b/include/git2/index.h @@ -61,7 +61,7 @@ typedef struct git_index_entry { unsigned short flags; unsigned short flags_extended; - char *path; + const char *path; } git_index_entry; /** diff --git a/src/checkout.c b/src/checkout.c index 93d6bc9c5..d94cb0c7d 100644 --- a/src/checkout.c +++ b/src/checkout.c @@ -184,8 +184,7 @@ static bool checkout_is_workdir_modified( if (baseitem->size && wditem->file_size != baseitem->size) return true; - if (git_diff__oid_for_file( - &oid, data->diff, wditem->path, wditem->mode, wditem->file_size) < 0) + if (git_diff__oid_for_entry(&oid, data->diff, wditem) < 0) return false; return (git_oid__cmp(&baseitem->id, &oid) != 0); diff --git a/src/diff.c b/src/diff.c index 4c028ca4e..eae4543fc 100644 --- a/src/diff.c +++ b/src/diff.c @@ -516,38 +516,52 @@ int git_diff__oid_for_file( uint16_t mode, git_off_t size) { + git_index_entry entry; + + memset(&entry, 0, sizeof(entry)); + entry.mode = mode; + entry.file_size = size; + entry.path = (char *)path; + + return git_diff__oid_for_entry(out, diff, &entry); +} + +int git_diff__oid_for_entry( + git_oid *out, git_diff *diff, const git_index_entry *src) +{ int error = 0; git_buf full_path = GIT_BUF_INIT; + git_index_entry entry = *src; git_filter_list *fl = NULL; memset(out, 0, sizeof(*out)); if (git_buf_joinpath( - &full_path, git_repository_workdir(diff->repo), path) < 0) + &full_path, git_repository_workdir(diff->repo), entry.path) < 0) return -1; - if (!mode) { + if (!entry.mode) { struct stat st; GIT_PERF_INC(diff->stat_calls); if (p_stat(full_path.ptr, &st) < 0) { - error = git_path_set_error(errno, path, "stat"); + error = git_path_set_error(errno, entry.path, "stat"); git_buf_free(&full_path); return error; } - mode = st.st_mode; - size = st.st_size; + git_index_entry__init_from_stat( + &entry, &st, (diff->diffcaps & GIT_DIFFCAPS_TRUST_MODE_BITS) != 0); } /* calculate OID for file if possible */ - if (S_ISGITLINK(mode)) { + if (S_ISGITLINK(entry.mode)) { git_submodule *sm; GIT_PERF_INC(diff->submodule_lookups); - if (!git_submodule_lookup(&sm, diff->repo, path)) { + if (!git_submodule_lookup(&sm, diff->repo, entry.path)) { const git_oid *sm_oid = git_submodule_wd_id(sm); if (sm_oid) git_oid_cpy(out, sm_oid); @@ -558,14 +572,15 @@ int git_diff__oid_for_file( */ giterr_clear(); } - } else if (S_ISLNK(mode)) { + } else if (S_ISLNK(entry.mode)) { GIT_PERF_INC(diff->oid_calculations); error = git_odb__hashlink(out, full_path.ptr); - } else if (!git__is_sizet(size)) { - giterr_set(GITERR_OS, "File size overflow (for 32-bits) on '%s'", path); + } else if (!git__is_sizet(entry.file_size)) { + giterr_set(GITERR_OS, "File size overflow (for 32-bits) on '%s'", + entry.path); error = -1; } else if (!(error = git_filter_list_load( - &fl, diff->repo, NULL, path, GIT_FILTER_TO_ODB))) + &fl, diff->repo, NULL, entry.path, GIT_FILTER_TO_ODB))) { int fd = git_futils_open_ro(full_path.ptr); if (fd < 0) @@ -573,13 +588,15 @@ int git_diff__oid_for_file( else { GIT_PERF_INC(diff->oid_calculations); error = git_odb__hashfd_filtered( - out, fd, (size_t)size, GIT_OBJ_BLOB, fl); + out, fd, (size_t)entry.file_size, GIT_OBJ_BLOB, fl); p_close(fd); } git_filter_list_free(fl); } + /* TODO: update index for entry if requested */ + git_buf_free(&full_path); return error; } @@ -759,8 +776,7 @@ static int maybe_modified( */ if (modified_uncertain && git_oid_iszero(&nitem->id)) { if (git_oid_iszero(&noid)) { - if ((error = git_diff__oid_for_file(&noid, - diff, nitem->path, nitem->mode, nitem->file_size)) < 0) + if ((error = git_diff__oid_for_entry(&noid, diff, nitem)) < 0) return error; } diff --git a/src/diff.h b/src/diff.h index 491fc4667..8fa3c9b7b 100644 --- a/src/diff.h +++ b/src/diff.h @@ -95,7 +95,9 @@ extern int git_diff_delta__format_file_header( int oid_strlen); extern int git_diff__oid_for_file( - git_oid *oit, git_diff *, const char *, uint16_t, git_off_t); + git_oid *out, git_diff *, const char *, uint16_t, git_off_t); +extern int git_diff__oid_for_entry( + git_oid *out, git_diff *, const git_index_entry *entry); extern int git_diff__from_iterators( git_diff **diff_ptr, diff --git a/src/index.c b/src/index.c index c044af402..8a7f29279 100644 --- a/src/index.c +++ b/src/index.c @@ -842,7 +842,7 @@ static int index_entry_reuc_init(git_index_reuc_entry **reuc_out, static void index_entry_cpy(git_index_entry *tgt, const git_index_entry *src) { - char *tgt_path = tgt->path; + const char *tgt_path = tgt->path; memcpy(tgt, src, sizeof(*tgt)); tgt->path = tgt_path; /* reset to existing path data */ } @@ -2282,9 +2282,7 @@ static int read_tree_cb( entry->mode == old_entry->mode && git_oid_equal(&entry->id, &old_entry->id)) { - char *oldpath = entry->path; - memcpy(entry, old_entry, sizeof(*entry)); - entry->path = oldpath; + index_entry_cpy(entry, old_entry); entry->flags_extended = 0; } |