summaryrefslogtreecommitdiff
path: root/src/diff.c
diff options
context:
space:
mode:
authorVicent Martí <vicent@github.com>2012-10-09 11:45:50 -0700
committerVicent Martí <vicent@github.com>2012-10-09 11:45:50 -0700
commit21e0d297af95e49b933c2a8d09994a32011354b1 (patch)
tree1e248d6899feac797f0c1307ad7cf52cead42389 /src/diff.c
parentaa4437f637371c531355029686cb5780fd99c988 (diff)
parent5d1308f25ff36d03f0a22451642cc0f2a931daae (diff)
downloadlibgit2-21e0d297af95e49b933c2a8d09994a32011354b1.tar.gz
Merge pull request #967 from arrbee/diff-submodule-tests-and-fixes
Diff submodule tests and fixes
Diffstat (limited to 'src/diff.c')
-rw-r--r--src/diff.c59
1 files changed, 48 insertions, 11 deletions
diff --git a/src/diff.c b/src/diff.c
index 7a0051ae3..8ab8af3a1 100644
--- a/src/diff.c
+++ b/src/diff.c
@@ -224,7 +224,10 @@ static int diff_delta__from_one(
}
delta->old_file.flags |= GIT_DIFF_FILE_VALID_OID;
- delta->new_file.flags |= GIT_DIFF_FILE_VALID_OID;
+
+ if (delta->status == GIT_DELTA_DELETED ||
+ !git_oid_iszero(&delta->new_file.oid))
+ delta->new_file.flags |= GIT_DIFF_FILE_VALID_OID;
if (git_vector_insert(&diff->deltas, delta) < 0) {
git__free(delta);
@@ -441,17 +444,28 @@ static int oid_for_workdir_item(
const git_index_entry *item,
git_oid *oid)
{
- int result;
+ int result = 0;
git_buf full_path = GIT_BUF_INIT;
- if (git_buf_joinpath(&full_path, git_repository_workdir(repo), item->path) < 0)
+ if (git_buf_joinpath(
+ &full_path, git_repository_workdir(repo), item->path) < 0)
return -1;
- /* calculate OID for file if possible*/
+ /* calculate OID for file if possible */
if (S_ISGITLINK(item->mode)) {
- /* Don't bother to figure out an oid for a submodule. We won't use it anyway. */
- memset(oid, 0, sizeof(*oid));
- result = 0;
+ git_submodule *sm;
+ const git_oid *sm_oid;
+
+ if (!git_submodule_lookup(&sm, repo, item->path) &&
+ (sm_oid = git_submodule_wd_oid(sm)) != NULL)
+ git_oid_cpy(oid, sm_oid);
+ else {
+ /* if submodule lookup failed probably just in an intermediate
+ * state where some init hasn't happened, so ignore the error
+ */
+ giterr_clear();
+ memset(oid, 0, sizeof(*oid));
+ }
} else if (S_ISLNK(item->mode))
result = git_odb__hashlink(oid, full_path.ptr);
else if (!git__is_sizet(item->file_size)) {
@@ -570,6 +584,15 @@ static int maybe_modified(
return -1;
status = GIT_SUBMODULE_STATUS_IS_UNMODIFIED(sm_status)
? GIT_DELTA_UNMODIFIED : GIT_DELTA_MODIFIED;
+
+ /* grab OID while we are here */
+ if (git_oid_iszero(&nitem->oid)) {
+ const git_oid *sm_oid = git_submodule_wd_oid(sub);
+ if (sub != NULL) {
+ git_oid_cpy(&noid, sm_oid);
+ use_noid = &noid;
+ }
+ }
}
}
}
@@ -669,7 +692,8 @@ static int diff_from_iterators(
/* check if contained in ignored parent directory */
if (git_buf_len(&ignore_prefix) &&
- ITERATOR_PREFIXCMP(*old_iter, nitem->path, git_buf_cstr(&ignore_prefix)) == 0)
+ ITERATOR_PREFIXCMP(*old_iter, nitem->path,
+ git_buf_cstr(&ignore_prefix)) == 0)
delta_type = GIT_DELTA_IGNORED;
if (S_ISDIR(nitem->mode)) {
@@ -677,10 +701,23 @@ static int diff_from_iterators(
* it or if the user requested the contents of untracked
* directories and it is not under an ignored directory.
*/
- if ((oitem && ITERATOR_PREFIXCMP(*old_iter, oitem->path, nitem->path) == 0) ||
+ bool contains_tracked =
+ (oitem &&
+ !ITERATOR_PREFIXCMP(*old_iter, oitem->path, nitem->path));
+ bool recurse_untracked =
(delta_type == GIT_DELTA_UNTRACKED &&
- (diff->opts.flags & GIT_DIFF_RECURSE_UNTRACKED_DIRS) != 0))
- {
+ (diff->opts.flags & GIT_DIFF_RECURSE_UNTRACKED_DIRS) != 0);
+
+ /* do not advance into directories that contain a .git file */
+ if (!contains_tracked && recurse_untracked) {
+ git_buf *full = NULL;
+ if (git_iterator_current_workdir_path(new_iter, &full) < 0)
+ goto fail;
+ if (git_path_contains_dir(full, DOT_GIT))
+ recurse_untracked = false;
+ }
+
+ if (contains_tracked || recurse_untracked) {
/* if this directory is ignored, remember it as the
* "ignore_prefix" for processing contained items
*/