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