summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeat Bolli <dev+git@drbeat.li>2015-11-23 22:32:12 +0100
committerJeff King <peff@peff.net>2015-11-24 18:55:26 -0500
commit3c6de746bd461705fdaa6113085e62fb55705049 (patch)
treec58b4719d19f416304a5cf0d258f4c06a73905a5
parent5cb2e162d21fa45a63f186b31970e2e9c9b10ba9 (diff)
downloadgit-bb/merge-marker-crlf.tar.gz
merge-file: consider core.crlf when writing merge markersbb/merge-marker-crlf
When merging files in repos with core.eol = crlf, git merge-file inserts just a LF at the end of the merge markers. Files with mixed line endings cause trouble in Windows editors and e.g. contrib/git-jump, where an unmerged file in a run of "git jump merge" is reported as simply "binary file matches". Fixing this improves Git's behavior under Windows. Signed-off-by: Beat Bolli <dev+git@drbeat.li> Cc: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Jeff King <peff@peff.net>
-rw-r--r--builtin/merge-file.c1
-rw-r--r--ll-merge.c1
-rwxr-xr-xt/t6023-merge-file.sh7
-rw-r--r--xdiff/xdiff.h1
-rw-r--r--xdiff/xmerge.c29
5 files changed, 29 insertions, 10 deletions
diff --git a/builtin/merge-file.c b/builtin/merge-file.c
index 55447053f2..c534c91f44 100644
--- a/builtin/merge-file.c
+++ b/builtin/merge-file.c
@@ -81,6 +81,7 @@ int cmd_merge_file(int argc, const char **argv, const char *prefix)
argv[i]);
}
+ xmp.crlf = (core_eol == EOL_CRLF);
xmp.ancestor = names[1];
xmp.file1 = names[0];
xmp.file2 = names[2];
diff --git a/ll-merge.c b/ll-merge.c
index bf83290793..3407f8c5d7 100644
--- a/ll-merge.c
+++ b/ll-merge.c
@@ -111,6 +111,7 @@ static int ll_xdl_merge(const struct ll_merge_driver *drv_unused,
xmp.style = git_xmerge_style;
if (marker_size > 0)
xmp.marker_size = marker_size;
+ xmp.crlf = (core_eol == EOL_CRLF);
xmp.ancestor = orig_name;
xmp.file1 = name1;
xmp.file2 = name2;
diff --git a/t/t6023-merge-file.sh b/t/t6023-merge-file.sh
index 190ee903cf..245359a527 100755
--- a/t/t6023-merge-file.sh
+++ b/t/t6023-merge-file.sh
@@ -346,4 +346,11 @@ test_expect_success 'conflict at EOF without LF resolved by --union' \
printf "line1\nline2\nline3x\nline3y" >expect.txt &&
test_cmp expect.txt output.txt'
+
+test_expect_success 'conflict markers contain CRLF when core.eol=crlf' '
+ test_must_fail git -c core.eol=crlf merge-file -p \
+ nolf-diff1.txt nolf-orig.txt nolf-diff2.txt >output.txt &&
+ test $(sed -n "/\.txt\r$/p" output.txt | wc -l) = 3
+'
+
test_done
diff --git a/xdiff/xdiff.h b/xdiff/xdiff.h
index c0339919cc..a5bea4a5bb 100644
--- a/xdiff/xdiff.h
+++ b/xdiff/xdiff.h
@@ -122,6 +122,7 @@ typedef struct s_xmparam {
int level;
int favor;
int style;
+ int crlf;
const char *ancestor; /* label for orig */
const char *file1; /* label for mf1 */
const char *file2; /* label for mf2 */
diff --git a/xdiff/xmerge.c b/xdiff/xmerge.c
index 625198e058..4ff0db4752 100644
--- a/xdiff/xmerge.c
+++ b/xdiff/xmerge.c
@@ -146,7 +146,7 @@ static int xdl_orig_copy(xdfenv_t *xe, int i, int count, int add_nl, char *dest)
static int fill_conflict_hunk(xdfenv_t *xe1, const char *name1,
xdfenv_t *xe2, const char *name2,
const char *name3,
- int size, int i, int style,
+ int size, int i, int style, int crlf,
xdmerge_t *m, char *dest, int marker_size)
{
int marker1_size = (name1 ? strlen(name1) + 1 : 0);
@@ -161,7 +161,7 @@ static int fill_conflict_hunk(xdfenv_t *xe1, const char *name1,
dest ? dest + size : NULL);
if (!dest) {
- size += marker_size + 1 + marker1_size;
+ size += marker_size + 1 + crlf + marker1_size;
} else {
memset(dest + size, '<', marker_size);
size += marker_size;
@@ -170,6 +170,8 @@ static int fill_conflict_hunk(xdfenv_t *xe1, const char *name1,
memcpy(dest + size + 1, name1, marker1_size - 1);
size += marker1_size;
}
+ if (crlf)
+ dest[size++] = '\r';
dest[size++] = '\n';
}
@@ -180,7 +182,7 @@ static int fill_conflict_hunk(xdfenv_t *xe1, const char *name1,
if (style == XDL_MERGE_DIFF3) {
/* Shared preimage */
if (!dest) {
- size += marker_size + 1 + marker3_size;
+ size += marker_size + 1 + crlf + marker3_size;
} else {
memset(dest + size, '|', marker_size);
size += marker_size;
@@ -189,6 +191,8 @@ static int fill_conflict_hunk(xdfenv_t *xe1, const char *name1,
memcpy(dest + size + 1, name3, marker3_size - 1);
size += marker3_size;
}
+ if (crlf)
+ dest[size++] = '\r';
dest[size++] = '\n';
}
size += xdl_orig_copy(xe1, m->i0, m->chg0, 1,
@@ -196,10 +200,12 @@ static int fill_conflict_hunk(xdfenv_t *xe1, const char *name1,
}
if (!dest) {
- size += marker_size + 1;
+ size += marker_size + 1 + crlf;
} else {
memset(dest + size, '=', marker_size);
size += marker_size;
+ if (crlf)
+ dest[size++] = '\r';
dest[size++] = '\n';
}
@@ -207,7 +213,7 @@ static int fill_conflict_hunk(xdfenv_t *xe1, const char *name1,
size += xdl_recs_copy(xe2, m->i2, m->chg2, 1,
dest ? dest + size : NULL);
if (!dest) {
- size += marker_size + 1 + marker2_size;
+ size += marker_size + 1 + crlf + marker2_size;
} else {
memset(dest + size, '>', marker_size);
size += marker_size;
@@ -216,6 +222,8 @@ static int fill_conflict_hunk(xdfenv_t *xe1, const char *name1,
memcpy(dest + size + 1, name2, marker2_size - 1);
size += marker2_size;
}
+ if (crlf)
+ dest[size++] = '\r';
dest[size++] = '\n';
}
return size;
@@ -226,7 +234,7 @@ static int xdl_fill_merge_buffer(xdfenv_t *xe1, const char *name1,
const char *ancestor_name,
int favor,
xdmerge_t *m, char *dest, int style,
- int marker_size)
+ int crlf, int marker_size)
{
int size, i;
@@ -237,8 +245,8 @@ static int xdl_fill_merge_buffer(xdfenv_t *xe1, const char *name1,
if (m->mode == 0)
size = fill_conflict_hunk(xe1, name1, xe2, name2,
ancestor_name,
- size, i, style, m, dest,
- marker_size);
+ size, i, style, crlf, m,
+ dest, marker_size);
else if (m->mode & 3) {
/* Before conflicting part */
size += xdl_recs_copy(xe1, i, m->i1 - i, 0,
@@ -419,6 +427,7 @@ static int xdl_do_merge(xdfenv_t *xe1, xdchange_t *xscr1,
int level = xmp->level;
int style = xmp->style;
int favor = xmp->favor;
+ int crlf = xmp->crlf;
if (style == XDL_MERGE_DIFF3) {
/*
@@ -554,7 +563,7 @@ static int xdl_do_merge(xdfenv_t *xe1, xdchange_t *xscr1,
int size = xdl_fill_merge_buffer(xe1, name1, xe2, name2,
ancestor_name,
favor, changes, NULL, style,
- marker_size);
+ crlf, marker_size);
result->ptr = xdl_malloc(size);
if (!result->ptr) {
xdl_cleanup_merge(changes);
@@ -563,7 +572,7 @@ static int xdl_do_merge(xdfenv_t *xe1, xdchange_t *xscr1,
result->size = size;
xdl_fill_merge_buffer(xe1, name1, xe2, name2,
ancestor_name, favor, changes,
- result->ptr, style, marker_size);
+ result->ptr, style, crlf, marker_size);
}
return xdl_cleanup_merge(changes);
}