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