Skip to content

Commit bdf6442

Browse files
committed
Merge branch 'jc/maint-split-diff-metainfo'
* jc/maint-split-diff-metainfo: diff.c: output correct index lines for a split diff
2 parents ed096c4 + 90b23e5 commit bdf6442

File tree

3 files changed

+99
-67
lines changed

3 files changed

+99
-67
lines changed

diff.c

Lines changed: 80 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -2087,16 +2087,86 @@ static void run_external_diff(const char *pgm,
20872087
}
20882088
}
20892089

2090+
static int similarity_index(struct diff_filepair *p)
2091+
{
2092+
return p->score * 100 / MAX_SCORE;
2093+
}
2094+
2095+
static void fill_metainfo(struct strbuf *msg,
2096+
const char *name,
2097+
const char *other,
2098+
struct diff_filespec *one,
2099+
struct diff_filespec *two,
2100+
struct diff_options *o,
2101+
struct diff_filepair *p)
2102+
{
2103+
strbuf_init(msg, PATH_MAX * 2 + 300);
2104+
switch (p->status) {
2105+
case DIFF_STATUS_COPIED:
2106+
strbuf_addf(msg, "similarity index %d%%", similarity_index(p));
2107+
strbuf_addstr(msg, "\ncopy from ");
2108+
quote_c_style(name, msg, NULL, 0);
2109+
strbuf_addstr(msg, "\ncopy to ");
2110+
quote_c_style(other, msg, NULL, 0);
2111+
strbuf_addch(msg, '\n');
2112+
break;
2113+
case DIFF_STATUS_RENAMED:
2114+
strbuf_addf(msg, "similarity index %d%%", similarity_index(p));
2115+
strbuf_addstr(msg, "\nrename from ");
2116+
quote_c_style(name, msg, NULL, 0);
2117+
strbuf_addstr(msg, "\nrename to ");
2118+
quote_c_style(other, msg, NULL, 0);
2119+
strbuf_addch(msg, '\n');
2120+
break;
2121+
case DIFF_STATUS_MODIFIED:
2122+
if (p->score) {
2123+
strbuf_addf(msg, "dissimilarity index %d%%\n",
2124+
similarity_index(p));
2125+
break;
2126+
}
2127+
/* fallthru */
2128+
default:
2129+
/* nothing */
2130+
;
2131+
}
2132+
if (one && two && hashcmp(one->sha1, two->sha1)) {
2133+
int abbrev = DIFF_OPT_TST(o, FULL_INDEX) ? 40 : DEFAULT_ABBREV;
2134+
2135+
if (DIFF_OPT_TST(o, BINARY)) {
2136+
mmfile_t mf;
2137+
if ((!fill_mmfile(&mf, one) && diff_filespec_is_binary(one)) ||
2138+
(!fill_mmfile(&mf, two) && diff_filespec_is_binary(two)))
2139+
abbrev = 40;
2140+
}
2141+
strbuf_addf(msg, "index %.*s..%.*s",
2142+
abbrev, sha1_to_hex(one->sha1),
2143+
abbrev, sha1_to_hex(two->sha1));
2144+
if (one->mode == two->mode)
2145+
strbuf_addf(msg, " %06o", one->mode);
2146+
strbuf_addch(msg, '\n');
2147+
}
2148+
if (msg->len)
2149+
strbuf_setlen(msg, msg->len - 1);
2150+
}
2151+
20902152
static void run_diff_cmd(const char *pgm,
20912153
const char *name,
20922154
const char *other,
20932155
const char *attr_path,
20942156
struct diff_filespec *one,
20952157
struct diff_filespec *two,
2096-
const char *xfrm_msg,
2158+
struct strbuf *msg,
20972159
struct diff_options *o,
2098-
int complete_rewrite)
2160+
struct diff_filepair *p)
20992161
{
2162+
const char *xfrm_msg = NULL;
2163+
int complete_rewrite = (p->status == DIFF_STATUS_MODIFIED) && p->score;
2164+
2165+
if (msg) {
2166+
fill_metainfo(msg, name, other, one, two, o, p);
2167+
xfrm_msg = msg->len ? msg->buf : NULL;
2168+
}
2169+
21002170
if (!DIFF_OPT_TST(o, ALLOW_EXTERNAL))
21012171
pgm = NULL;
21022172
else {
@@ -2136,11 +2206,6 @@ static void diff_fill_sha1_info(struct diff_filespec *one)
21362206
hashclr(one->sha1);
21372207
}
21382208

2139-
static int similarity_index(struct diff_filepair *p)
2140-
{
2141-
return p->score * 100 / MAX_SCORE;
2142-
}
2143-
21442209
static void strip_prefix(int prefix_length, const char **namep, const char **otherp)
21452210
{
21462211
/* Strip the prefix but do not molest /dev/null and absolute paths */
@@ -2154,13 +2219,11 @@ static void run_diff(struct diff_filepair *p, struct diff_options *o)
21542219
{
21552220
const char *pgm = external_diff();
21562221
struct strbuf msg;
2157-
char *xfrm_msg;
21582222
struct diff_filespec *one = p->one;
21592223
struct diff_filespec *two = p->two;
21602224
const char *name;
21612225
const char *other;
21622226
const char *attr_path;
2163-
int complete_rewrite = 0;
21642227

21652228
name = p->one->path;
21662229
other = (strcmp(name, p->two->path) ? p->two->path : NULL);
@@ -2170,83 +2233,34 @@ static void run_diff(struct diff_filepair *p, struct diff_options *o)
21702233

21712234
if (DIFF_PAIR_UNMERGED(p)) {
21722235
run_diff_cmd(pgm, name, NULL, attr_path,
2173-
NULL, NULL, NULL, o, 0);
2236+
NULL, NULL, NULL, o, p);
21742237
return;
21752238
}
21762239

21772240
diff_fill_sha1_info(one);
21782241
diff_fill_sha1_info(two);
21792242

2180-
strbuf_init(&msg, PATH_MAX * 2 + 300);
2181-
switch (p->status) {
2182-
case DIFF_STATUS_COPIED:
2183-
strbuf_addf(&msg, "similarity index %d%%", similarity_index(p));
2184-
strbuf_addstr(&msg, "\ncopy from ");
2185-
quote_c_style(name, &msg, NULL, 0);
2186-
strbuf_addstr(&msg, "\ncopy to ");
2187-
quote_c_style(other, &msg, NULL, 0);
2188-
strbuf_addch(&msg, '\n');
2189-
break;
2190-
case DIFF_STATUS_RENAMED:
2191-
strbuf_addf(&msg, "similarity index %d%%", similarity_index(p));
2192-
strbuf_addstr(&msg, "\nrename from ");
2193-
quote_c_style(name, &msg, NULL, 0);
2194-
strbuf_addstr(&msg, "\nrename to ");
2195-
quote_c_style(other, &msg, NULL, 0);
2196-
strbuf_addch(&msg, '\n');
2197-
break;
2198-
case DIFF_STATUS_MODIFIED:
2199-
if (p->score) {
2200-
strbuf_addf(&msg, "dissimilarity index %d%%\n",
2201-
similarity_index(p));
2202-
complete_rewrite = 1;
2203-
break;
2204-
}
2205-
/* fallthru */
2206-
default:
2207-
/* nothing */
2208-
;
2209-
}
2210-
2211-
if (hashcmp(one->sha1, two->sha1)) {
2212-
int abbrev = DIFF_OPT_TST(o, FULL_INDEX) ? 40 : DEFAULT_ABBREV;
2213-
2214-
if (DIFF_OPT_TST(o, BINARY)) {
2215-
mmfile_t mf;
2216-
if ((!fill_mmfile(&mf, one) && diff_filespec_is_binary(one)) ||
2217-
(!fill_mmfile(&mf, two) && diff_filespec_is_binary(two)))
2218-
abbrev = 40;
2219-
}
2220-
strbuf_addf(&msg, "index %.*s..%.*s",
2221-
abbrev, sha1_to_hex(one->sha1),
2222-
abbrev, sha1_to_hex(two->sha1));
2223-
if (one->mode == two->mode)
2224-
strbuf_addf(&msg, " %06o", one->mode);
2225-
strbuf_addch(&msg, '\n');
2226-
}
2227-
2228-
if (msg.len)
2229-
strbuf_setlen(&msg, msg.len - 1);
2230-
xfrm_msg = msg.len ? msg.buf : NULL;
2231-
22322243
if (!pgm &&
22332244
DIFF_FILE_VALID(one) && DIFF_FILE_VALID(two) &&
22342245
(S_IFMT & one->mode) != (S_IFMT & two->mode)) {
2235-
/* a filepair that changes between file and symlink
2246+
/*
2247+
* a filepair that changes between file and symlink
22362248
* needs to be split into deletion and creation.
22372249
*/
22382250
struct diff_filespec *null = alloc_filespec(two->path);
22392251
run_diff_cmd(NULL, name, other, attr_path,
2240-
one, null, xfrm_msg, o, 0);
2252+
one, null, &msg, o, p);
22412253
free(null);
2254+
strbuf_release(&msg);
2255+
22422256
null = alloc_filespec(one->path);
22432257
run_diff_cmd(NULL, name, other, attr_path,
2244-
null, two, xfrm_msg, o, 0);
2258+
null, two, &msg, o, p);
22452259
free(null);
22462260
}
22472261
else
22482262
run_diff_cmd(pgm, name, other, attr_path,
2249-
one, two, xfrm_msg, o, complete_rewrite);
2263+
one, two, &msg, o, p);
22502264

