##// END OF EJS Templates
bookmarks: move push/pull command features to core
Matt Mackall -
r13368:d4ab9486 default
parent child Browse files
Show More
@@ -457,6 +457,100 b' def bisect(ui, repo, rev=None, extra=Non'
457 cmdutil.bail_if_changed(repo)
457 cmdutil.bail_if_changed(repo)
458 return hg.clean(repo, node)
458 return hg.clean(repo, node)
459
459
460 def bookmark(ui, repo, mark=None, rev=None, force=False, delete=False, rename=None):
461 '''track a line of development with movable markers
462
463 Bookmarks are pointers to certain commits that move when
464 committing. Bookmarks are local. They can be renamed, copied and
465 deleted. It is possible to use bookmark names in :hg:`merge` and
466 :hg:`update` to merge and update respectively to a given bookmark.
467
468 You can use :hg:`bookmark NAME` to set a bookmark on the working
469 directory's parent revision with the given name. If you specify
470 a revision using -r REV (where REV may be an existing bookmark),
471 the bookmark is assigned to that revision.
472
473 Bookmarks can be pushed and pulled between repositories (see :hg:`help
474 push` and :hg:`help pull`). This requires the bookmark extension to be
475 enabled for both the local and remote repositories.
476 '''
477 hexfn = ui.debugflag and hex or short
478 marks = repo._bookmarks
479 cur = repo.changectx('.').node()
480
481 if rename:
482 if rename not in marks:
483 raise util.Abort(_("a bookmark of this name does not exist"))
484 if mark in marks and not force:
485 raise util.Abort(_("a bookmark of the same name already exists"))
486 if mark is None:
487 raise util.Abort(_("new bookmark name required"))
488 marks[mark] = marks[rename]
489 del marks[rename]
490 if repo._bookmarkcurrent == rename:
491 bookmarks.setcurrent(repo, mark)
492 bookmarks.write(repo)
493 return
494
495 if delete:
496 if mark is None:
497 raise util.Abort(_("bookmark name required"))
498 if mark not in marks:
499 raise util.Abort(_("a bookmark of this name does not exist"))
500 if mark == repo._bookmarkcurrent:
501 bookmarks.setcurrent(repo, None)
502 del marks[mark]
503 bookmarks.write(repo)
504 return
505
506 if mark is not None:
507 if "\n" in mark:
508 raise util.Abort(_("bookmark name cannot contain newlines"))
509 mark = mark.strip()
510 if not mark:
511 raise util.Abort(_("bookmark names cannot consist entirely of "
512 "whitespace"))
513 if mark in marks and not force:
514 raise util.Abort(_("a bookmark of the same name already exists"))
515 if ((mark in repo.branchtags() or mark == repo.dirstate.branch())
516 and not force):
517 raise util.Abort(
518 _("a bookmark cannot have the name of an existing branch"))
519 if rev:
520 marks[mark] = repo.lookup(rev)
521 else:
522 marks[mark] = repo.changectx('.').node()
523 bookmarks.setcurrent(repo, mark)
524 bookmarks.write(repo)
525 return
526
527 if mark is None:
528 if rev:
529 raise util.Abort(_("bookmark name required"))
530 if len(marks) == 0:
531 ui.status(_("no bookmarks set\n"))
532 else:
533 for bmark, n in marks.iteritems():
534 if ui.configbool('bookmarks', 'track.current'):
535 current = repo._bookmarkcurrent
536 if bmark == current and n == cur:
537 prefix, label = '*', 'bookmarks.current'
538 else:
539 prefix, label = ' ', ''
540 else:
541 if n == cur:
542 prefix, label = '*', 'bookmarks.current'
543 else:
544 prefix, label = ' ', ''
545
546 if ui.quiet:
547 ui.write("%s\n" % bmark, label=label)
548 else:
549 ui.write(" %s %-25s %d:%s\n" % (
550 prefix, bmark, repo.changelog.rev(n), hexfn(n)),
551 label=label)
552 return
553
460 def branch(ui, repo, label=None, **opts):
554 def branch(ui, repo, label=None, **opts):
461 """set or show the current branch name
555 """set or show the current branch name
462
556
@@ -2806,6 +2900,16 b' def pull(ui, repo, source="default", **o'
2806 other = hg.repository(hg.remoteui(repo, opts), source)
2900 other = hg.repository(hg.remoteui(repo, opts), source)
2807 ui.status(_('pulling from %s\n') % url.hidepassword(source))
2901 ui.status(_('pulling from %s\n') % url.hidepassword(source))
2808 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
2902 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
2903
2904 if opts.get('bookmark'):
2905 if not revs:
2906 revs = []
2907 rb = other.listkeys('bookmarks')
2908 for b in opts['bookmark']:
2909 if b not in rb:
2910 raise util.Abort(_('remote bookmark %s not found!') % b)
2911 revs.append(rb[b])
2912
2809 if revs:
2913 if revs:
2810 try:
2914 try:
2811 revs = [other.lookup(rev) for rev in revs]
2915 revs = [other.lookup(rev) for rev in revs]
@@ -2819,10 +2923,21 b' def pull(ui, repo, source="default", **o'
2819 checkout = str(repo.changelog.rev(other.lookup(checkout)))
2923 checkout = str(repo.changelog.rev(other.lookup(checkout)))
2820 repo._subtoppath = source
2924 repo._subtoppath = source
2821 try:
2925 try:
2822 return postincoming(ui, repo, modheads, opts.get('update'), checkout)
2926 ret = postincoming(ui, repo, modheads, opts.get('update'), checkout)
2927
2823 finally:
2928 finally:
2824 del repo._subtoppath
2929 del repo._subtoppath
2825
2930
2931 # update specified bookmarks
2932 if opts.get('bookmark'):
2933 for b in opts['bookmark']:
2934 # explicit pull overrides local bookmark if any
2935 ui.status(_("importing bookmark %s\n") % b)
2936 repo._bookmarks[b] = repo[rb[b]].node()
2937 bookmarks.write(repo)
2938
2939 return ret
2940
2826 def push(ui, repo, dest=None, **opts):
2941 def push(ui, repo, dest=None, **opts):
2827 """push changes to the specified destination
2942 """push changes to the specified destination
2828
2943
@@ -2852,6 +2967,17 b' def push(ui, repo, dest=None, **opts):'
2852
2967
2853 Returns 0 if push was successful, 1 if nothing to push.
2968 Returns 0 if push was successful, 1 if nothing to push.
2854 """
2969 """
2970
2971 if opts.get('bookmark'):
2972 for b in opts['bookmark']:
2973 # translate -B options to -r so changesets get pushed
2974 if b in repo._bookmarks:
2975 opts.setdefault('rev', []).append(b)
2976 else:
2977 # if we try to push a deleted bookmark, translate it to null
2978 # this lets simultaneous -r, -b options continue working
2979 opts.setdefault('rev', []).append("null")
2980
2855 dest = ui.expandpath(dest or 'default-push', dest or 'default')
2981 dest = ui.expandpath(dest or 'default-push', dest or 'default')
2856 dest, branches = hg.parseurl(dest, opts.get('branch'))
2982 dest, branches = hg.parseurl(dest, opts.get('branch'))
2857 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
2983 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
@@ -2870,9 +2996,33 b' def push(ui, repo, dest=None, **opts):'
2870 return False
2996 return False
2871 finally:
2997 finally:
2872 del repo._subtoppath
2998 del repo._subtoppath
2873 r = repo.push(other, opts.get('force'), revs=revs,
2999 result = repo.push(other, opts.get('force'), revs=revs,
2874 newbranch=opts.get('new_branch'))
3000 newbranch=opts.get('new_branch'))
2875 return r == 0
3001
3002 result = (result == 0)
3003
3004 if opts.get('bookmark'):
3005 rb = other.listkeys('bookmarks')
3006 for b in opts['bookmark']:
3007 # explicit push overrides remote bookmark if any
3008 if b in repo._bookmarks:
3009 ui.status(_("exporting bookmark %s\n") % b)
3010 new = repo[b].hex()
3011 elif b in rb:
3012 ui.status(_("deleting remote bookmark %s\n") % b)
3013 new = '' # delete
3014 else:
3015 ui.warn(_('bookmark %s does not exist on the local '
3016 'or remote repository!\n') % b)
3017 return 2
3018 old = rb.get(b, '')
3019 r = other.pushkey('bookmarks', b, old, new)
3020 if not r:
3021 ui.warn(_('updating bookmark %s failed!\n') % b)
3022 if not result:
3023 result = 2
3024
3025 return result
2876
3026
2877 def recover(ui, repo):
3027 def recover(ui, repo):
2878 """roll back an interrupted transaction
3028 """roll back an interrupted transaction
@@ -4091,6 +4241,13 b' table = {'
4091 _('use command to check changeset state'), _('CMD')),
4241 _('use command to check changeset state'), _('CMD')),
4092 ('U', 'noupdate', False, _('do not update to target'))],
4242 ('U', 'noupdate', False, _('do not update to target'))],
4093 _("[-gbsr] [-U] [-c CMD] [REV]")),
4243 _("[-gbsr] [-U] [-c CMD] [REV]")),
4244 "bookmarks":
4245 (bookmark,
4246 [('f', 'force', False, _('force')),
4247 ('r', 'rev', '', _('revision'), _('REV')),
4248 ('d', 'delete', False, _('delete a given bookmark')),
4249 ('m', 'rename', '', _('rename a given bookmark'), _('NAME'))],
4250 _('hg bookmarks [-f] [-d] [-m NAME] [-r REV] [NAME]')),
4094 "branch":
4251 "branch":
4095 (branch,
4252 (branch,
4096 [('f', 'force', None,
4253 [('f', 'force', None,
@@ -4396,6 +4553,7 b' table = {'
4396 _('run even when remote repository is unrelated')),
4553 _('run even when remote repository is unrelated')),
4397 ('r', 'rev', [],
4554 ('r', 'rev', [],
4398 _('a remote changeset intended to be added'), _('REV')),
4555 _('a remote changeset intended to be added'), _('REV')),
4556 ('B', 'bookmark', [], _("bookmark to pull"), _('BOOKMARK')),
4399 ('b', 'branch', [],
4557 ('b', 'branch', [],
4400 _('a specific branch you would like to pull'), _('BRANCH')),
4558 _('a specific branch you would like to pull'), _('BRANCH')),
4401 ] + remoteopts,
4559 ] + remoteopts,
@@ -4406,6 +4564,7 b' table = {'
4406 ('r', 'rev', [],
4564 ('r', 'rev', [],
4407 _('a changeset intended to be included in the destination'),
4565 _('a changeset intended to be included in the destination'),
4408 _('REV')),
4566 _('REV')),
4567 ('B', 'bookmark', [], _("bookmark to push"), _('BOOKMARK')),
4409 ('b', 'branch', [],
4568 ('b', 'branch', [],
4410 _('a specific branch you would like to push'), _('BRANCH')),
4569 _('a specific branch you would like to push'), _('BRANCH')),
4411 ('', 'new-branch', False, _('allow pushing a new branch')),
4570 ('', 'new-branch', False, _('allow pushing a new branch')),
@@ -11,7 +11,7 b' from i18n import _, gettext'
11
11
12 _extensions = {}
12 _extensions = {}
13 _order = []
13 _order = []
14 _ignore = ['hbisect']
14 _ignore = ['hbisect', 'bookmarks']
15
15
16 def extensions():
16 def extensions():
17 for name in _order:
17 for name in _order:
@@ -71,14 +71,21 b' delete a remote bookmark'
71
71
72 $ hg book -d W
72 $ hg book -d W
73 $ hg push -B W ../a
73 $ hg push -B W ../a
74 pushing to ../a
75 searching for changes
76 no changes found
74 deleting remote bookmark W
77 deleting remote bookmark W
75
78
76 push/pull name that doesn't exist
79 push/pull name that doesn't exist
77
80
78 $ hg push -B badname ../a
81 $ hg push -B badname ../a
82 pushing to ../a
83 searching for changes
84 no changes found
79 bookmark badname does not exist on the local or remote repository!
85 bookmark badname does not exist on the local or remote repository!
80 [2]
86 [2]
81 $ hg pull -B anotherbadname ../a
87 $ hg pull -B anotherbadname ../a
88 pulling from ../a
82 abort: remote bookmark anotherbadname not found!
89 abort: remote bookmark anotherbadname not found!
83 [255]
90 [255]
84
91
@@ -6,6 +6,7 b' Show all commands except debug commands'
6 archive
6 archive
7 backout
7 backout
8 bisect
8 bisect
9 bookmarks
9 branch
10 branch
10 branches
11 branches
11 bundle
12 bundle
@@ -187,8 +188,8 b' Show all commands + options'
187 init: ssh, remotecmd, insecure
188 init: ssh, remotecmd, insecure
188 log: follow, follow-first, date, copies, keyword, rev, removed, only-merges, user, only-branch, branch, prune, patch, git, limit, no-merges, stat, style, template, include, exclude
189 log: follow, follow-first, date, copies, keyword, rev, removed, only-merges, user, only-branch, branch, prune, patch, git, limit, no-merges, stat, style, template, include, exclude
189 merge: force, tool, rev, preview
190 merge: force, tool, rev, preview
190 pull: update, force, rev, branch, ssh, remotecmd, insecure
191 pull: update, force, rev, bookmark, branch, ssh, remotecmd, insecure
191 push: force, rev, branch, new-branch, ssh, remotecmd, insecure
192 push: force, rev, bookmark, branch, new-branch, ssh, remotecmd, insecure
192 remove: after, force, include, exclude
193 remove: after, force, include, exclude
193 serve: accesslog, daemon, daemon-pipefds, errorlog, port, address, prefix, name, web-conf, webdir-conf, pid-file, stdio, templates, style, ipv6, certificate
194 serve: accesslog, daemon, daemon-pipefds, errorlog, port, address, prefix, name, web-conf, webdir-conf, pid-file, stdio, templates, style, ipv6, certificate
194 status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, copies, print0, rev, change, include, exclude, subrepos
195 status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, copies, print0, rev, change, include, exclude, subrepos
@@ -198,6 +199,7 b' Show all commands + options'
198 archive: no-decode, prefix, rev, type, subrepos, include, exclude
199 archive: no-decode, prefix, rev, type, subrepos, include, exclude
199 backout: merge, parent, tool, rev, include, exclude, message, logfile, date, user
200 backout: merge, parent, tool, rev, include, exclude, message, logfile, date, user
200 bisect: reset, good, bad, skip, command, noupdate
201 bisect: reset, good, bad, skip, command, noupdate
202 bookmarks: force, rev, delete, rename
201 branch: force, clean
203 branch: force, clean
202 branches: active, closed
204 branches: active, closed
203 bundle: force, rev, branch, base, all, type, ssh, remotecmd, insecure
205 bundle: force, rev, branch, base, all, type, ssh, remotecmd, insecure
@@ -284,6 +284,7 b' Testing -h/--help:'
284 archive create an unversioned archive of a repository revision
284 archive create an unversioned archive of a repository revision
285 backout reverse effect of earlier changeset
285 backout reverse effect of earlier changeset
286 bisect subdivision search of changesets
286 bisect subdivision search of changesets
287 bookmarks track a line of development with movable markers
287 branch set or show the current branch name
288 branch set or show the current branch name
288 branches list repository named branches
289 branches list repository named branches
289 bundle create a changegroup file
290 bundle create a changegroup file
@@ -360,6 +361,7 b' Testing -h/--help:'
360 archive create an unversioned archive of a repository revision
361 archive create an unversioned archive of a repository revision
361 backout reverse effect of earlier changeset
362 backout reverse effect of earlier changeset
362 bisect subdivision search of changesets
363 bisect subdivision search of changesets
364 bookmarks track a line of development with movable markers
363 branch set or show the current branch name
365 branch set or show the current branch name
364 branches list repository named branches
366 branches list repository named branches
365 bundle create a changegroup file
367 bundle create a changegroup file
@@ -55,6 +55,7 b' Short help:'
55 archive create an unversioned archive of a repository revision
55 archive create an unversioned archive of a repository revision
56 backout reverse effect of earlier changeset
56 backout reverse effect of earlier changeset
57 bisect subdivision search of changesets
57 bisect subdivision search of changesets
58 bookmarks track a line of development with movable markers
58 branch set or show the current branch name
59 branch set or show the current branch name
59 branches list repository named branches
60 branches list repository named branches
60 bundle create a changegroup file
61 bundle create a changegroup file
@@ -127,6 +128,7 b' Short help:'
127 archive create an unversioned archive of a repository revision
128 archive create an unversioned archive of a repository revision
128 backout reverse effect of earlier changeset
129 backout reverse effect of earlier changeset
129 bisect subdivision search of changesets
130 bisect subdivision search of changesets
131 bookmarks track a line of development with movable markers
130 branch set or show the current branch name
132 branch set or show the current branch name
131 branches list repository named branches
133 branches list repository named branches
132 bundle create a changegroup file
134 bundle create a changegroup file
@@ -649,6 +651,7 b' Test that default list of commands omits'
649 archive create an unversioned archive of a repository revision
651 archive create an unversioned archive of a repository revision
650 backout reverse effect of earlier changeset
652 backout reverse effect of earlier changeset
651 bisect subdivision search of changesets
653 bisect subdivision search of changesets
654 bookmarks track a line of development with movable markers
652 branch set or show the current branch name
655 branch set or show the current branch name
653 branches list repository named branches
656 branches list repository named branches
654 bundle create a changegroup file
657 bundle create a changegroup file
@@ -233,6 +233,9 b' test pushkeys and bookmarks'
233 importing bookmark foo
233 importing bookmark foo
234 $ hg book -d foo
234 $ hg book -d foo
235 $ hg push -B foo
235 $ hg push -B foo
236 pushing to ssh://user@dummy/remote
237 searching for changes
238 no changes found
236 deleting remote bookmark foo
239 deleting remote bookmark foo
237
240
238 a bad, evil hook that prints to stdout
241 a bad, evil hook that prints to stdout
@@ -287,5 +290,3 b' push should succeed even though it has a'
287 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
290 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
288 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
291 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
289 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
292 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
290 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
291 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
1 NO CONTENT: file was removed
NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now