comparison mercurial/logexchange.py @ 35347:a29fe459fc49

remotenames: rename related file and storage dir to logexchange This patch renames remotenames.py to logexchange.py, test-remotenames.t to test-logexchange.t. Also this patch renames the directory in which the data is stored from remotenames to logexchange. After this patch, data about bookmarks and branches from a server we pull is stored in `.hg/logexchange/(bookmarks|branches)` files. Thanks to smf for the suggestion. Differential Revision: https://phab.mercurial-scm.org/D1607
author Pulkit Goyal <7895pulkit@gmail.com>
date Thu, 07 Dec 2017 00:26:45 +0530
parents mercurial/remotenames.py@2ea6e42ed15e
children 62a428bf6359
comparison
equal deleted inserted replaced
35346:9eb19b13e92a 35347:a29fe459fc49
1 # logexchange.py
2 #
3 # Copyright 2017 Augie Fackler <raf@durin42.com>
4 # Copyright 2017 Sean Farley <sean@farley.io>
5 #
6 # This software may be used and distributed according to the terms of the
7 # GNU General Public License version 2 or any later version.
8
9 from __future__ import absolute_import
10
11 from .node import hex
12
13 from . import (
14 vfs as vfsmod,
15 )
16
17 # directory name in .hg/ in which remotenames files will be present
18 remotenamedir = 'logexchange'
19
20 def readremotenamefile(repo, filename):
21 """
22 reads a file from .hg/logexchange/ directory and yields it's content
23 filename: the file to be read
24 yield a tuple (node, remotepath, name)
25 """
26
27 vfs = vfsmod.vfs(repo.vfs.join(remotenamedir))
28 if not vfs.exists(filename):
29 return
30 f = vfs(filename)
31 lineno = 0
32 for line in f:
33 line = line.strip()
34 if not line:
35 continue
36 # contains the version number
37 if lineno == 0:
38 lineno += 1
39 try:
40 node, remote, rname = line.split('\0')
41 yield node, remote, rname
42 except ValueError:
43 pass
44
45 f.close()
46
47 def readremotenames(repo):
48 """
49 read the details about the remotenames stored in .hg/logexchange/ and
50 yields a tuple (node, remotepath, name). It does not yields information
51 about whether an entry yielded is branch or bookmark. To get that
52 information, call the respective functions.
53 """
54
55 for bmentry in readremotenamefile(repo, 'bookmarks'):
56 yield bmentry
57 for branchentry in readremotenamefile(repo, 'branches'):
58 yield branchentry
59
60 def writeremotenamefile(repo, remotepath, names, nametype):
61 vfs = vfsmod.vfs(repo.vfs.join(remotenamedir))
62 f = vfs(nametype, 'w', atomictemp=True)
63 # write the storage version info on top of file
64 # version '0' represents the very initial version of the storage format
65 f.write('0\n\n')
66
67 olddata = set(readremotenamefile(repo, nametype))
68 # re-save the data from a different remote than this one.
69 for node, oldpath, rname in sorted(olddata):
70 if oldpath != remotepath:
71 f.write('%s\0%s\0%s\n' % (node, oldpath, rname))
72
73 for name, node in sorted(names.iteritems()):
74 if nametype == "branches":
75 for n in node:
76 f.write('%s\0%s\0%s\n' % (n, remotepath, name))
77 elif nametype == "bookmarks":
78 if node:
79 f.write('%s\0%s\0%s\n' % (node, remotepath, name))
80
81 f.close()
82
83 def saveremotenames(repo, remotepath, branches=None, bookmarks=None):
84 """
85 save remotenames i.e. remotebookmarks and remotebranches in their
86 respective files under ".hg/logexchange/" directory.
87 """
88 wlock = repo.wlock()
89 try:
90 if bookmarks:
91 writeremotenamefile(repo, remotepath, bookmarks, 'bookmarks')
92 if branches:
93 writeremotenamefile(repo, remotepath, branches, 'branches')
94 finally:
95 wlock.release()
96
97 def pullremotenames(localrepo, remoterepo):
98 """
99 pulls bookmarks and branches information of the remote repo during a
100 pull or clone operation.
101 localrepo is our local repository
102 remoterepo is the peer instance
103 """
104 remotepath = remoterepo.url()
105 bookmarks = remoterepo.listkeys('bookmarks')
106 # on a push, we don't want to keep obsolete heads since
107 # they won't show up as heads on the next pull, so we
108 # remove them here otherwise we would require the user
109 # to issue a pull to refresh the storage
110 bmap = {}
111 repo = localrepo.unfiltered()
112 for branch, nodes in remoterepo.branchmap().iteritems():
113 bmap[branch] = []
114 for node in nodes:
115 if node in repo and not repo[node].obsolete():
116 bmap[branch].append(hex(node))
117
118 saveremotenames(localrepo, remotepath, bmap, bookmarks)