22512265
strbuf_release(&msg);
22522266
}

t/t4030-diff-textconv.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ cat >expect.typechange <<'EOF'
104104
-1
105105
diff --git a/file b/file
106106
new file mode 120000
107-
index ad8b3d2..67be421
107+
index 0000000..67be421
108108
--- /dev/null
109109
+++ b/file
110110
@@ -0,0 +1 @@

t/t4114-apply-typechange.sh

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ test_expect_success 'setup repository and commits' '
2525
git update-index foo &&
2626
git commit -m "foo back to file" &&
2727
git branch foo-back-to-file &&
28+
printf "\0" > foo &&
29+
git update-index foo &&
30+
git commit -m "foo becomes binary" &&
31+
git branch foo-becomes-binary &&
2832
rm -f foo &&
2933
git update-index --remove foo &&
3034
mkdir foo &&
@@ -85,6 +89,20 @@ test_expect_success 'symlink becomes file' '
8589
'
8690
test_debug 'cat patch'
8791

92+
test_expect_success 'binary file becomes symlink' '
93+
git checkout -f foo-becomes-binary &&
94+
git diff-tree -p --binary HEAD foo-symlinked-to-bar > patch &&
95+
git apply --index < patch
96+
'
97+
test_debug 'cat patch'
98+
99+
test_expect_success 'symlink becomes binary file' '
100+
git checkout -f foo-symlinked-to-bar &&
101+
git diff-tree -p --binary HEAD foo-becomes-binary > patch &&
102+
git apply --index < patch
103+
'
104+
test_debug 'cat patch'
105+
88106

89107
test_expect_success 'symlink becomes directory' '
90108
git checkout -f foo-symlinked-to-bar &&

0 commit comments

Comments
 (0)