Mercurial > public > mercurial-scm > hg
comparison mercurial/cmdutil.py @ 39278:53e532007878
cmdutil: return a revlog from openrevlog() and split function
The filelog class is a wrapper around a revlog instance. I have plans
to give manifests and the changelog a similar treatment.
When filelog was ported away from revlog and when I started writing
patches to do the same for manifests, I noticed that a lot of
debug* and perf* commands were relying on low-level revlog APIs
like start(), end(), deltaparent(), etc. For filelog, I added these
to the interface, even though I didn't want to because they don't
belong on a generic storage interface.
For manifest (and eventually changelog), the pain is too much to bear.
We need to cut the tight coupling.
These debug* and perf* commands use cmdutil.openrevlog() to obtain
a revlog instance.
This commit effectively renames openrevlog() to openstorage(), adds
an argument to ensure a revlog instance is returned, and introduces a
replacement openrevlog() that calls openstorage() such that a revlog
instance is returned.
By doing things this way, we allow the debug* and perf* commands to
still work on revlog-based repositories without having to expose
low-level revlog APIs in the storage interfaces.
The practical side-effect of this on the current code base is we return
a revlog instance instead of a filelog. The manifest and changelog are
not affected at this time.
Some of filelog's storage APIs are different from revlog. For example,
read() strips the optional header containing copy/rename metadata. This
may impact some perf* commands. But I don't think the impact is
worth worrying about.
Upcoming commits will port existing consumers to openstorage(), where
appropriate.
This commit does cause some test regressions when using the simple
store. These will be fixed as commands are ported to use storage APIs.
.. api:: cmdutil.openrevlog() now returns a revlog instance or aborts
Previously, it would return a storage object, which may not be a
revlog instance.
Use the new cmdutil.openstorage() API to return an object conforming
to the storage interface of the thing you are accessing if you don't
need a revlog instance.
Differential Revision: https://phab.mercurial-scm.org/D4354
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Tue, 14 Aug 2018 16:28:21 +0000 |
parents | 73cf21b2e8a6 |
children | 6b81d2ff118f |
comparison
equal
deleted
inserted
replaced
39277:f785073f792c | 39278:53e532007878 |
---|---|
1052 fp = repo.ui.fin | 1052 fp = repo.ui.fin |
1053 return _unclosablefile(fp) | 1053 return _unclosablefile(fp) |
1054 fn = makefilename(ctx, pat, **props) | 1054 fn = makefilename(ctx, pat, **props) |
1055 return open(fn, mode) | 1055 return open(fn, mode) |
1056 | 1056 |
1057 def openrevlog(repo, cmd, file_, opts): | 1057 def openstorage(repo, cmd, file_, opts, returnrevlog=False): |
1058 """opens the changelog, manifest, a filelog or a given revlog""" | 1058 """opens the changelog, manifest, a filelog or a given revlog""" |
1059 cl = opts['changelog'] | 1059 cl = opts['changelog'] |
1060 mf = opts['manifest'] | 1060 mf = opts['manifest'] |
1061 dir = opts['dir'] | 1061 dir = opts['dir'] |
1062 msg = None | 1062 msg = None |
1090 r = repo.manifestlog.getstorage(b'') | 1090 r = repo.manifestlog.getstorage(b'') |
1091 elif file_: | 1091 elif file_: |
1092 filelog = repo.file(file_) | 1092 filelog = repo.file(file_) |
1093 if len(filelog): | 1093 if len(filelog): |
1094 r = filelog | 1094 r = filelog |
1095 | |
1096 # Not all storage may be revlogs. If requested, try to return an actual | |
1097 # revlog instance. | |
1098 if returnrevlog: | |
1099 if isinstance(r, revlog.revlog): | |
1100 pass | |
1101 elif util.safehasattr(r, '_revlog'): | |
1102 r = r._revlog | |
1103 elif r is not None: | |
1104 raise error.Abort(_('%r does not appear to be a revlog') % r) | |
1105 | |
1095 if not r: | 1106 if not r: |
1107 if not returnrevlog: | |
1108 raise error.Abort(_('cannot give path to non-revlog')) | |
1109 | |
1096 if not file_: | 1110 if not file_: |
1097 raise error.CommandError(cmd, _('invalid arguments')) | 1111 raise error.CommandError(cmd, _('invalid arguments')) |
1098 if not os.path.isfile(file_): | 1112 if not os.path.isfile(file_): |
1099 raise error.Abort(_("revlog '%s' not found") % file_) | 1113 raise error.Abort(_("revlog '%s' not found") % file_) |
1100 r = revlog.revlog(vfsmod.vfs(pycompat.getcwd(), audit=False), | 1114 r = revlog.revlog(vfsmod.vfs(pycompat.getcwd(), audit=False), |
1101 file_[:-2] + ".i") | 1115 file_[:-2] + ".i") |
1102 return r | 1116 return r |
1117 | |
1118 def openrevlog(repo, cmd, file_, opts): | |
1119 """Obtain a revlog backing storage of an item. | |
1120 | |
1121 This is similar to ``openstorage()`` except it always returns a revlog. | |
1122 | |
1123 In most cases, a caller cares about the main storage object - not the | |
1124 revlog backing it. Therefore, this function should only be used by code | |
1125 that needs to examine low-level revlog implementation details. e.g. debug | |
1126 commands. | |
1127 """ | |
1128 return openstorage(repo, cmd, file_, opts, returnrevlog=True) | |
1103 | 1129 |
1104 def copy(ui, repo, pats, opts, rename=False): | 1130 def copy(ui, repo, pats, opts, rename=False): |
1105 # called with the repo lock held | 1131 # called with the repo lock held |
1106 # | 1132 # |
1107 # hgsep => pathname that uses "/" to separate directories | 1133 # hgsep => pathname that uses "/" to separate directories |