comparison mercurial/merge.py @ 16093:7e30f5f2285f

merge: refactor unknown file conflict checking Previously, we would do a full working directory walk including unknown files to perform a merge. In many cases, this was painful because unknown files greatly outnumbered tracked files and generally had no useful effect on the merge. Here we instead wait until we find a file in the destination that's not tracked locally and detect if it exists and is not ignored. This is usually cheaper but can be -more- expensive in the case where we're adding a huge number of files. On the other hand, the cost of statting the new files should be dwarfed by the cost of eventually writing them. In this version, case collisions are detected implicitly by os.path.exists and wctx[f] lookup.
author Matt Mackall <mpm@selenic.com>
date Thu, 09 Feb 2012 16:50:19 -0600
parents 914bc95e227b
children 0776a6cababe
comparison
equal deleted inserted replaced
16092:914bc95e227b 16093:7e30f5f2285f
79 del self._state[dfile] 79 del self._state[dfile]
80 elif not r: 80 elif not r:
81 self.mark(dfile, 'r') 81 self.mark(dfile, 'r')
82 return r 82 return r
83 83
84 def _checkunknown(wctx, mctx, folding): 84 def _checkunknownfile(repo, wctx, mctx, f):
85 return (not repo.dirstate._ignore(f)
86 and os.path.exists(repo.wjoin(f))
87 and mctx[f].cmp(wctx[f]))
88
89 def _checkunknown(repo, wctx, mctx):
85 "check for collisions between unknown files and files in mctx" 90 "check for collisions between unknown files and files in mctx"
86 if folding:
87 foldf = util.normcase
88 else:
89 foldf = lambda fn: fn
90 folded = {}
91 for fn in mctx:
92 folded[foldf(fn)] = fn
93 91
94 error = False 92 error = False
95 for fn in wctx.unknown(): 93 for f in mctx:
96 f = foldf(fn) 94 if f not in wctx and _checkunknownfile(repo, wctx, mctx, f):
97 if f in folded and mctx[folded[f]].cmp(wctx[f]):
98 error = True 95 error = True
99 wctx._repo.ui.warn(_("%s: untracked file differs\n") % fn) 96 wctx._repo.ui.warn(_("%s: untracked file differs\n") % f)
100 if error: 97 if error:
101 raise util.Abort(_("untracked files in working directory differ " 98 raise util.Abort(_("untracked files in working directory differ "
102 "from files in requested revision")) 99 "from files in requested revision"))
103 100
104 def _checkcollision(mctx, wctx): 101 def _checkcollision(mctx, wctx):
563 ### calculate phase 560 ### calculate phase
564 action = [] 561 action = []
565 wc.status(unknown=True) # prime cache 562 wc.status(unknown=True) # prime cache
566 folding = not util.checkcase(repo.path) 563 folding = not util.checkcase(repo.path)
567 if not force: 564 if not force:
568 _checkunknown(wc, p2, folding) 565 _checkunknown(repo, wc, p2)
569 if folding: 566 if folding:
570 _checkcollision(p2, branchmerge and p1) 567 _checkcollision(p2, branchmerge and p1)
571 action += _forgetremoved(wc, p2, branchmerge) 568 action += _forgetremoved(wc, p2, branchmerge)
572 action += manifestmerge(repo, wc, p2, pa, overwrite, partial) 569 action += manifestmerge(repo, wc, p2, pa, overwrite, partial)
573 570