Commit 7e57d2506a4719dbe13115ba3bf7e4a012daa3e3

Sascha Cunz 2012-09-18T23:43:23

Diff: teach get_workdir_content to show a submodule as text 1. teach diff.c:maybe_modified to query git_submodule_status for the modification state of a submodule. According to the git_submodule_status docs, it will filter for to-ignore states already. 2. teach diff_output.c:get_workdir_content to check the submodule status again and create a line like: Subproject commit <SHA-1>\n or Subproject comimt <SHA-1>-dirty\n like git.git does.

diff --git a/src/diff.c b/src/diff.c
index 77cbc3c..375520e 100644
--- a/src/diff.c
+++ b/src/diff.c
@@ -561,8 +561,11 @@ static int maybe_modified(
 			else if (git_submodule_ignore(sub) == GIT_SUBMODULE_IGNORE_ALL)
 				status = GIT_DELTA_UNMODIFIED;
 			else {
-				/* TODO: support other GIT_SUBMODULE_IGNORE values */
-				status = GIT_DELTA_UNMODIFIED;
+				unsigned int sm_status = 0;
+				if (git_submodule_status(&sm_status, sub) < 0)
+					return -1;
+				status = GIT_SUBMODULE_STATUS_IS_UNMODIFIED(sm_status)
+						 ? GIT_DELTA_UNMODIFIED : GIT_DELTA_MODIFIED;
 			}
 		}
 	}
diff --git a/src/diff_output.c b/src/diff_output.c
index b8516cc..f8a9f8e 100644
--- a/src/diff_output.c
+++ b/src/diff_output.c
@@ -7,6 +7,7 @@
 #include "common.h"
 #include "git2/attr.h"
 #include "git2/oid.h"
+#include "git2/submodule.h"
 #include "diff_output.h"
 #include <ctype.h>
 #include "fileops.h"
@@ -276,6 +277,43 @@ static int get_workdir_content(
 	git_buf path = GIT_BUF_INIT;
 	const char *wd = git_repository_workdir(ctxt->repo);
 
+	if (file->mode == GIT_FILEMODE_COMMIT)
+	{
+		git_buf content = GIT_BUF_INIT;
+		git_submodule* sm = NULL;
+		const git_oid* sm_head = NULL;
+		unsigned int sm_status = 0;
+		const char* sm_status_text = "";
+		char oidstr[GIT_OID_HEXSZ+1];
+
+		if ((error = git_submodule_lookup(&sm, ctxt->repo, file->path)) < 0) {
+			return error;
+		}
+
+		if ((sm_head = git_submodule_head_oid(sm)) == NULL) {
+			giterr_set(GITERR_SUBMODULE, "Cannot find head of submodule '%s'", file->path);
+			return -1;
+		}
+
+		if ((error = git_submodule_status(&sm_status, sm)) < 0) {
+			return -1;
+		}
+		if (!GIT_SUBMODULE_STATUS_IS_UNMODIFIED(sm_status)) {
+			sm_status_text = "-dirty";
+		}
+
+		git_oid_fmt(oidstr, sm_head);
+		oidstr[GIT_OID_HEXSZ] = 0;
+		git_buf_printf(&content, "Subproject commit %s%s\n", oidstr, sm_status_text );
+
+		map->data = git_buf_detach(&content);
+		map->len = strlen(map->data);
+
+		file->flags |= GIT_DIFF_FILE_FREE_DATA;
+
+		return 0;
+	}
+
 	if (git_buf_joinpath(&path, wd, file->path) < 0)
 		return -1;