##// END OF EJS Templates
share: use the 'sharedpath' attr on repo instead of reloading from the file...
Matt Harbison -
r23626:012a7b48 default
parent child Browse files
Show More
@@ -1,130 +1,125
1 1 # Copyright 2006, 2007 Matt Mackall <mpm@selenic.com>
2 2 #
3 3 # This software may be used and distributed according to the terms of the
4 4 # GNU General Public License version 2 or any later version.
5 5
6 6 '''share a common history between several working directories'''
7 7
8 8 from mercurial.i18n import _
9 9 from mercurial import cmdutil, hg, util, extensions, bookmarks
10 10 from mercurial.hg import repository, parseurl
11 11 import errno
12 12
13 13 cmdtable = {}
14 14 command = cmdutil.command(cmdtable)
15 15 testedwith = 'internal'
16 16
17 17 @command('share',
18 18 [('U', 'noupdate', None, _('do not create a working copy')),
19 19 ('B', 'bookmarks', None, _('also share bookmarks'))],
20 20 _('[-U] [-B] SOURCE [DEST]'),
21 21 norepo=True)
22 22 def share(ui, source, dest=None, noupdate=False, bookmarks=False):
23 23 """create a new shared repository
24 24
25 25 Initialize a new repository and working directory that shares its
26 26 history (and optionally bookmarks) with another repository.
27 27
28 28 .. note::
29 29
30 30 using rollback or extensions that destroy/modify history (mq,
31 31 rebase, etc.) can cause considerable confusion with shared
32 32 clones. In particular, if two shared clones are both updated to
33 33 the same changeset, and one of them destroys that changeset
34 34 with rollback, the other clone will suddenly stop working: all
35 35 operations will fail with "abort: working directory has unknown
36 36 parent". The only known workaround is to use debugsetparents on
37 37 the broken clone to reset it to a changeset that still exists.
38 38 """
39 39
40 40 return hg.share(ui, source, dest, not noupdate, bookmarks)
41 41
42 42 @command('unshare', [], '')
43 43 def unshare(ui, repo):
44 44 """convert a shared repository to a normal one
45 45
46 46 Copy the store data to the repo and remove the sharedpath data.
47 47 """
48 48
49 49 if repo.sharedpath == repo.path:
50 50 raise util.Abort(_("this is not a shared repo"))
51 51
52 52 destlock = lock = None
53 53 lock = repo.lock()
54 54 try:
55 55 # we use locks here because if we race with commit, we
56 56 # can end up with extra data in the cloned revlogs that's
57 57 # not pointed to by changesets, thus causing verify to
58 58 # fail
59 59
60 60 destlock = hg.copystore(ui, repo, repo.path)
61 61
62 62 sharefile = repo.join('sharedpath')
63 63 util.rename(sharefile, sharefile + '.old')
64 64
65 65 repo.requirements.discard('sharedpath')
66 66 repo._writerequirements()
67 67 finally:
68 68 destlock and destlock.release()
69 69 lock and lock.release()
70 70
71 71 # update store, spath, sopener and sjoin of repo
72 72 repo.unfiltered().__init__(repo.baseui, repo.root)
73 73
74 74 def extsetup(ui):
75 75 extensions.wrapfunction(bookmarks.bmstore, 'getbkfile', getbkfile)
76 76 extensions.wrapfunction(bookmarks.bmstore, 'recordchange', recordchange)
77 77 extensions.wrapfunction(bookmarks.bmstore, 'write', write)
78 78
79 79 def _hassharedbookmarks(repo):
80 80 """Returns whether this repo has shared bookmarks"""
81 81 try:
82 82 repo.vfs.read('bookmarks.shared')
83 83 return True
84 84 except IOError, inst:
85 85 if inst.errno != errno.ENOENT:
86 86 raise
87 87 return False
88 88
89 89 def _getsrcrepo(repo):
90 90 """
91 91 Returns the source repository object for a given shared repository.
92 92 If repo is not a shared repository, return None.
93 93 """
94 srcrepo = None
95 try:
96 # strip because some tools write with newline after
97 sharedpath = repo.vfs.read('sharedpath').strip()
98 # the sharedpath always ends in the .hg; we want the path to the repo
99 source = repo.vfs.split(sharedpath)[0]
100 srcurl, branches = parseurl(source)
101 srcrepo = repository(repo.ui, srcurl)
102 except IOError, inst:
103 if inst.errno != errno.ENOENT:
104 raise
105 return srcrepo
94 if repo.sharedpath == repo.path:
95 return None
96
97 # the sharedpath always ends in the .hg; we want the path to the repo
98 source = repo.vfs.split(repo.sharedpath)[0]
99 srcurl, branches = parseurl(source)
100 return repository(repo.ui, srcurl)
106 101
107 102 def getbkfile(orig, self, repo):
108 103 if _hassharedbookmarks(repo):
109 104 srcrepo = _getsrcrepo(repo)
110 105 if srcrepo is not None:
111 106 repo = srcrepo
112 107 return orig(self, repo)
113 108
114 109 def recordchange(orig, self, tr):
115 110 # Continue with write to local bookmarks file as usual
116 111 orig(self, tr)
117 112
118 113 if _hassharedbookmarks(self._repo):
119 114 srcrepo = _getsrcrepo(self._repo)
120 115 if srcrepo is not None:
121 116 category = 'share-bookmarks'
122 117 tr.addpostclose(category, lambda tr: self._writerepo(srcrepo))
123 118
124 119 def write(orig, self):
125 120 # First write local bookmarks file in case we ever unshare
126 121 orig(self)
127 122 if _hassharedbookmarks(self._repo):
128 123 srcrepo = _getsrcrepo(self._repo)
129 124 if srcrepo is not None:
130 125 self._writerepo(srcrepo)
General Comments 0
You need to be logged in to leave comments. Login now