##// END OF EJS Templates
run-tests: align call argument on string...
run-tests: align call argument on string The real hg path is bytes and need to be converted to align with the other arguments.

File last commit:

r52756:f4733654 default
r53435:8adfaa5a default
Show More
automv.py
128 lines | 4.1 KiB | text/x-python | PythonLexer
Martijn Pieters
automv: new experimental extension...
r28129 # automv.py
#
# Copyright 2013-2016 Facebook, Inc.
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
Jun Wu
automv: use lowercase for docstring title...
r31599 """check for unrecorded moves at commit time (EXPERIMENTAL)
Martijn Pieters
automv: new experimental extension...
r28129
This extension checks at commit/amend time if any of the committed files
comes from an unrecorded mv.
The threshold at which a file is considered a move can be set with the
Martijn Pieters
automv: switch to specifying the similarity as an integer (0-100)...
r28152 ``automv.similarity`` config option. This option takes a percentage between 0
Martijn Pieters
automv: use 95 as the default similarity threshold...
r28183 (disabled) and 100 (files must be identical), the default is 95.
Martijn Pieters
automv: new experimental extension...
r28129
"""
Martijn Pieters
automv: use 95 as the default similarity threshold...
r28183
# Using 95 as a default similarity is based on an analysis of the mercurial
# repositories of the cpython, mozilla-central & mercurial repositories, as
# well as 2 very large facebook repositories. At 95 50% of all potential
# missed moves would be caught, as well as correspond with 87% of all
# explicitly marked moves. Together, 80% of moved files are 95% similar or
# more.
#
# See http://markmail.org/thread/5pxnljesvufvom57 for context.
Matt Harbison
typing: add `from __future__ import annotations` to most files...
r52756 from __future__ import annotations
Martijn Pieters
automv: new experimental extension...
r28129
Yuya Nishihara
py3: move up symbol imports to enforce import-checker rules...
r29205 from mercurial.i18n import _
Martijn Pieters
automv: new experimental extension...
r28129 from mercurial import (
commands,
copies,
Martijn Pieters
automv: use 95 as the default similarity threshold...
r28183 error,
Martijn Pieters
automv: new experimental extension...
r28129 extensions,
Pulkit Goyal
py3: handle keyword arguments in hgext/automv.py...
r34972 pycompat,
configitems: register the 'automv.similarity' config...
r33185 registrar,
Martijn Pieters
automv: new experimental extension...
r28129 scmutil,
Augie Fackler
formatting: blacken the codebase...
r43346 similar,
Martijn Pieters
automv: new experimental extension...
r28129 )
configitems: register the 'automv.similarity' config...
r33185 configtable = {}
configitem = registrar.configitem(configtable)
Augie Fackler
formatting: blacken the codebase...
r43346 configitem(
Augie Fackler
formating: upgrade to black 20.8b1...
r46554 b'automv',
b'similarity',
default=95,
configitems: register the 'automv.similarity' config...
r33185 )
Augie Fackler
formatting: blacken the codebase...
r43346
Martijn Pieters
automv: new experimental extension...
r28129 def extsetup(ui):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 entry = extensions.wrapcommand(commands.table, b'commit', mvcheck)
Martijn Pieters
automv: new experimental extension...
r28129 entry[1].append(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 (b'', b'no-automv', None, _(b'disable automatic file move detection'))
Augie Fackler
formatting: blacken the codebase...
r43346 )
Martijn Pieters
automv: new experimental extension...
r28129
def mvcheck(orig, ui, repo, *pats, **opts):
Martijn Pieters
automv: improve function docstrings
r28149 """Hook to check for moves at commit time"""
Martijn Pieters
automv: do not release lock between marking files and the actual commit
r28151 renames = None
Matt Harbison
automv: migrate `opts` to native kwargs
r51763 disabled = opts.pop('no_automv', False)
automv: lock the repository before searching for renames...
r51019 with repo.wlock():
if not disabled:
threshold = ui.configint(b'automv', b'similarity')
if not 0 <= threshold <= 100:
raise error.Abort(
_(b'automv.similarity must be between 0 and 100')
)
if threshold > 0:
Matt Harbison
automv: migrate `opts` to native kwargs
r51763 match = scmutil.match(
repo[None], pats, pycompat.byteskwargs(opts)
)
automv: lock the repository before searching for renames...
r51019 added, removed = _interestingfiles(repo, match)
uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
renames = _findrenames(
repo, uipathfn, added, removed, threshold / 100.0
)
Martijn Pieters
automv: do not release lock between marking files and the actual commit
r28151
if renames is not None:
dirstate: use `dirstate.change_files` to scope the change in `automv`...
r50938 with repo.dirstate.changing_files(repo):
# XXX this should be wider and integrated with the commit
# transaction. At the same time as we do the `addremove` logic
# for commit. However we can't really do better with the
# current extension structure, and this is not worse than what
# happened before.
scmutil._markchanges(repo, (), (), renames)
Matt Harbison
automv: migrate `opts` to native kwargs
r51763 return orig(ui, repo, *pats, **opts)
Martijn Pieters
automv: new experimental extension...
r28129
Augie Fackler
formatting: blacken the codebase...
r43346
Martijn Pieters
automv: new experimental extension...
r28129 def _interestingfiles(repo, matcher):
Martijn Pieters
automv: improve function docstrings
r28149 """Find what files were added or removed in this commit.
Returns a tuple of two lists: (added, removed). Only files not *already*
marked as moved are included in the added list.
"""
Martijn Pieters
automv: simplify retrieving the status...
r28146 stat = repo.status(match=matcher)
Martin von Zweigbergk
automv: access status fields by name, not index...
r42747 added = stat.added
removed = stat.removed
Martijn Pieters
automv: new experimental extension...
r28129
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 copy = copies.pathcopies(repo[b'.'], repo[None], matcher)
Martijn Pieters
automv: new experimental extension...
r28129 # remove the copy files for which we already have copy info
added = [f for f in added if f not in copy]
return added, removed
Augie Fackler
formatting: blacken the codebase...
r43346
Martin von Zweigbergk
automv: respect ui.relative-paths...
r41809 def _findrenames(repo, uipathfn, added, removed, similarity):
Martijn Pieters
automv: improve function docstrings
r28149 """Find what files in added are really moved files.
Any file named in removed that is at least similarity% similar to a file
in added is seen as a rename.
"""
Martijn Pieters
automv: new experimental extension...
r28129 renames = {}
if similarity > 0:
for src, dst, score in similar.findrenames(
Augie Fackler
formatting: blacken the codebase...
r43346 repo, added, removed, similarity
):
Martijn Pieters
automv: new experimental extension...
r28129 if repo.ui.verbose:
repo.ui.status(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'detected move of %s as %s (%d%% similar)\n')
Augie Fackler
formatting: blacken the codebase...
r43346 % (uipathfn(src), uipathfn(dst), score * 100)
)
Martijn Pieters
automv: new experimental extension...
r28129 renames[dst] = src
if renames:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 repo.ui.status(_(b'detected move of %d files\n') % len(renames))
Martijn Pieters
automv: new experimental extension...
r28129 return renames