Mercurial > public > mercurial-scm > hg
comparison mercurial/filemerge.py @ 27039:d7517deedf86
filemerge._picktool: only pick from nomerge tools for change/delete conflicts
For --tool or HGMERGE, we could have either:
(a) proceeded with the particular tool, then failed the merge.
(b) chosen to prompt regardless.
We're explicitly choosing (b) here, because it's effectively what we've been
doing so far and helps maintain an easier-to-use interface.
However, in future patches we're going to change the default selection from
'pick changed version' to 'leave unresolved'. That fixes most of the brokenness
involved with choice (b).
author | Siddharth Agarwal <sid0@fb.com> |
---|---|
date | Sun, 15 Nov 2015 21:40:15 -0800 |
parents | 58a4eb16e722 |
children | 1bde66b89bb2 |
comparison
equal
deleted
inserted
replaced
27038:58a4eb16e722 | 27039:d7517deedf86 |
---|---|
118 if p: | 118 if p: |
119 return p | 119 return p |
120 exe = _toolstr(ui, tool, "executable", tool) | 120 exe = _toolstr(ui, tool, "executable", tool) |
121 return util.findexe(util.expandpath(exe)) | 121 return util.findexe(util.expandpath(exe)) |
122 | 122 |
123 def _picktool(repo, ui, path, binary, symlink): | 123 def _picktool(repo, ui, path, binary, symlink, changedelete): |
124 def check(tool, pat, symlink, binary): | 124 def supportscd(tool): |
125 return tool in internals and internals[tool].mergetype == nomerge | |
126 | |
127 def check(tool, pat, symlink, binary, changedelete): | |
125 tmsg = tool | 128 tmsg = tool |
126 if pat: | 129 if pat: |
127 tmsg += " specified for " + pat | 130 tmsg += " specified for " + pat |
128 if not _findtool(ui, tool): | 131 if not _findtool(ui, tool): |
129 if pat: # explicitly requested tool deserves a warning | 132 if pat: # explicitly requested tool deserves a warning |
132 ui.note(_("couldn't find merge tool %s\n") % tmsg) | 135 ui.note(_("couldn't find merge tool %s\n") % tmsg) |
133 elif symlink and not _toolbool(ui, tool, "symlink"): | 136 elif symlink and not _toolbool(ui, tool, "symlink"): |
134 ui.warn(_("tool %s can't handle symlinks\n") % tmsg) | 137 ui.warn(_("tool %s can't handle symlinks\n") % tmsg) |
135 elif binary and not _toolbool(ui, tool, "binary"): | 138 elif binary and not _toolbool(ui, tool, "binary"): |
136 ui.warn(_("tool %s can't handle binary\n") % tmsg) | 139 ui.warn(_("tool %s can't handle binary\n") % tmsg) |
140 elif changedelete and not supportscd(tool): | |
141 # the nomerge tools are the only tools that support change/delete | |
142 # conflicts | |
143 pass | |
137 elif not util.gui() and _toolbool(ui, tool, "gui"): | 144 elif not util.gui() and _toolbool(ui, tool, "gui"): |
138 ui.warn(_("tool %s requires a GUI\n") % tmsg) | 145 ui.warn(_("tool %s requires a GUI\n") % tmsg) |
139 else: | 146 else: |
140 return True | 147 return True |
141 return False | 148 return False |
143 # internal config: ui.forcemerge | 150 # internal config: ui.forcemerge |
144 # forcemerge comes from command line arguments, highest priority | 151 # forcemerge comes from command line arguments, highest priority |
145 force = ui.config('ui', 'forcemerge') | 152 force = ui.config('ui', 'forcemerge') |
146 if force: | 153 if force: |
147 toolpath = _findtool(ui, force) | 154 toolpath = _findtool(ui, force) |
148 if toolpath: | 155 if changedelete and not supportscd(toolpath): |
149 return (force, util.shellquote(toolpath)) | 156 return ":prompt", None |
150 else: | 157 else: |
151 # mimic HGMERGE if given tool not found | 158 if toolpath: |
152 return (force, force) | 159 return (force, util.shellquote(toolpath)) |
160 else: | |
161 # mimic HGMERGE if given tool not found | |
162 return (force, force) | |
153 | 163 |
154 # HGMERGE takes next precedence | 164 # HGMERGE takes next precedence |
155 hgmerge = os.environ.get("HGMERGE") | 165 hgmerge = os.environ.get("HGMERGE") |
156 if hgmerge: | 166 if hgmerge: |
157 return (hgmerge, hgmerge) | 167 if changedelete and not supportscd(hgmerge): |
168 return ":prompt", None | |
169 else: | |
170 return (hgmerge, hgmerge) | |
158 | 171 |
159 # then patterns | 172 # then patterns |
160 for pat, tool in ui.configitems("merge-patterns"): | 173 for pat, tool in ui.configitems("merge-patterns"): |
161 mf = match.match(repo.root, '', [pat]) | 174 mf = match.match(repo.root, '', [pat]) |
162 if mf(path) and check(tool, pat, symlink, False): | 175 if mf(path) and check(tool, pat, symlink, False, changedelete): |
163 toolpath = _findtool(ui, tool) | 176 toolpath = _findtool(ui, tool) |
164 return (tool, util.shellquote(toolpath)) | 177 return (tool, util.shellquote(toolpath)) |
165 | 178 |
166 # then merge tools | 179 # then merge tools |
167 tools = {} | 180 tools = {} |
174 disabled.add(t) | 187 disabled.add(t) |
175 names = tools.keys() | 188 names = tools.keys() |
176 tools = sorted([(-p, t) for t, p in tools.items() if t not in disabled]) | 189 tools = sorted([(-p, t) for t, p in tools.items() if t not in disabled]) |
177 uimerge = ui.config("ui", "merge") | 190 uimerge = ui.config("ui", "merge") |
178 if uimerge: | 191 if uimerge: |
179 if uimerge not in names: | 192 # external tools defined in uimerge won't be able to handle |
193 # change/delete conflicts | |
194 if uimerge not in names and not changedelete: | |
180 return (uimerge, uimerge) | 195 return (uimerge, uimerge) |
181 tools.insert(0, (None, uimerge)) # highest priority | 196 tools.insert(0, (None, uimerge)) # highest priority |
182 tools.append((None, "hgmerge")) # the old default, if found | 197 tools.append((None, "hgmerge")) # the old default, if found |
183 for p, t in tools: | 198 for p, t in tools: |
184 if check(t, None, symlink, binary): | 199 if check(t, None, symlink, binary, changedelete): |
185 toolpath = _findtool(ui, t) | 200 toolpath = _findtool(ui, t) |
186 return (t, util.shellquote(toolpath)) | 201 return (t, util.shellquote(toolpath)) |
187 | 202 |
188 # internal merge or prompt as last resort | 203 # internal merge or prompt as last resort |
189 if symlink or binary: | 204 if symlink or binary or changedelete: |
190 return ":prompt", None | 205 return ":prompt", None |
191 return ":merge", None | 206 return ":merge", None |
192 | 207 |
193 def _eoltype(data): | 208 def _eoltype(data): |
194 "Guess the EOL type of a file" | 209 "Guess the EOL type of a file" |
533 | 548 |
534 ui = repo.ui | 549 ui = repo.ui |
535 fd = fcd.path() | 550 fd = fcd.path() |
536 binary = fcd.isbinary() or fco.isbinary() or fca.isbinary() | 551 binary = fcd.isbinary() or fco.isbinary() or fca.isbinary() |
537 symlink = 'l' in fcd.flags() + fco.flags() | 552 symlink = 'l' in fcd.flags() + fco.flags() |
538 tool, toolpath = _picktool(repo, ui, fd, binary, symlink) | 553 changedelete = fcd.isabsent() or fco.isabsent() |
554 tool, toolpath = _picktool(repo, ui, fd, binary, symlink, changedelete) | |
539 if tool in internals and tool.startswith('internal:'): | 555 if tool in internals and tool.startswith('internal:'): |
540 # normalize to new-style names (':merge' etc) | 556 # normalize to new-style names (':merge' etc) |
541 tool = tool[len('internal'):] | 557 tool = tool[len('internal'):] |
542 ui.debug("picked tool '%s' for %s (binary %s symlink %s)\n" % | 558 ui.debug("picked tool '%s' for %s (binary %s symlink %s)\n" % |
543 (tool, fd, binary, symlink)) | 559 (tool, fd, binary, symlink)) |