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