summaryrefslogtreecommitdiffabout
authorLars Hjemli <hjemli@gmail.com>2007-05-16 02:21:06 (UTC)
committer Lars Hjemli <hjemli@gmail.com>2007-05-16 02:21:06 (UTC)
commitf4f1339fe62fb1a28c147567195a86dd99485e25 (patch) (unidiff)
tree948b58f6bc18ec87f81f84221510eec85c41e16d
parentd82c08a0446aa712a7d825e07f3d51796421b3a2 (diff)
downloadcgit-f4f1339fe62fb1a28c147567195a86dd99485e25.zip
cgit-f4f1339fe62fb1a28c147567195a86dd99485e25.tar.gz
cgit-f4f1339fe62fb1a28c147567195a86dd99485e25.tar.bz2
Don't die when diffing trees with subprojects
The subprojects needs special handling, since they refer to objects which normally won't exist in the refering repository. Fix some extended header bugs and missing features while at it. Signed-off-by: Lars Hjemli <hjemli@gmail.com>
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--ui-diff.c50
1 files changed, 37 insertions, 13 deletions
diff --git a/ui-diff.c b/ui-diff.c
index afe1c90..3ed0a46 100644
--- a/ui-diff.c
+++ b/ui-diff.c
@@ -28,45 +28,69 @@ static void print_line(char *line, int len)
28 line[len-1] = '\0'; 28 line[len-1] = '\0';
29 html_txt(line); 29 html_txt(line);
30 html("</div>"); 30 html("</div>");
31 line[len-1] = c; 31 line[len-1] = c;
32} 32}
33 33
34static void header(unsigned char *sha1, char *path1, 34static void header(unsigned char *sha1, char *path1, int mode1,
35 unsigned char *sha2, char *path2) 35 unsigned char *sha2, char *path2, int mode2)
36{ 36{
37 char *abbrev1, *abbrev2; 37 char *abbrev1, *abbrev2;
38 if (is_null_sha1(sha1)) 38 int subproject;
39 path1 = "dev/null"; 39
40 if (is_null_sha1(sha2)) 40 subproject = (S_ISDIRLNK(mode1) || S_ISDIRLNK(mode2));
41 path2 = "dev/null";
42 html("<tr><td>"); 41 html("<tr><td>");
43 html("<div class='head'>"); 42 html("<div class='head'>");
44 html("diff --git a/"); 43 html("diff --git a/");
45 html_txt(path1); 44 html_txt(path1);
46 html(" b/"); 45 html(" b/");
47 html_txt(path2); 46 html_txt(path2);
47
48 if (is_null_sha1(sha1))
49 path1 = "dev/null";
50 if (is_null_sha1(sha2))
51 path2 = "dev/null";
52
53 if (mode1 == 0)
54 htmlf("<br/>new file mode %.6o", mode2);
55
56 if (mode2 == 0)
57 htmlf("<br/>deleted file mode %.6o", mode1);
58
59 if (!subproject) {
48 abbrev1 = xstrdup(find_unique_abbrev(sha1, DEFAULT_ABBREV)); 60 abbrev1 = xstrdup(find_unique_abbrev(sha1, DEFAULT_ABBREV));
49 abbrev2 = xstrdup(find_unique_abbrev(sha2, DEFAULT_ABBREV)); 61 abbrev2 = xstrdup(find_unique_abbrev(sha2, DEFAULT_ABBREV));
50 htmlf("\nindex %s..%s", abbrev1, abbrev2); 62 htmlf("<br/>index %s..%s", abbrev1, abbrev2);
51 free(abbrev1); 63 free(abbrev1);
52 free(abbrev2); 64 free(abbrev2);
53 html("\n--- a/"); 65 if (mode1 != 0 && mode2 != 0) {
66 htmlf(" %.6o", mode1);
67 if (mode2 != mode1)
68 htmlf("..%.6o", mode2);
69 }
70 html("<br/>--- a/");
54 html_txt(path1); 71 html_txt(path1);
55 html("\n+++ b/"); 72 html("<br/>+++ b/");
56 html_txt(path2); 73 html_txt(path2);
74 }
57 html("</div>"); 75 html("</div>");
58} 76}
59 77
60static void filepair_cb(struct diff_filepair *pair) 78static void filepair_cb(struct diff_filepair *pair)
61{ 79{
62 header(pair->one->sha1, pair->one->path, 80 header(pair->one->sha1, pair->one->path, pair->one->mode,
63 pair->two->sha1, pair->two->path); 81 pair->two->sha1, pair->two->path, pair->two->mode);
82 if (S_ISDIRLNK(pair->one->mode) || S_ISDIRLNK(pair->two->mode)) {
83 if (S_ISDIRLNK(pair->one->mode))
84 print_line(fmt("-Subproject %s", sha1_to_hex(pair->one->sha1)), 52);
85 if (S_ISDIRLNK(pair->two->mode))
86 print_line(fmt("+Subproject %s", sha1_to_hex(pair->two->sha1)), 52);
87 return;
88 }
64 if (cgit_diff_files(pair->one->sha1, pair->two->sha1, print_line)) 89 if (cgit_diff_files(pair->one->sha1, pair->two->sha1, print_line))
65 cgit_print_error("Error running diff"); 90 cgit_print_error("Error running diff");
66 html("</tr></td>");
67} 91}
68 92
69void cgit_print_diff(const char *head, const char *old_hex, const char *new_hex, char *path) 93void cgit_print_diff(const char *head, const char *old_hex, const char *new_hex, char *path)
70{ 94{
71 unsigned char sha1[20], sha2[20]; 95 unsigned char sha1[20], sha2[20];
72 enum object_type type; 96 enum object_type type;
@@ -97,13 +121,13 @@ void cgit_print_diff(const char *head, const char *old_hex, const char *new_hex,
97 } 121 }
98 122
99 html("<table class='diff'>"); 123 html("<table class='diff'>");
100 switch(type) { 124 switch(type) {
101 case OBJ_BLOB: 125 case OBJ_BLOB:
102 html("<tr><td>"); 126 html("<tr><td>");
103 header(sha1, path, sha2, path); 127 header(sha1, path, 0644, sha2, path, 0644);
104 if (cgit_diff_files(sha1, sha2, print_line)) 128 if (cgit_diff_files(sha1, sha2, print_line))
105 cgit_print_error("Error running diff"); 129 cgit_print_error("Error running diff");
106 html("</tr></td>"); 130 html("</tr></td>");
107 break; 131 break;
108 case OBJ_TREE: 132 case OBJ_TREE:
109 cgit_diff_tree(sha1, sha2, filepair_cb); 133 cgit_diff_tree(sha1, sha2, filepair_cb);