当扩展(插件)想要更改表示本地存储库的对象时,在Mercurial(分布式修订控制系统)中对此类实例进行重分类。该对象被调用repo
,并且最初是一个localrepo
实例。它依次传递给每个扩展,并在需要时扩展将定义一个新类,该新类是该子类的子类,repo.__class__
并将其类更改repo
为该新子类!
def reposetup(ui, repo):
# ...
class bookmark_repo(repo.__class__):
def rollback(self):
if os.path.exists(self.join('undo.bookmarks')):
util.rename(self.join('undo.bookmarks'), self.join('bookmarks'))
return super(bookmark_repo, self).rollback()
# ...
repo.__class__ = bookmark_repo
扩展名(我从书签扩展名中获取了代码)定义了一个名为的模块级函数reposetup
。在初始化扩展并传递ui
(用户界面)和repo
(存储库)参数时,Mercurial将调用此方法。
然后,该函数定义repo
碰巧是任何类的子类。这将 不 足够简单的子类localrepo
,因为扩展需要能够延长对方。因此,如果第一个扩展名更改repo.__class__
为foo_repo
,则下一个扩展名应更改repo.__class__
为的子类,foo_repo
而不仅仅是的子类localrepo
。最后,该函数将更改instanceø的类,就像您在代码中所做的一样。