1 # remotenames.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 = 'remotenames' |
|
19 |
|
20 def readremotenamefile(repo, filename): |
|
21 """ |
|
22 reads a file from .hg/remotenames/ 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/remotenames/ 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/remotenames/" 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) |
|