##// END OF EJS Templates
bookmarks: process pulled remote bookmarks in sorted order
Mads Kiilerich -
r18363:c6e033a7 default
parent child Browse files
Show More
@@ -1,283 +1,283
1 # Mercurial bookmark support code
1 # Mercurial bookmark support code
2 #
2 #
3 # Copyright 2008 David Soria Parra <dsp@php.net>
3 # Copyright 2008 David Soria Parra <dsp@php.net>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from mercurial.i18n import _
8 from mercurial.i18n import _
9 from mercurial.node import hex
9 from mercurial.node import hex
10 from mercurial import encoding, error, util, obsolete
10 from mercurial import encoding, error, util, obsolete
11 import errno, os
11 import errno, os
12
12
13 class bmstore(dict):
13 class bmstore(dict):
14 """Storage for bookmarks.
14 """Storage for bookmarks.
15
15
16 This object should do all bookmark reads and writes, so that it's
16 This object should do all bookmark reads and writes, so that it's
17 fairly simple to replace the storage underlying bookmarks without
17 fairly simple to replace the storage underlying bookmarks without
18 having to clone the logic surrounding bookmarks.
18 having to clone the logic surrounding bookmarks.
19
19
20 This particular bmstore implementation stores bookmarks as
20 This particular bmstore implementation stores bookmarks as
21 {hash}\s{name}\n (the same format as localtags) in
21 {hash}\s{name}\n (the same format as localtags) in
22 .hg/bookmarks. The mapping is stored as {name: nodeid}.
22 .hg/bookmarks. The mapping is stored as {name: nodeid}.
23
23
24 This class does NOT handle the "current" bookmark state at this
24 This class does NOT handle the "current" bookmark state at this
25 time.
25 time.
26 """
26 """
27
27
28 def __init__(self, repo):
28 def __init__(self, repo):
29 dict.__init__(self)
29 dict.__init__(self)
30 self._repo = repo
30 self._repo = repo
31 try:
31 try:
32 for line in repo.vfs('bookmarks'):
32 for line in repo.vfs('bookmarks'):
33 line = line.strip()
33 line = line.strip()
34 if not line:
34 if not line:
35 continue
35 continue
36 if ' ' not in line:
36 if ' ' not in line:
37 repo.ui.warn(_('malformed line in .hg/bookmarks: %r\n')
37 repo.ui.warn(_('malformed line in .hg/bookmarks: %r\n')
38 % line)
38 % line)
39 continue
39 continue
40 sha, refspec = line.split(' ', 1)
40 sha, refspec = line.split(' ', 1)
41 refspec = encoding.tolocal(refspec)
41 refspec = encoding.tolocal(refspec)
42 try:
42 try:
43 self[refspec] = repo.changelog.lookup(sha)
43 self[refspec] = repo.changelog.lookup(sha)
44 except LookupError:
44 except LookupError:
45 pass
45 pass
46 except IOError, inst:
46 except IOError, inst:
47 if inst.errno != errno.ENOENT:
47 if inst.errno != errno.ENOENT:
48 raise
48 raise
49
49
50 def write(self):
50 def write(self):
51 '''Write bookmarks
51 '''Write bookmarks
52
52
53 Write the given bookmark => hash dictionary to the .hg/bookmarks file
53 Write the given bookmark => hash dictionary to the .hg/bookmarks file
54 in a format equal to those of localtags.
54 in a format equal to those of localtags.
55
55
56 We also store a backup of the previous state in undo.bookmarks that
56 We also store a backup of the previous state in undo.bookmarks that
57 can be copied back on rollback.
57 can be copied back on rollback.
58 '''
58 '''
59 repo = self._repo
59 repo = self._repo
60 if repo._bookmarkcurrent not in self:
60 if repo._bookmarkcurrent not in self:
61 setcurrent(repo, None)
61 setcurrent(repo, None)
62
62
63 wlock = repo.wlock()
63 wlock = repo.wlock()
64 try:
64 try:
65
65
66 file = repo.vfs('bookmarks', 'w', atomictemp=True)
66 file = repo.vfs('bookmarks', 'w', atomictemp=True)
67 for name, node in self.iteritems():
67 for name, node in self.iteritems():
68 file.write("%s %s\n" % (hex(node), encoding.fromlocal(name)))
68 file.write("%s %s\n" % (hex(node), encoding.fromlocal(name)))
69 file.close()
69 file.close()
70
70
71 # touch 00changelog.i so hgweb reloads bookmarks (no lock needed)
71 # touch 00changelog.i so hgweb reloads bookmarks (no lock needed)
72 try:
72 try:
73 os.utime(repo.sjoin('00changelog.i'), None)
73 os.utime(repo.sjoin('00changelog.i'), None)
74 except OSError:
74 except OSError:
75 pass
75 pass
76
76
77 finally:
77 finally:
78 wlock.release()
78 wlock.release()
79
79
80 def readcurrent(repo):
80 def readcurrent(repo):
81 '''Get the current bookmark
81 '''Get the current bookmark
82
82
83 If we use gittish branches we have a current bookmark that
83 If we use gittish branches we have a current bookmark that
84 we are on. This function returns the name of the bookmark. It
84 we are on. This function returns the name of the bookmark. It
85 is stored in .hg/bookmarks.current
85 is stored in .hg/bookmarks.current
86 '''
86 '''
87 mark = None
87 mark = None
88 try:
88 try:
89 file = repo.opener('bookmarks.current')
89 file = repo.opener('bookmarks.current')
90 except IOError, inst:
90 except IOError, inst:
91 if inst.errno != errno.ENOENT:
91 if inst.errno != errno.ENOENT:
92 raise
92 raise
93 return None
93 return None
94 try:
94 try:
95 # No readline() in osutil.posixfile, reading everything is cheap
95 # No readline() in osutil.posixfile, reading everything is cheap
96 mark = encoding.tolocal((file.readlines() or [''])[0])
96 mark = encoding.tolocal((file.readlines() or [''])[0])
97 if mark == '' or mark not in repo._bookmarks:
97 if mark == '' or mark not in repo._bookmarks:
98 mark = None
98 mark = None
99 finally:
99 finally:
100 file.close()
100 file.close()
101 return mark
101 return mark
102
102
103 def setcurrent(repo, mark):
103 def setcurrent(repo, mark):
104 '''Set the name of the bookmark that we are currently on
104 '''Set the name of the bookmark that we are currently on
105
105
106 Set the name of the bookmark that we are on (hg update <bookmark>).
106 Set the name of the bookmark that we are on (hg update <bookmark>).
107 The name is recorded in .hg/bookmarks.current
107 The name is recorded in .hg/bookmarks.current
108 '''
108 '''
109 current = repo._bookmarkcurrent
109 current = repo._bookmarkcurrent
110 if current == mark:
110 if current == mark:
111 return
111 return
112
112
113 if mark not in repo._bookmarks:
113 if mark not in repo._bookmarks:
114 mark = ''
114 mark = ''
115
115
116 wlock = repo.wlock()
116 wlock = repo.wlock()
117 try:
117 try:
118 file = repo.opener('bookmarks.current', 'w', atomictemp=True)
118 file = repo.opener('bookmarks.current', 'w', atomictemp=True)
119 file.write(encoding.fromlocal(mark))
119 file.write(encoding.fromlocal(mark))
120 file.close()
120 file.close()
121 finally:
121 finally:
122 wlock.release()
122 wlock.release()
123 repo._bookmarkcurrent = mark
123 repo._bookmarkcurrent = mark
124
124
125 def unsetcurrent(repo):
125 def unsetcurrent(repo):
126 wlock = repo.wlock()
126 wlock = repo.wlock()
127 try:
127 try:
128 try:
128 try:
129 util.unlink(repo.join('bookmarks.current'))
129 util.unlink(repo.join('bookmarks.current'))
130 repo._bookmarkcurrent = None
130 repo._bookmarkcurrent = None
131 except OSError, inst:
131 except OSError, inst:
132 if inst.errno != errno.ENOENT:
132 if inst.errno != errno.ENOENT:
133 raise
133 raise
134 finally:
134 finally:
135 wlock.release()
135 wlock.release()
136
136
137 def updatecurrentbookmark(repo, oldnode, curbranch):
137 def updatecurrentbookmark(repo, oldnode, curbranch):
138 try:
138 try:
139 return update(repo, oldnode, repo.branchtip(curbranch))
139 return update(repo, oldnode, repo.branchtip(curbranch))
140 except error.RepoLookupError:
140 except error.RepoLookupError:
141 if curbranch == "default": # no default branch!
141 if curbranch == "default": # no default branch!
142 return update(repo, oldnode, repo.lookup("tip"))
142 return update(repo, oldnode, repo.lookup("tip"))
143 else:
143 else:
144 raise util.Abort(_("branch %s not found") % curbranch)
144 raise util.Abort(_("branch %s not found") % curbranch)
145
145
146 def update(repo, parents, node):
146 def update(repo, parents, node):
147 marks = repo._bookmarks
147 marks = repo._bookmarks
148 update = False
148 update = False
149 cur = repo._bookmarkcurrent
149 cur = repo._bookmarkcurrent
150 if not cur:
150 if not cur:
151 return False
151 return False
152
152
153 toupdate = [b for b in marks if b.split('@', 1)[0] == cur.split('@', 1)[0]]
153 toupdate = [b for b in marks if b.split('@', 1)[0] == cur.split('@', 1)[0]]
154 for mark in toupdate:
154 for mark in toupdate:
155 if mark and marks[mark] in parents:
155 if mark and marks[mark] in parents:
156 old = repo[marks[mark]]
156 old = repo[marks[mark]]
157 new = repo[node]
157 new = repo[node]
158 if old.descendant(new) and mark == cur:
158 if old.descendant(new) and mark == cur:
159 marks[cur] = new.node()
159 marks[cur] = new.node()
160 update = True
160 update = True
161 if mark != cur:
161 if mark != cur:
162 del marks[mark]
162 del marks[mark]
163 if update:
163 if update:
164 marks.write()
164 marks.write()
165 return update
165 return update
166
166
167 def listbookmarks(repo):
167 def listbookmarks(repo):
168 # We may try to list bookmarks on a repo type that does not
168 # We may try to list bookmarks on a repo type that does not
169 # support it (e.g., statichttprepository).
169 # support it (e.g., statichttprepository).
170 marks = getattr(repo, '_bookmarks', {})
170 marks = getattr(repo, '_bookmarks', {})
171
171
172 d = {}
172 d = {}
173 for k, v in marks.iteritems():
173 for k, v in marks.iteritems():
174 # don't expose local divergent bookmarks
174 # don't expose local divergent bookmarks
175 if '@' not in k or k.endswith('@'):
175 if '@' not in k or k.endswith('@'):
176 d[k] = hex(v)
176 d[k] = hex(v)
177 return d
177 return d
178
178
179 def pushbookmark(repo, key, old, new):
179 def pushbookmark(repo, key, old, new):
180 w = repo.wlock()
180 w = repo.wlock()
181 try:
181 try:
182 marks = repo._bookmarks
182 marks = repo._bookmarks
183 if hex(marks.get(key, '')) != old:
183 if hex(marks.get(key, '')) != old:
184 return False
184 return False
185 if new == '':
185 if new == '':
186 del marks[key]
186 del marks[key]
187 else:
187 else:
188 if new not in repo:
188 if new not in repo:
189 return False
189 return False
190 marks[key] = repo[new].node()
190 marks[key] = repo[new].node()
191 marks.write()
191 marks.write()
192 return True
192 return True
193 finally:
193 finally:
194 w.release()
194 w.release()
195
195
196 def updatefromremote(ui, repo, remote, path):
196 def updatefromremote(ui, repo, remote, path):
197 ui.debug("checking for updated bookmarks\n")
197 ui.debug("checking for updated bookmarks\n")
198 rb = remote.listkeys('bookmarks')
198 rb = remote.listkeys('bookmarks')
199 changed = False
199 changed = False
200 localmarks = repo._bookmarks
200 localmarks = repo._bookmarks
201 for k in rb.keys():
201 for k in sorted(rb):
202 if k in localmarks:
202 if k in localmarks:
203 nr, nl = rb[k], localmarks[k]
203 nr, nl = rb[k], localmarks[k]
204 if nr in repo:
204 if nr in repo:
205 cr = repo[nr]
205 cr = repo[nr]
206 cl = repo[nl]
206 cl = repo[nl]
207 if cl.rev() >= cr.rev():
207 if cl.rev() >= cr.rev():
208 continue
208 continue
209 if validdest(repo, cl, cr):
209 if validdest(repo, cl, cr):
210 localmarks[k] = cr.node()
210 localmarks[k] = cr.node()
211 changed = True
211 changed = True
212 ui.status(_("updating bookmark %s\n") % k)
212 ui.status(_("updating bookmark %s\n") % k)
213 else:
213 else:
214 if k == '@':
214 if k == '@':
215 kd = ''
215 kd = ''
216 else:
216 else:
217 kd = k
217 kd = k
218 # find a unique @ suffix
218 # find a unique @ suffix
219 for x in range(1, 100):
219 for x in range(1, 100):
220 n = '%s@%d' % (kd, x)
220 n = '%s@%d' % (kd, x)
221 if n not in localmarks:
221 if n not in localmarks:
222 break
222 break
223 # try to use an @pathalias suffix
223 # try to use an @pathalias suffix
224 # if an @pathalias already exists, we overwrite (update) it
224 # if an @pathalias already exists, we overwrite (update) it
225 for p, u in ui.configitems("paths"):
225 for p, u in ui.configitems("paths"):
226 if path == u:
226 if path == u:
227 n = '%s@%s' % (kd, p)
227 n = '%s@%s' % (kd, p)
228
228
229 localmarks[n] = cr.node()
229 localmarks[n] = cr.node()
230 changed = True
230 changed = True
231 ui.warn(_("divergent bookmark %s stored as %s\n") % (k, n))
231 ui.warn(_("divergent bookmark %s stored as %s\n") % (k, n))
232 elif rb[k] in repo:
232 elif rb[k] in repo:
233 # add remote bookmarks for changes we already have
233 # add remote bookmarks for changes we already have
234 localmarks[k] = repo[rb[k]].node()
234 localmarks[k] = repo[rb[k]].node()
235 changed = True
235 changed = True
236 ui.status(_("adding remote bookmark %s\n") % k)
236 ui.status(_("adding remote bookmark %s\n") % k)
237
237
238 if changed:
238 if changed:
239 localmarks.write()
239 localmarks.write()
240
240
241 def diff(ui, dst, src):
241 def diff(ui, dst, src):
242 ui.status(_("searching for changed bookmarks\n"))
242 ui.status(_("searching for changed bookmarks\n"))
243
243
244 smarks = src.listkeys('bookmarks')
244 smarks = src.listkeys('bookmarks')
245 dmarks = dst.listkeys('bookmarks')
245 dmarks = dst.listkeys('bookmarks')
246
246
247 diff = sorted(set(smarks) - set(dmarks))
247 diff = sorted(set(smarks) - set(dmarks))
248 for k in diff:
248 for k in diff:
249 mark = ui.debugflag and smarks[k] or smarks[k][:12]
249 mark = ui.debugflag and smarks[k] or smarks[k][:12]
250 ui.write(" %-25s %s\n" % (k, mark))
250 ui.write(" %-25s %s\n" % (k, mark))
251
251
252 if len(diff) <= 0:
252 if len(diff) <= 0:
253 ui.status(_("no changed bookmarks found\n"))
253 ui.status(_("no changed bookmarks found\n"))
254 return 1
254 return 1
255 return 0
255 return 0
256
256
257 def validdest(repo, old, new):
257 def validdest(repo, old, new):
258 """Is the new bookmark destination a valid update from the old one"""
258 """Is the new bookmark destination a valid update from the old one"""
259 repo = repo.unfiltered()
259 repo = repo.unfiltered()
260 if old == new:
260 if old == new:
261 # Old == new -> nothing to update.
261 # Old == new -> nothing to update.
262 return False
262 return False
263 elif not old:
263 elif not old:
264 # old is nullrev, anything is valid.
264 # old is nullrev, anything is valid.
265 # (new != nullrev has been excluded by the previous check)
265 # (new != nullrev has been excluded by the previous check)
266 return True
266 return True
267 elif repo.obsstore:
267 elif repo.obsstore:
268 # We only need this complicated logic if there is obsolescence
268 # We only need this complicated logic if there is obsolescence
269 # XXX will probably deserve an optimised revset.
269 # XXX will probably deserve an optimised revset.
270 nm = repo.changelog.nodemap
270 nm = repo.changelog.nodemap
271 validdests = set([old])
271 validdests = set([old])
272 plen = -1
272 plen = -1
273 # compute the whole set of successors or descendants
273 # compute the whole set of successors or descendants
274 while len(validdests) != plen:
274 while len(validdests) != plen:
275 plen = len(validdests)
275 plen = len(validdests)
276 succs = set(c.node() for c in validdests)
276 succs = set(c.node() for c in validdests)
277 mutable = [c.node() for c in validdests if c.mutable()]
277 mutable = [c.node() for c in validdests if c.mutable()]
278 succs.update(obsolete.allsuccessors(repo.obsstore, mutable))
278 succs.update(obsolete.allsuccessors(repo.obsstore, mutable))
279 known = (n for n in succs if n in nm)
279 known = (n for n in succs if n in nm)
280 validdests = set(repo.set('%ln::', known))
280 validdests = set(repo.set('%ln::', known))
281 return new in validdests
281 return new in validdests
282 else:
282 else:
283 return old.descendant(new)
283 return old.descendant(new)
@@ -1,383 +1,383
1 $ "$TESTDIR/hghave" serve || exit 80
1 $ "$TESTDIR/hghave" serve || exit 80
2
2
3 $ cat << EOF >> $HGRCPATH
3 $ cat << EOF >> $HGRCPATH
4 > [ui]
4 > [ui]
5 > logtemplate={rev}:{node|short} {desc|firstline}
5 > logtemplate={rev}:{node|short} {desc|firstline}
6 > [phases]
6 > [phases]
7 > publish=False
7 > publish=False
8 > [extensions]
8 > [extensions]
9 > EOF
9 > EOF
10 $ cat > obs.py << EOF
10 $ cat > obs.py << EOF
11 > import mercurial.obsolete
11 > import mercurial.obsolete
12 > mercurial.obsolete._enabled = True
12 > mercurial.obsolete._enabled = True
13 > EOF
13 > EOF
14 $ echo "obs=${TESTTMP}/obs.py" >> $HGRCPATH
14 $ echo "obs=${TESTTMP}/obs.py" >> $HGRCPATH
15
15
16 initialize
16 initialize
17
17
18 $ hg init a
18 $ hg init a
19 $ cd a
19 $ cd a
20 $ echo 'test' > test
20 $ echo 'test' > test
21 $ hg commit -Am'test'
21 $ hg commit -Am'test'
22 adding test
22 adding test
23
23
24 set bookmarks
24 set bookmarks
25
25
26 $ hg bookmark X
26 $ hg bookmark X
27 $ hg bookmark Y
27 $ hg bookmark Y
28 $ hg bookmark Z
28 $ hg bookmark Z
29
29
30 import bookmark by name
30 import bookmark by name
31
31
32 $ hg init ../b
32 $ hg init ../b
33 $ cd ../b
33 $ cd ../b
34 $ hg book Y
34 $ hg book Y
35 $ hg book
35 $ hg book
36 * Y -1:000000000000
36 * Y -1:000000000000
37 $ hg pull ../a
37 $ hg pull ../a
38 pulling from ../a
38 pulling from ../a
39 requesting all changes
39 requesting all changes
40 adding changesets
40 adding changesets
41 adding manifests
41 adding manifests
42 adding file changes
42 adding file changes
43 added 1 changesets with 1 changes to 1 files
43 added 1 changesets with 1 changes to 1 files
44 adding remote bookmark X
44 updating bookmark Y
45 updating bookmark Y
45 adding remote bookmark X
46 adding remote bookmark Z
46 adding remote bookmark Z
47 (run 'hg update' to get a working copy)
47 (run 'hg update' to get a working copy)
48 $ hg bookmarks
48 $ hg bookmarks
49 X 0:4e3505fd9583
49 X 0:4e3505fd9583
50 Y 0:4e3505fd9583
50 Y 0:4e3505fd9583
51 Z 0:4e3505fd9583
51 Z 0:4e3505fd9583
52 $ hg debugpushkey ../a namespaces
52 $ hg debugpushkey ../a namespaces
53 bookmarks
53 bookmarks
54 namespaces
54 namespaces
55 obsolete
55 obsolete
56 phases
56 phases
57 $ hg debugpushkey ../a bookmarks
57 $ hg debugpushkey ../a bookmarks
58 X 4e3505fd95835d721066b76e75dbb8cc554d7f77
58 X 4e3505fd95835d721066b76e75dbb8cc554d7f77
59 Y 4e3505fd95835d721066b76e75dbb8cc554d7f77
59 Y 4e3505fd95835d721066b76e75dbb8cc554d7f77
60 Z 4e3505fd95835d721066b76e75dbb8cc554d7f77
60 Z 4e3505fd95835d721066b76e75dbb8cc554d7f77
61 $ hg pull -B X ../a
61 $ hg pull -B X ../a
62 pulling from ../a
62 pulling from ../a
63 no changes found
63 no changes found
64 importing bookmark X
64 importing bookmark X
65 $ hg bookmark
65 $ hg bookmark
66 X 0:4e3505fd9583
66 X 0:4e3505fd9583
67 Y 0:4e3505fd9583
67 Y 0:4e3505fd9583
68 Z 0:4e3505fd9583
68 Z 0:4e3505fd9583
69
69
70 export bookmark by name
70 export bookmark by name
71
71
72 $ hg bookmark W
72 $ hg bookmark W
73 $ hg bookmark foo
73 $ hg bookmark foo
74 $ hg bookmark foobar
74 $ hg bookmark foobar
75 $ hg push -B W ../a
75 $ hg push -B W ../a
76 pushing to ../a
76 pushing to ../a
77 searching for changes
77 searching for changes
78 no changes found
78 no changes found
79 exporting bookmark W
79 exporting bookmark W
80 [1]
80 [1]
81 $ hg -R ../a bookmarks
81 $ hg -R ../a bookmarks
82 W -1:000000000000
82 W -1:000000000000
83 X 0:4e3505fd9583
83 X 0:4e3505fd9583
84 Y 0:4e3505fd9583
84 Y 0:4e3505fd9583
85 * Z 0:4e3505fd9583
85 * Z 0:4e3505fd9583
86
86
87 delete a remote bookmark
87 delete a remote bookmark
88
88
89 $ hg book -d W
89 $ hg book -d W
90 $ hg push -B W ../a
90 $ hg push -B W ../a
91 pushing to ../a
91 pushing to ../a
92 searching for changes
92 searching for changes
93 no changes found
93 no changes found
94 deleting remote bookmark W
94 deleting remote bookmark W
95 [1]
95 [1]
96
96
97 push/pull name that doesn't exist
97 push/pull name that doesn't exist
98
98
99 $ hg push -B badname ../a
99 $ hg push -B badname ../a
100 pushing to ../a
100 pushing to ../a
101 searching for changes
101 searching for changes
102 no changes found
102 no changes found
103 bookmark badname does not exist on the local or remote repository!
103 bookmark badname does not exist on the local or remote repository!
104 [2]
104 [2]
105 $ hg pull -B anotherbadname ../a
105 $ hg pull -B anotherbadname ../a
106 pulling from ../a
106 pulling from ../a
107 abort: remote bookmark anotherbadname not found!
107 abort: remote bookmark anotherbadname not found!
108 [255]
108 [255]
109
109
110 divergent bookmarks
110 divergent bookmarks
111
111
112 $ cd ../a
112 $ cd ../a
113 $ echo c1 > f1
113 $ echo c1 > f1
114 $ hg ci -Am1
114 $ hg ci -Am1
115 adding f1
115 adding f1
116 $ hg book -f @
116 $ hg book -f @
117 $ hg book -f X
117 $ hg book -f X
118 $ hg book
118 $ hg book
119 @ 1:0d2164f0ce0d
119 @ 1:0d2164f0ce0d
120 * X 1:0d2164f0ce0d
120 * X 1:0d2164f0ce0d
121 Y 0:4e3505fd9583
121 Y 0:4e3505fd9583
122 Z 1:0d2164f0ce0d
122 Z 1:0d2164f0ce0d
123
123
124 $ cd ../b
124 $ cd ../b
125 $ hg up
125 $ hg up
126 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
126 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
127 updating bookmark foobar
127 updating bookmark foobar
128 $ echo c2 > f2
128 $ echo c2 > f2
129 $ hg ci -Am2
129 $ hg ci -Am2
130 adding f2
130 adding f2
131 $ hg book -f @
131 $ hg book -f @
132 $ hg book -f X
132 $ hg book -f X
133 $ hg book
133 $ hg book
134 @ 1:9b140be10808
134 @ 1:9b140be10808
135 * X 1:9b140be10808
135 * X 1:9b140be10808
136 Y 0:4e3505fd9583
136 Y 0:4e3505fd9583
137 Z 0:4e3505fd9583
137 Z 0:4e3505fd9583
138 foo -1:000000000000
138 foo -1:000000000000
139 foobar 1:9b140be10808
139 foobar 1:9b140be10808
140
140
141 $ hg pull --config paths.foo=../a foo
141 $ hg pull --config paths.foo=../a foo
142 pulling from $TESTTMP/a (glob)
142 pulling from $TESTTMP/a (glob)
143 searching for changes
143 searching for changes
144 adding changesets
144 adding changesets
145 adding manifests
145 adding manifests
146 adding file changes
146 adding file changes
147 added 1 changesets with 1 changes to 1 files (+1 heads)
147 added 1 changesets with 1 changes to 1 files (+1 heads)
148 divergent bookmark @ stored as @foo
148 divergent bookmark X stored as X@foo
149 divergent bookmark X stored as X@foo
149 updating bookmark Z
150 updating bookmark Z
150 divergent bookmark @ stored as @foo
151 (run 'hg heads' to see heads, 'hg merge' to merge)
151 (run 'hg heads' to see heads, 'hg merge' to merge)
152 $ hg book
152 $ hg book
153 @ 1:9b140be10808
153 @ 1:9b140be10808
154 @foo 2:0d2164f0ce0d
154 @foo 2:0d2164f0ce0d
155 * X 1:9b140be10808
155 * X 1:9b140be10808
156 X@foo 2:0d2164f0ce0d
156 X@foo 2:0d2164f0ce0d
157 Y 0:4e3505fd9583
157 Y 0:4e3505fd9583
158 Z 2:0d2164f0ce0d
158 Z 2:0d2164f0ce0d
159 foo -1:000000000000
159 foo -1:000000000000
160 foobar 1:9b140be10808
160 foobar 1:9b140be10808
161 $ hg push -f ../a
161 $ hg push -f ../a
162 pushing to ../a
162 pushing to ../a
163 searching for changes
163 searching for changes
164 adding changesets
164 adding changesets
165 adding manifests
165 adding manifests
166 adding file changes
166 adding file changes
167 added 1 changesets with 1 changes to 1 files (+1 heads)
167 added 1 changesets with 1 changes to 1 files (+1 heads)
168 $ hg -R ../a book
168 $ hg -R ../a book
169 @ 1:0d2164f0ce0d
169 @ 1:0d2164f0ce0d
170 * X 1:0d2164f0ce0d
170 * X 1:0d2164f0ce0d
171 Y 0:4e3505fd9583
171 Y 0:4e3505fd9583
172 Z 1:0d2164f0ce0d
172 Z 1:0d2164f0ce0d
173
173
174 update a remote bookmark from a non-head to a head
174 update a remote bookmark from a non-head to a head
175
175
176 $ hg up -q Y
176 $ hg up -q Y
177 $ echo c3 > f2
177 $ echo c3 > f2
178 $ hg ci -Am3
178 $ hg ci -Am3
179 adding f2
179 adding f2
180 created new head
180 created new head
181 $ hg push ../a
181 $ hg push ../a
182 pushing to ../a
182 pushing to ../a
183 searching for changes
183 searching for changes
184 adding changesets
184 adding changesets
185 adding manifests
185 adding manifests
186 adding file changes
186 adding file changes
187 added 1 changesets with 1 changes to 1 files (+1 heads)
187 added 1 changesets with 1 changes to 1 files (+1 heads)
188 updating bookmark Y
188 updating bookmark Y
189 $ hg -R ../a book
189 $ hg -R ../a book
190 @ 1:0d2164f0ce0d
190 @ 1:0d2164f0ce0d
191 * X 1:0d2164f0ce0d
191 * X 1:0d2164f0ce0d
192 Y 3:f6fc62dde3c0
192 Y 3:f6fc62dde3c0
193 Z 1:0d2164f0ce0d
193 Z 1:0d2164f0ce0d
194
194
195 diverging a remote bookmark fails
195 diverging a remote bookmark fails
196
196
197 $ hg up -q 4e3505fd9583
197 $ hg up -q 4e3505fd9583
198 $ echo c4 > f2
198 $ echo c4 > f2
199 $ hg ci -Am4
199 $ hg ci -Am4
200 adding f2
200 adding f2
201 created new head
201 created new head
202 $ echo c5 > f2
202 $ echo c5 > f2
203 $ hg ci -Am5
203 $ hg ci -Am5
204 $ hg log -G
204 $ hg log -G
205 @ 5:c922c0139ca0 5
205 @ 5:c922c0139ca0 5
206 |
206 |
207 o 4:4efff6d98829 4
207 o 4:4efff6d98829 4
208 |
208 |
209 | o 3:f6fc62dde3c0 3
209 | o 3:f6fc62dde3c0 3
210 |/
210 |/
211 | o 2:0d2164f0ce0d 1
211 | o 2:0d2164f0ce0d 1
212 |/
212 |/
213 | o 1:9b140be10808 2
213 | o 1:9b140be10808 2
214 |/
214 |/
215 o 0:4e3505fd9583 test
215 o 0:4e3505fd9583 test
216
216
217
217
218 $ hg book -f Y
218 $ hg book -f Y
219
219
220 $ cat <<EOF > ../a/.hg/hgrc
220 $ cat <<EOF > ../a/.hg/hgrc
221 > [web]
221 > [web]
222 > push_ssl = false
222 > push_ssl = false
223 > allow_push = *
223 > allow_push = *
224 > EOF
224 > EOF
225
225
226 $ hg -R ../a serve -p $HGPORT2 -d --pid-file=../hg2.pid
226 $ hg -R ../a serve -p $HGPORT2 -d --pid-file=../hg2.pid
227 $ cat ../hg2.pid >> $DAEMON_PIDS
227 $ cat ../hg2.pid >> $DAEMON_PIDS
228
228
229 $ hg push http://localhost:$HGPORT2/
229 $ hg push http://localhost:$HGPORT2/
230 pushing to http://localhost:$HGPORT2/
230 pushing to http://localhost:$HGPORT2/
231 searching for changes
231 searching for changes
232 abort: push creates new remote head c922c0139ca0!
232 abort: push creates new remote head c922c0139ca0!
233 (did you forget to merge? use push -f to force)
233 (did you forget to merge? use push -f to force)
234 [255]
234 [255]
235 $ hg -R ../a book
235 $ hg -R ../a book
236 @ 1:0d2164f0ce0d
236 @ 1:0d2164f0ce0d
237 * X 1:0d2164f0ce0d
237 * X 1:0d2164f0ce0d
238 Y 3:f6fc62dde3c0
238 Y 3:f6fc62dde3c0
239 Z 1:0d2164f0ce0d
239 Z 1:0d2164f0ce0d
240
240
241
241
242 Unrelated marker does not alter the decision
242 Unrelated marker does not alter the decision
243
243
244 $ hg debugobsolete aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
244 $ hg debugobsolete aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
245 $ hg push http://localhost:$HGPORT2/
245 $ hg push http://localhost:$HGPORT2/
246 pushing to http://localhost:$HGPORT2/
246 pushing to http://localhost:$HGPORT2/
247 searching for changes
247 searching for changes
248 abort: push creates new remote head c922c0139ca0!
248 abort: push creates new remote head c922c0139ca0!
249 (did you forget to merge? use push -f to force)
249 (did you forget to merge? use push -f to force)
250 [255]
250 [255]
251 $ hg -R ../a book
251 $ hg -R ../a book
252 @ 1:0d2164f0ce0d
252 @ 1:0d2164f0ce0d
253 * X 1:0d2164f0ce0d
253 * X 1:0d2164f0ce0d
254 Y 3:f6fc62dde3c0
254 Y 3:f6fc62dde3c0
255 Z 1:0d2164f0ce0d
255 Z 1:0d2164f0ce0d
256
256
257 Update to a successor works
257 Update to a successor works
258
258
259 $ hg id --debug -r 3
259 $ hg id --debug -r 3
260 f6fc62dde3c0771e29704af56ba4d8af77abcc2f
260 f6fc62dde3c0771e29704af56ba4d8af77abcc2f
261 $ hg id --debug -r 4
261 $ hg id --debug -r 4
262 4efff6d98829d9c824c621afd6e3f01865f5439f
262 4efff6d98829d9c824c621afd6e3f01865f5439f
263 $ hg id --debug -r 5
263 $ hg id --debug -r 5
264 c922c0139ca03858f655e4a2af4dd02796a63969 tip Y
264 c922c0139ca03858f655e4a2af4dd02796a63969 tip Y
265 $ hg debugobsolete f6fc62dde3c0771e29704af56ba4d8af77abcc2f cccccccccccccccccccccccccccccccccccccccc
265 $ hg debugobsolete f6fc62dde3c0771e29704af56ba4d8af77abcc2f cccccccccccccccccccccccccccccccccccccccc
266 $ hg debugobsolete cccccccccccccccccccccccccccccccccccccccc 4efff6d98829d9c824c621afd6e3f01865f5439f
266 $ hg debugobsolete cccccccccccccccccccccccccccccccccccccccc 4efff6d98829d9c824c621afd6e3f01865f5439f
267 $ hg push http://localhost:$HGPORT2/
267 $ hg push http://localhost:$HGPORT2/
268 pushing to http://localhost:$HGPORT2/
268 pushing to http://localhost:$HGPORT2/
269 searching for changes
269 searching for changes
270 remote: adding changesets
270 remote: adding changesets
271 remote: adding manifests
271 remote: adding manifests
272 remote: adding file changes
272 remote: adding file changes
273 remote: added 2 changesets with 2 changes to 1 files (+1 heads)
273 remote: added 2 changesets with 2 changes to 1 files (+1 heads)
274 updating bookmark Y
274 updating bookmark Y
275 $ hg -R ../a book
275 $ hg -R ../a book
276 @ 1:0d2164f0ce0d
276 @ 1:0d2164f0ce0d
277 * X 1:0d2164f0ce0d
277 * X 1:0d2164f0ce0d
278 Y 5:c922c0139ca0
278 Y 5:c922c0139ca0
279 Z 1:0d2164f0ce0d
279 Z 1:0d2164f0ce0d
280
280
281 hgweb
281 hgweb
282
282
283 $ cat <<EOF > .hg/hgrc
283 $ cat <<EOF > .hg/hgrc
284 > [web]
284 > [web]
285 > push_ssl = false
285 > push_ssl = false
286 > allow_push = *
286 > allow_push = *
287 > EOF
287 > EOF
288
288
289 $ hg serve -p $HGPORT -d --pid-file=../hg.pid -E errors.log
289 $ hg serve -p $HGPORT -d --pid-file=../hg.pid -E errors.log
290 $ cat ../hg.pid >> $DAEMON_PIDS
290 $ cat ../hg.pid >> $DAEMON_PIDS
291 $ cd ../a
291 $ cd ../a
292
292
293 $ hg debugpushkey http://localhost:$HGPORT/ namespaces
293 $ hg debugpushkey http://localhost:$HGPORT/ namespaces
294 bookmarks
294 bookmarks
295 namespaces
295 namespaces
296 obsolete
296 obsolete
297 phases
297 phases
298 $ hg debugpushkey http://localhost:$HGPORT/ bookmarks
298 $ hg debugpushkey http://localhost:$HGPORT/ bookmarks
299 @ 9b140be1080824d768c5a4691a564088eede71f9
299 @ 9b140be1080824d768c5a4691a564088eede71f9
300 X 9b140be1080824d768c5a4691a564088eede71f9
300 X 9b140be1080824d768c5a4691a564088eede71f9
301 Y c922c0139ca03858f655e4a2af4dd02796a63969
301 Y c922c0139ca03858f655e4a2af4dd02796a63969
302 Z 0d2164f0ce0d8f1d6f94351eba04b794909be66c
302 Z 0d2164f0ce0d8f1d6f94351eba04b794909be66c
303 foo 0000000000000000000000000000000000000000
303 foo 0000000000000000000000000000000000000000
304 foobar 9b140be1080824d768c5a4691a564088eede71f9
304 foobar 9b140be1080824d768c5a4691a564088eede71f9
305 $ hg out -B http://localhost:$HGPORT/
305 $ hg out -B http://localhost:$HGPORT/
306 comparing with http://localhost:$HGPORT/
306 comparing with http://localhost:$HGPORT/
307 searching for changed bookmarks
307 searching for changed bookmarks
308 no changed bookmarks found
308 no changed bookmarks found
309 [1]
309 [1]
310 $ hg push -B Z http://localhost:$HGPORT/
310 $ hg push -B Z http://localhost:$HGPORT/
311 pushing to http://localhost:$HGPORT/
311 pushing to http://localhost:$HGPORT/
312 searching for changes
312 searching for changes
313 no changes found
313 no changes found
314 exporting bookmark Z
314 exporting bookmark Z
315 [1]
315 [1]
316 $ hg book -d Z
316 $ hg book -d Z
317 $ hg in -B http://localhost:$HGPORT/
317 $ hg in -B http://localhost:$HGPORT/
318 comparing with http://localhost:$HGPORT/
318 comparing with http://localhost:$HGPORT/
319 searching for changed bookmarks
319 searching for changed bookmarks
320 Z 0d2164f0ce0d
320 Z 0d2164f0ce0d
321 foo 000000000000
321 foo 000000000000
322 foobar 9b140be10808
322 foobar 9b140be10808
323 $ hg pull -B Z http://localhost:$HGPORT/
323 $ hg pull -B Z http://localhost:$HGPORT/
324 pulling from http://localhost:$HGPORT/
324 pulling from http://localhost:$HGPORT/
325 no changes found
325 no changes found
326 divergent bookmark @ stored as @1
326 divergent bookmark @ stored as @1
327 divergent bookmark X stored as X@1
328 adding remote bookmark Z
327 adding remote bookmark foo
329 adding remote bookmark foo
328 adding remote bookmark foobar
330 adding remote bookmark foobar
329 divergent bookmark X stored as X@1
330 adding remote bookmark Z
331 importing bookmark Z
331 importing bookmark Z
332 $ hg clone http://localhost:$HGPORT/ cloned-bookmarks
332 $ hg clone http://localhost:$HGPORT/ cloned-bookmarks
333 requesting all changes
333 requesting all changes
334 adding changesets
334 adding changesets
335 adding manifests
335 adding manifests
336 adding file changes
336 adding file changes
337 added 5 changesets with 5 changes to 3 files (+2 heads)
337 added 5 changesets with 5 changes to 3 files (+2 heads)
338 updating to bookmark @
338 updating to bookmark @
339 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
339 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
340 $ hg -R cloned-bookmarks bookmarks
340 $ hg -R cloned-bookmarks bookmarks
341 * @ 1:9b140be10808
341 * @ 1:9b140be10808
342 X 1:9b140be10808
342 X 1:9b140be10808
343 Y 4:c922c0139ca0
343 Y 4:c922c0139ca0
344 Z 2:0d2164f0ce0d
344 Z 2:0d2164f0ce0d
345 foo -1:000000000000
345 foo -1:000000000000
346 foobar 1:9b140be10808
346 foobar 1:9b140be10808
347
347
348 $ cd ..
348 $ cd ..
349
349
350 Pushing a bookmark should only push the changes required by that
350 Pushing a bookmark should only push the changes required by that
351 bookmark, not all outgoing changes:
351 bookmark, not all outgoing changes:
352 $ hg clone http://localhost:$HGPORT/ addmarks
352 $ hg clone http://localhost:$HGPORT/ addmarks
353 requesting all changes
353 requesting all changes
354 adding changesets
354 adding changesets
355 adding manifests
355 adding manifests
356 adding file changes
356 adding file changes
357 added 5 changesets with 5 changes to 3 files (+2 heads)
357 added 5 changesets with 5 changes to 3 files (+2 heads)
358 updating to bookmark @
358 updating to bookmark @
359 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
359 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
360 $ cd addmarks
360 $ cd addmarks
361 $ echo foo > foo
361 $ echo foo > foo
362 $ hg add foo
362 $ hg add foo
363 $ hg commit -m 'add foo'
363 $ hg commit -m 'add foo'
364 $ echo bar > bar
364 $ echo bar > bar
365 $ hg add bar
365 $ hg add bar
366 $ hg commit -m 'add bar'
366 $ hg commit -m 'add bar'
367 $ hg co "tip^"
367 $ hg co "tip^"
368 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
368 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
369 $ hg book add-foo
369 $ hg book add-foo
370 $ hg book -r tip add-bar
370 $ hg book -r tip add-bar
371 Note: this push *must* push only a single changeset, as that's the point
371 Note: this push *must* push only a single changeset, as that's the point
372 of this test.
372 of this test.
373 $ hg push -B add-foo --traceback
373 $ hg push -B add-foo --traceback
374 pushing to http://localhost:$HGPORT/
374 pushing to http://localhost:$HGPORT/
375 searching for changes
375 searching for changes
376 remote: adding changesets
376 remote: adding changesets
377 remote: adding manifests
377 remote: adding manifests
378 remote: adding file changes
378 remote: adding file changes
379 remote: added 1 changesets with 1 changes to 1 files
379 remote: added 1 changesets with 1 changes to 1 files
380 updating bookmark @ failed!
380 updating bookmark @ failed!
381 exporting bookmark add-foo
381 exporting bookmark add-foo
382
382
383 $ cd ..
383 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now