[PATCH/RFC] blame: respect "core.ignorecase"

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



If "core.ignorecase" is true, "git blame" fails
when the given path differs to the real path in case
sensitivity.

Signed-off-by: Ralf Thielow <ralf.thielow@xxxxxxxxx>
---
 .gitignore             |  1 +
 Makefile               |  3 +++
 builtin/blame.c        | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++
 test-path-ignorecase.c | 27 +++++++++++++++++++++++
 4 Dateien geändert, 89 Zeilen hinzugefügt(+)
 create mode 100644 test-path-ignorecase.c

diff --git a/.gitignore b/.gitignore
index bb5c91e..65ab9f6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -195,6 +195,7 @@
 /test-sigchain
 /test-subprocess
 /test-svn-fe
+/test-path-ignorecase
 /common-cmds.h
 *.tar.gz
 *.dsc
diff --git a/Makefile b/Makefile
index 6b0c961..dbdd214 100644
--- a/Makefile
+++ b/Makefile
@@ -503,6 +503,7 @@ TEST_PROGRAMS_NEED_X += test-sha1
 TEST_PROGRAMS_NEED_X += test-sigchain
 TEST_PROGRAMS_NEED_X += test-subprocess
 TEST_PROGRAMS_NEED_X += test-svn-fe
+TEST_PROGRAMS_NEED_X += test-path-ignorecase
 
 TEST_PROGRAMS = $(patsubst %,%$X,$(TEST_PROGRAMS_NEED_X))
 
@@ -2562,6 +2563,8 @@ test-parse-options$X: parse-options.o parse-options-cb.o
 
 test-svn-fe$X: vcs-svn/lib.a
 
+test-path-ignorecase$X: builtin/blame.o
+
 .PRECIOUS: $(TEST_OBJS)
 
 test-%$X: test-%.o GIT-LDFLAGS $(GITLIBS)
diff --git a/builtin/blame.c b/builtin/blame.c
index 0d50273..895f665 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -1937,6 +1937,61 @@ static int has_string_in_work_tree(const char *path)
 	return !lstat(path, &st);
 }
 
+const char* get_path_ignorecase(const char *path)
+{
+	struct strbuf res = STRBUF_INIT;
+	struct strbuf p = STRBUF_INIT;
+	int offset = 0;
+
+	if (!ignore_case || has_string_in_work_tree(path))
+		return path;
+
+	for (;;) {
+		char c = path[offset++];
+
+		if (is_dir_sep(c) || c == '\0') {
+			DIR *dir;
+
+			if (res.len)
+				dir = opendir(res.buf);
+			else
+				dir = opendir(".");
+
+			if (dir != NULL) {
+				for (;;) {
+					struct dirent *ent = readdir(dir);
+
+					if (ent == NULL )
+						break;
+
+					if (!strcmp(".", ent->d_name) || !strcmp("..", ent->d_name))
+						continue;
+
+					if (!strcmp(p.buf, ent->d_name))
+						break;
+
+					if (!strcasecmp(p.buf, ent->d_name)) {
+						strbuf_release(&p);
+						strbuf_add(&p, ent->d_name, strlen(ent->d_name));
+						break;
+					}
+				}
+				closedir(dir);
+			}
+
+			strbuf_addch(&p, c);
+			strbuf_addbuf(&res, &p);
+			strbuf_release(&p);
+		} else {
+			strbuf_addch(&p, c);
+		}
+
+		if (c == '\0')
+			break;
+	}
+	return res.buf;
+}
+
 static unsigned parse_score(const char *arg)
 {
 	char *end;
@@ -2448,6 +2503,7 @@ parse_done:
 			/* FALLTHROUGH */
 		case 1: /* (1a) */
 			path = add_prefix(prefix, argv[--argc]);
+			path = get_path_ignorecase(path);
 			argv[argc] = NULL;
 			break;
 		default:
@@ -2457,8 +2513,10 @@ parse_done:
 		if (argc < 2)
 			usage_with_options(blame_opt_usage, options);
 		path = add_prefix(prefix, argv[argc - 1]);
+		path = get_path_ignorecase(path);
 		if (argc == 3 && !has_string_in_work_tree(path)) { /* (2b) */
 			path = add_prefix(prefix, argv[1]);
+			path = get_path_ignorecase(path);
 			argv[1] = argv[2];
 		}
 		argv[argc - 1] = "--";
diff --git a/test-path-ignorecase.c b/test-path-ignorecase.c
new file mode 100644
index 0000000..1f17f5c
--- /dev/null
+++ b/test-path-ignorecase.c
@@ -0,0 +1,27 @@
+#include "cache.h"
+
+static const char *usage_msg = "\n"
+		"test-similar-path <path>...\n";
+const char* get_path_ignorecase(const char *path);
+
+int main(int argc, char **argv)
+{
+	char *p;
+	const char *np;
+
+	if (argc != 2) {
+		usage(usage_msg);
+		return 1;
+	}
+
+	argv++;
+	p = *argv;
+
+	ignore_case = 1;
+
+	np = get_path_ignorecase(p);
+
+	printf("%s\n", np);
+
+	return 0;
+}
-- 
1.7.12.1.gfe115d7

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]