@matheusbsbs / matheus-bagliano / commits / 4e5dd044c6
Fork 0

merge-recursive: options to ignore whitespace changes

Add support for merging with ignoring line endings (specifically --ignore-space-at-eol) when using recursive merging. This is as a strategy-option, so that you can do: git merge --strategy-option=ignore-space-at-eol <branch> and git rebase --strategy-option=ignore-space-at-eol <branch> This can be useful for coping with line-ending damage (Xcode 3.1 has a nasty habit of converting all CRLFs to LFs, and VC6 tends to just use CRLFs for inserted lines). The only option I need is ignore-space-at-eol, but while at it, include the other xdiff whitespace options (ignore-space-change, ignore-all-space), too. [jn: with documentation] Signed-off-by: Justin Frankel <justin@cockos.com> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Justin Frankel committed Aug 26, 2010 at 00:51 UTC 4e5dd044c62f2a82de083e7cd46cad7b0d3465ae
3 files changed +207
Documentation/merge-strategies.txt
+15
@@ -47,6 +47,21 @@ patience;;
47 this when the branches to be merged have diverged wildly.
48 See also linkgit:git-diff[1] `--patience`.
49
50 +ignore-space-change;;
51 +ignore-all-space;;
52 +ignore-space-at-eol;;
53 + Treats lines with the indicated type of whitespace change as
54 + unchanged for the sake of a three-way merge. Whitespace
55 + changes mixed with other changes to a line are not ignored.
56 + See also linkgit:git-diff[1] `-b`, `-w`, and
57 + `--ignore-space-at-eol`.
58 ++
59 +* If 'their' version only introduces whitespace changes to a line,
60 + 'our' version is used;
61 +* If 'our' version introduces whitespace changes but 'their'
62 + version includes a substantial change, 'their' version is used;
63 +* Otherwise, the merge proceeds in the usual way.
64 +
65 renormalize;;
66 This runs a virtual check-out and check-in of all three stages
67 of a file when resolving a three-way merge. This option is
merge-recursive.c
+6
@@ -1515,6 +1515,12 @@ int parse_merge_opt(struct merge_options *o, const char *s)
1515 o->subtree_shift = s + strlen("subtree=");
1516 else if (!strcmp(s, "patience"))
1517 o->xdl_opts |= XDF_PATIENCE_DIFF;
1518 + else if (!strcmp(s, "ignore-space-change"))
1519 + o->xdl_opts |= XDF_IGNORE_WHITESPACE_CHANGE;
1520 + else if (!strcmp(s, "ignore-all-space"))
1521 + o->xdl_opts |= XDF_IGNORE_WHITESPACE;
1522 + else if (!strcmp(s, "ignore-space-at-eol"))
1523 + o->xdl_opts |= XDF_IGNORE_WHITESPACE_AT_EOL;
1524 else if (!strcmp(s, "renormalize"))
1525 o->renormalize = 1;
1526 else if (!strcmp(s, "no-renormalize"))
t/t3032-merge-recursive-options.sh new
+186
@@ -0,0 +1,186 @@
1 +#!/bin/sh
2 +
3 +test_description='merge-recursive options
4 +
5 +* [master] Clarify
6 + ! [remote] Remove cruft
7 +--
8 + + [remote] Remove cruft
9 +* [master] Clarify
10 +*+ [remote^] Initial revision
11 +* ok 1: setup
12 +'
13 +
14 +. ./test-lib.sh
15 +
16 +test_expect_success 'setup' '
17 + conflict_hunks () {
18 + sed -n -e "
19 + /^<<<</ b inconflict
20 + b
21 + : inconflict
22 + p
23 + /^>>>>/ b
24 + n
25 + b inconflict
26 + " "$@"
27 + } &&
28 +
29 + cat <<-\EOF >text.txt &&
30 + Hope, he says, cherishes the soul of him who lives in
31 + justice and holiness and is the nurse of his age and the
32 + companion of his journey;--hope which is mightiest to sway
33 + the restless soul of man.
34 +
35 + How admirable are his words! And the great blessing of riches, I do
36 + not say to every man, but to a good man, is, that he has had no
37 + occasion to deceive or to defraud others, either intentionally or
38 + unintentionally; and when he departs to the world below he is not in
39 + any apprehension about offerings due to the gods or debts which he owes
40 + to men. Now to this peace of mind the possession of wealth greatly
41 + contributes; and therefore I say, that, setting one thing against
42 + another, of the many advantages which wealth has to give, to a man of
43 + sense this is in my opinion the greatest.
44 +
45 + Well said, Cephalus, I replied; but as concerning justice, what is
46 + it?--to speak the truth and to pay your debts--no more than this? And
47 + even to this are there not exceptions? Suppose that a friend when in
48 + his right mind has deposited arms with me and he asks for them when he
49 + is not in his right mind, ought I to give them back to him? No one
50 + would say that I ought or that I should be right in doing so, any more
51 + than they would say that I ought always to speak the truth to one who
52 + is in his condition.
53 +
54 + You are quite right, he replied.
55 +
56 + But then, I said, speaking the truth and paying your debts is not a
57 + correct definition of justice.
58 +
59 + CEPHALUS - SOCRATES - POLEMARCHUS
60 +
61 + Quite correct, Socrates, if Simonides is to be believed, said
62 + Polemarchus interposing.
63 +
64 + I fear, said Cephalus, that I must go now, for I have to look after the
65 + sacrifices, and I hand over the argument to Polemarchus and the company.
66 + EOF
67 + git add text.txt &&
68 + test_tick &&
69 + git commit -m "Initial revision" &&
70 +
71 + git checkout -b remote &&
72 + sed -e "
73 + s/\. /\. /g
74 + s/[?] /? /g
75 + s/ / /g
76 + s/--/---/g
77 + s/but as concerning/but as con cerning/
78 + /CEPHALUS - SOCRATES - POLEMARCHUS/ d
79 + " text.txt >text.txt+ &&
80 + mv text.txt+ text.txt &&
81 + git commit -a -m "Remove cruft" &&
82 +
83 + git checkout master &&
84 + sed -e "
85 + s/\(not in his right mind\),\(.*\)/\1;\2Q/
86 + s/Quite correct\(.*\)/It is too correct\1Q/
87 + s/unintentionally/un intentionally/
88 + /un intentionally/ s/$/Q/
89 + s/Polemarchus interposing./Polemarchus, interposing.Q/
90 + /justice and holiness/ s/$/Q/
91 + /pay your debts/ s/$/Q/
92 + " text.txt | q_to_cr >text.txt+ &&
93 + mv text.txt+ text.txt &&
94 + git commit -a -m "Clarify" &&
95 + git show-branch --all
96 +'
97 +
98 +test_expect_success 'naive merge fails' '
99 + git read-tree --reset -u HEAD &&
100 + test_must_fail git merge-recursive HEAD^ -- HEAD remote &&
101 + test_must_fail git update-index --refresh &&
102 + grep "<<<<<<" text.txt
103 +'
104 +
105 +test_expect_success '--ignore-space-change makes merge succeed' '
106 + git read-tree --reset -u HEAD &&
107 + git merge-recursive --ignore-space-change HEAD^ -- HEAD remote
108 +'
109 +
110 +test_expect_success '--ignore-space-change: our w/s-only change wins' '
111 + q_to_cr <<-\EOF >expected &&
112 + justice and holiness and is the nurse of his age and theQ
113 + EOF
114 +
115 + git read-tree --reset -u HEAD &&
116 + git merge-recursive --ignore-space-change HEAD^ -- HEAD remote &&
117 + grep "justice and holiness" text.txt >actual &&
118 + test_cmp expected actual
119 +'
120 +
121 +test_expect_success '--ignore-space-change: their real change wins over w/s' '
122 + cat <<-\EOF >expected &&
123 + it?---to speak the truth and to pay your debts---no more than this? And
124 + EOF
125 +
126 + git read-tree --reset -u HEAD &&
127 + git merge-recursive --ignore-space-change HEAD^ -- HEAD remote &&
128 + grep "pay your debts" text.txt >actual &&
129 + test_cmp expected actual
130 +'
131 +
132 +test_expect_success '--ignore-space-change: does not ignore new spaces' '
133 + cat <<-\EOF >expected1 &&
134 + Well said, Cephalus, I replied; but as con cerning justice, what is
135 + EOF
136 + q_to_cr <<-\EOF >expected2 &&
137 + un intentionally; and when he departs to the world below he is not inQ
138 + EOF
139 +
140 + git read-tree --reset -u HEAD &&
141 + git merge-recursive --ignore-space-change HEAD^ -- HEAD remote &&
142 + grep "Well said" text.txt >actual1 &&
143 + grep "when he departs" text.txt >actual2 &&
144 + test_cmp expected1 actual1 &&
145 + test_cmp expected2 actual2
146 +'
147 +
148 +test_expect_success '--ignore-all-space drops their new spaces' '
149 + cat <<-\EOF >expected &&
150 + Well said, Cephalus, I replied; but as concerning justice, what is
151 + EOF
152 +
153 + git read-tree --reset -u HEAD &&
154 + git merge-recursive --ignore-all-space HEAD^ -- HEAD remote &&
155 + grep "Well said" text.txt >actual &&
156 + test_cmp expected actual
157 +'
158 +
159 +test_expect_success '--ignore-all-space keeps our new spaces' '
160 + q_to_cr <<-\EOF >expected &&
161 + un intentionally; and when he departs to the world below he is not inQ
162 + EOF
163 +
164 + git read-tree --reset -u HEAD &&
165 + git merge-recursive --ignore-all-space HEAD^ -- HEAD remote &&
166 + grep "when he departs" text.txt >actual &&
167 + test_cmp expected actual
168 +'
169 +
170 +test_expect_success '--ignore-space-at-eol' '
171 + q_to_cr <<-\EOF >expected &&
172 + <<<<<<< HEAD
173 + is not in his right mind; ought I to give them back to him? No oneQ
174 + =======
175 + is not in his right mind, ought I to give them back to him? No one
176 + >>>>>>> remote
177 + EOF
178 +
179 + git read-tree --reset -u HEAD &&
180 + test_must_fail git merge-recursive --ignore-space-at-eol \
181 + HEAD^ -- HEAD remote &&
182 + conflict_hunks text.txt >actual &&
183 + test_cmp expected actual
184 +'
185 +
186 +test_done