summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRussell Belfer <rb@github.com>2013-03-18 17:24:13 -0700
committerRussell Belfer <rb@github.com>2013-03-18 17:24:13 -0700
commit65025cb8934a289460bc64f82c27027c68a85be6 (patch)
tree4b945ad28ff220ffa8500275a5e7a635749e3d11 /src
parent5b27bf7e5bfd5c2f92a15c0058c801d49faf8403 (diff)
downloadlibgit2-65025cb8934a289460bc64f82c27027c68a85be6.tar.gz
Three submodule status bug fixes
1. Fix sort order problem with submodules where "mod" was sorting after "mod-plus" because they were being sorted as "mod/" and "mod-plus/". This involved pushing the "contains a .git entry" test significantly lower in the stack. 2. Reinstate behavior that a directory which contains a .git entry will be treated as a submodule during iteration even if it is not yet added to the .gitmodules. 3. Now that any directory containing .git is reported as submodule, we have to be more careful checking for GIT_EEXISTS when we do a submodule lookup, because that is the error code that is returned by git_submodule_lookup when you try to look up a directory containing .git that has no record in gitmodules or the index.
Diffstat (limited to 'src')
-rw-r--r--src/diff.c10
-rw-r--r--src/diff_output.c5
-rw-r--r--src/iterator.c4
-rw-r--r--src/path.c15
4 files changed, 26 insertions, 8 deletions
diff --git a/src/diff.c b/src/diff.c
index fc37d139d..fb69f8920 100644
--- a/src/diff.c
+++ b/src/diff.c
@@ -512,13 +512,17 @@ static int maybe_modified(
status = GIT_DELTA_UNMODIFIED;
else if (S_ISGITLINK(nmode)) {
+ int err;
git_submodule *sub;
if ((diff->opts.flags & GIT_DIFF_IGNORE_SUBMODULES) != 0)
status = GIT_DELTA_UNMODIFIED;
- else if (git_submodule_lookup(&sub, diff->repo, nitem->path) < 0)
- return -1;
- else if (git_submodule_ignore(sub) == GIT_SUBMODULE_IGNORE_ALL)
+ else if ((err = git_submodule_lookup(&sub, diff->repo, nitem->path)) < 0) {
+ if (err == GIT_EEXISTS)
+ status = GIT_DELTA_UNMODIFIED;
+ else
+ return err;
+ } else if (git_submodule_ignore(sub) == GIT_SUBMODULE_IGNORE_ALL)
status = GIT_DELTA_UNMODIFIED;
else {
unsigned int sm_status = 0;
diff --git a/src/diff_output.c b/src/diff_output.c
index b938cc06d..fba6129b7 100644
--- a/src/diff_output.c
+++ b/src/diff_output.c
@@ -299,7 +299,12 @@ static int get_workdir_sm_content(
if ((error = git_submodule_lookup(&sm, ctxt->repo, file->path)) < 0 ||
(error = git_submodule_status(&sm_status, sm)) < 0)
+ {
+ /* GIT_EEXISTS means a "submodule" that has not been git added */
+ if (error == GIT_EEXISTS)
+ error = 0;
return error;
+ }
/* update OID if we didn't have it previously */
if ((file->flags & GIT_DIFF_FLAG_VALID_OID) == 0) {
diff --git a/src/iterator.c b/src/iterator.c
index b15bcedd8..805a3c987 100644
--- a/src/iterator.c
+++ b/src/iterator.c
@@ -1150,11 +1150,13 @@ static int workdir_iterator__update_entry(workdir_iterator *wi)
return 0;
/* detect submodules */
-
error = git_submodule_lookup(NULL, wi->base.repo, wi->entry.path);
if (error == GIT_ENOTFOUND)
giterr_clear();
+ if (error == GIT_EEXISTS) /* if contains .git, treat as untracked submod */
+ error = 0;
+
/* if submodule, mark as GITLINK and remove trailing slash */
if (!error) {
size_t len = strlen(wi->entry.path);
diff --git a/src/path.c b/src/path.c
index 5767faeed..6437979d5 100644
--- a/src/path.c
+++ b/src/path.c
@@ -877,15 +877,22 @@ int git_path_dirload_with_stat(
if (cmp_len && strncomp(ps->path, end_stat, cmp_len) > 0)
continue;
+ git_buf_truncate(&full, prefix_len);
+
if ((error = git_buf_joinpath(&full, full.ptr, ps->path)) < 0 ||
(error = git_path_lstat(full.ptr, &ps->st)) < 0)
break;
- git_buf_truncate(&full, prefix_len);
-
if (S_ISDIR(ps->st.st_mode)) {
- ps->path[ps->path_len++] = '/';
- ps->path[ps->path_len] = '\0';
+ if ((error = git_buf_joinpath(&full, full.ptr, ".git")) < 0)
+ break;
+
+ if (p_access(full.ptr, F_OK) == 0) {
+ ps->st.st_mode = GIT_FILEMODE_COMMIT;
+ } else {
+ ps->path[ps->path_len++] = '/';
+ ps->path[ps->path_len] = '\0';
+ }
}
}