This is how it is done everywhere else.
But the logic here is a bit more complex because shallow clone
needs to reference the original linknode implementation. But
at least now all function implementations are defined in the
same place.
( )
hg-reviewers |
This is how it is done everywhere else.
But the logic here is a bit more complex because shallow clone
needs to reference the original linknode implementation. But
at least now all function implementations are defined in the
same place.
Lint Skipped |
Unit Tests Skipped |
Path | Packages | |||
---|---|---|---|---|
M | mercurial/changegroup.py (38 lines) |
Commit | Parents | Author | Summary | Date |
---|---|---|---|---|
Gregory Szorc | Aug 7 2018, 6:45 PM |
Status | Author | Revision | |
---|---|---|---|
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg |
mfdicts = None | mfdicts = None | ||||
if self._ellipses and self._isshallow: | if self._ellipses and self._isshallow: | ||||
mfdicts = [(self._repo.manifestlog[n].read(), lr) | mfdicts = [(self._repo.manifestlog[n].read(), lr) | ||||
for (n, lr) in mfs.iteritems()] | for (n, lr) in mfs.iteritems()] | ||||
mfs.clear() | mfs.clear() | ||||
clrevs = set(cl.rev(x) for x in clnodes) | clrevs = set(cl.rev(x) for x in clnodes) | ||||
if not fastpathlinkrev: | for chunk in self.generatefiles(changedfiles, commonrevs, | ||||
def linknodes(unused, fname): | source, mfdicts, fastpathlinkrev, | ||||
return fnodes.get(fname, {}) | fnodes, clrevs): | ||||
else: | |||||
cln = cl.node | |||||
def linknodes(filerevlog, fname): | |||||
llr = filerevlog.linkrev | |||||
fln = filerevlog.node | |||||
revs = ((r, llr(r)) for r in filerevlog) | |||||
return dict((fln(r), cln(lr)) for r, lr in revs if lr in clrevs) | |||||
for chunk in self.generatefiles(changedfiles, linknodes, commonrevs, | |||||
source, mfdicts): | |||||
yield chunk | yield chunk | ||||
yield self._close() | yield self._close() | ||||
if clnodes: | if clnodes: | ||||
repo.hook('outgoing', node=hex(clnodes[0]), source=source) | repo.hook('outgoing', node=hex(clnodes[0]), source=source) | ||||
def _generatechangelog(self, cl, nodes): | def _generatechangelog(self, cl, nodes): | ||||
for x in self._packmanifests(dir, store, revs, lookupfn): | for x in self._packmanifests(dir, store, revs, lookupfn): | ||||
size += len(x) | size += len(x) | ||||
yield x | yield x | ||||
self._verbosenote(_('%8.i (manifests)\n') % size) | self._verbosenote(_('%8.i (manifests)\n') % size) | ||||
yield self._manifestsend | yield self._manifestsend | ||||
# The 'source' parameter is useful for extensions | # The 'source' parameter is useful for extensions | ||||
def generatefiles(self, changedfiles, linknodes, commonrevs, source, | def generatefiles(self, changedfiles, commonrevs, source, | ||||
mfdicts): | mfdicts, fastpathlinkrev, fnodes, clrevs): | ||||
changedfiles = list(filter(self._filematcher, changedfiles)) | changedfiles = list(filter(self._filematcher, changedfiles)) | ||||
if not fastpathlinkrev: | |||||
def normallinknodes(unused, fname): | |||||
return fnodes.get(fname, {}) | |||||
else: | |||||
cln = self._repo.changelog.node | |||||
def normallinknodes(store, fname): | |||||
flinkrev = store.linkrev | |||||
fnode = store.node | |||||
revs = ((r, flinkrev(r)) for r in store) | |||||
return dict((fnode(r), cln(lr)) | |||||
for r, lr in revs if lr in clrevs) | |||||
if self._isshallow: | if self._isshallow: | ||||
# In a shallow clone, the linknodes callback needs to also include | # In a shallow clone, the linknodes callback needs to also include | ||||
# those file nodes that are in the manifests we sent but weren't | # those file nodes that are in the manifests we sent but weren't | ||||
# introduced by those manifests. | # introduced by those manifests. | ||||
commonctxs = [self._repo[c] for c in commonrevs] | commonctxs = [self._repo[c] for c in commonrevs] | ||||
oldlinknodes = linknodes | |||||
clrev = self._repo.changelog.rev | clrev = self._repo.changelog.rev | ||||
# Defining this function has a side-effect of overriding the | # Defining this function has a side-effect of overriding the | ||||
# function of the same name that was passed in as an argument. | # function of the same name that was passed in as an argument. | ||||
# TODO have caller pass in appropriate function. | # TODO have caller pass in appropriate function. | ||||
def linknodes(flog, fname): | def linknodes(flog, fname): | ||||
for c in commonctxs: | for c in commonctxs: | ||||
try: | try: | ||||
fnode = c.filenode(fname) | fnode = c.filenode(fname) | ||||
self._clrevtolocalrev[c.rev()] = flog.rev(fnode) | self._clrevtolocalrev[c.rev()] = flog.rev(fnode) | ||||
except error.ManifestLookupError: | except error.ManifestLookupError: | ||||
pass | pass | ||||
links = oldlinknodes(flog, fname) | links = normallinknodes(flog, fname) | ||||
if len(links) != len(mfdicts): | if len(links) != len(mfdicts): | ||||
for mf, lr in mfdicts: | for mf, lr in mfdicts: | ||||
fnode = mf.get(fname, None) | fnode = mf.get(fname, None) | ||||
if fnode in links: | if fnode in links: | ||||
links[fnode] = min(links[fnode], lr, key=clrev) | links[fnode] = min(links[fnode], lr, key=clrev) | ||||
elif fnode: | elif fnode: | ||||
links[fnode] = lr | links[fnode] = lr | ||||
return links | return links | ||||
else: | |||||
linknodes = normallinknodes | |||||
return self._generatefiles(changedfiles, linknodes, commonrevs, source) | return self._generatefiles(changedfiles, linknodes, commonrevs, source) | ||||
def _generatefiles(self, changedfiles, linknodes, commonrevs, source): | def _generatefiles(self, changedfiles, linknodes, commonrevs, source): | ||||
repo = self._repo | repo = self._repo | ||||
cl = repo.changelog | cl = repo.changelog | ||||
progress = repo.ui.makeprogress(_('bundling'), unit=_('files'), | progress = repo.ui.makeprogress(_('bundling'), unit=_('files'), | ||||
total=len(changedfiles)) | total=len(changedfiles)) |