author | Martijn Pieters <mjpieters@fb.com> |
Mon, 15 Feb 2016 16:40:06 +0000 | |
changeset 28146 | 28024d0d42dc |
parent 28129 | 7c40b4b7f8f1 |
child 28148 | e8c2a60864fc |
permissions | -rw-r--r-- |
28129
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
1 |
# automv.py |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
2 |
# |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
3 |
# Copyright 2013-2016 Facebook, Inc. |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
4 |
# |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
5 |
# This software may be used and distributed according to the terms of the |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
6 |
# GNU General Public License version 2 or any later version. |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
7 |
"""Check for unrecorded moves at commit time (EXPERIMENTAL) |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
8 |
|
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
9 |
This extension checks at commit/amend time if any of the committed files |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
10 |
comes from an unrecorded mv. |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
11 |
|
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
12 |
The threshold at which a file is considered a move can be set with the |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
13 |
``automv.similarity`` config option; the default value is 1.00. |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
14 |
|
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
15 |
""" |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
16 |
from __future__ import absolute_import |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
17 |
|
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
18 |
from mercurial import ( |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
19 |
commands, |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
20 |
copies, |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
21 |
extensions, |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
22 |
scmutil, |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
23 |
similar |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
24 |
) |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
25 |
from mercurial.i18n import _ |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
26 |
|
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
27 |
def extsetup(ui): |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
28 |
entry = extensions.wrapcommand( |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
29 |
commands.table, 'commit', mvcheck) |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
30 |
entry[1].append( |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
31 |
('', 'no-automv', None, |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
32 |
_('disable automatic file move detection'))) |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
33 |
|
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
34 |
def mvcheck(orig, ui, repo, *pats, **opts): |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
35 |
disabled = opts.pop('no_automv', False) |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
36 |
if not disabled: |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
37 |
threshold = float(ui.config('automv', 'similarity', '1.00')) |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
38 |
if threshold > 0: |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
39 |
match = scmutil.match(repo[None], pats, opts) |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
40 |
added, removed = _interestingfiles(repo, match) |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
41 |
renames = _findrenames(repo, match, added, removed, threshold) |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
42 |
_markchanges(repo, renames) |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
43 |
|
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
44 |
# developer config: automv.testmode |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
45 |
if not ui.configbool('automv', 'testmode'): |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
46 |
return orig(ui, repo, *pats, **opts) |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
47 |
|
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
48 |
def _interestingfiles(repo, matcher): |
28146
28024d0d42dc
automv: simplify retrieving the status
Martijn Pieters <mjpieters@fb.com>
parents:
28129
diff
changeset
|
49 |
stat = repo.status(match=matcher) |
28129
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
50 |
added = stat[1] |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
51 |
removed = stat[2] |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
52 |
|
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
53 |
copy = copies._forwardcopies(repo['.'], repo[None], matcher) |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
54 |
# remove the copy files for which we already have copy info |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
55 |
added = [f for f in added if f not in copy] |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
56 |
|
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
57 |
return added, removed |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
58 |
|
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
59 |
def _findrenames(repo, matcher, added, removed, similarity): |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
60 |
"""Find renames from removed files of the current commit/amend files |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
61 |
to the added ones""" |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
62 |
renames = {} |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
63 |
if similarity > 0: |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
64 |
for src, dst, score in similar.findrenames( |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
65 |
repo, added, removed, similarity): |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
66 |
if repo.ui.verbose: |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
67 |
repo.ui.status( |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
68 |
_('detected move of %s as %s (%d%% similar)\n') % ( |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
69 |
matcher.rel(src), matcher.rel(dst), score * 100)) |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
70 |
renames[dst] = src |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
71 |
if renames: |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
72 |
repo.ui.status(_('detected move of %d files\n') % len(renames)) |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
73 |
return renames |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
74 |
|
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
75 |
def _markchanges(repo, renames): |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
76 |
"""Marks the files in renames as copied.""" |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
77 |
wctx = repo[None] |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
78 |
wlock = repo.wlock() |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
79 |
try: |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
80 |
for dst, src in renames.iteritems(): |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
81 |
wctx.copy(src, dst) |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
82 |
finally: |
7c40b4b7f8f1
automv: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
83 |
wlock.release() |