##// END OF EJS Templates
fetch: migrate `opts` to native kwargs
Matt Harbison -
r51769:eeffc968 default
parent child Browse files
Show More
@@ -1,198 +1,195 b''
1 # fetch.py - pull and merge remote changes
1 # fetch.py - pull and merge remote changes
2 #
2 #
3 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
3 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
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 '''pull, update and merge in one command (DEPRECATED)'''
8 '''pull, update and merge in one command (DEPRECATED)'''
9
9
10
10
11 from mercurial.i18n import _
11 from mercurial.i18n import _
12 from mercurial.node import short
12 from mercurial.node import short
13 from mercurial import (
13 from mercurial import (
14 cmdutil,
14 cmdutil,
15 error,
15 error,
16 exchange,
16 exchange,
17 hg,
17 hg,
18 lock,
18 lock,
19 pycompat,
19 pycompat,
20 registrar,
20 registrar,
21 )
21 )
22 from mercurial.utils import (
22 from mercurial.utils import (
23 dateutil,
23 dateutil,
24 urlutil,
24 urlutil,
25 )
25 )
26
26
27 release = lock.release
27 release = lock.release
28 cmdtable = {}
28 cmdtable = {}
29 command = registrar.command(cmdtable)
29 command = registrar.command(cmdtable)
30 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
30 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
31 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
31 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
32 # be specifying the version(s) of Mercurial they are tested with, or
32 # be specifying the version(s) of Mercurial they are tested with, or
33 # leave the attribute unspecified.
33 # leave the attribute unspecified.
34 testedwith = b'ships-with-hg-core'
34 testedwith = b'ships-with-hg-core'
35
35
36
36
37 @command(
37 @command(
38 b'fetch',
38 b'fetch',
39 [
39 [
40 (
40 (
41 b'r',
41 b'r',
42 b'rev',
42 b'rev',
43 [],
43 [],
44 _(b'a specific revision you would like to pull'),
44 _(b'a specific revision you would like to pull'),
45 _(b'REV'),
45 _(b'REV'),
46 ),
46 ),
47 (b'', b'edit', None, _(b'invoke editor on commit messages')),
47 (b'', b'edit', None, _(b'invoke editor on commit messages')),
48 (b'', b'force-editor', None, _(b'edit commit message (DEPRECATED)')),
48 (b'', b'force-editor', None, _(b'edit commit message (DEPRECATED)')),
49 (b'', b'switch-parent', None, _(b'switch parents when merging')),
49 (b'', b'switch-parent', None, _(b'switch parents when merging')),
50 ]
50 ]
51 + cmdutil.commitopts
51 + cmdutil.commitopts
52 + cmdutil.commitopts2
52 + cmdutil.commitopts2
53 + cmdutil.remoteopts,
53 + cmdutil.remoteopts,
54 _(b'hg fetch [SOURCE]'),
54 _(b'hg fetch [SOURCE]'),
55 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
55 helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
56 )
56 )
57 def fetch(ui, repo, source=b'default', **opts):
57 def fetch(ui, repo, source=b'default', **opts):
58 """pull changes from a remote repository, merge new changes if needed.
58 """pull changes from a remote repository, merge new changes if needed.
59
59
60 This finds all changes from the repository at the specified path
60 This finds all changes from the repository at the specified path
61 or URL and adds them to the local repository.
61 or URL and adds them to the local repository.
62
62
63 If the pulled changes add a new branch head, the head is
63 If the pulled changes add a new branch head, the head is
64 automatically merged, and the result of the merge is committed.
64 automatically merged, and the result of the merge is committed.
65 Otherwise, the working directory is updated to include the new
65 Otherwise, the working directory is updated to include the new
66 changes.
66 changes.
67
67
68 When a merge is needed, the working directory is first updated to
68 When a merge is needed, the working directory is first updated to
69 the newly pulled changes. Local changes are then merged into the
69 the newly pulled changes. Local changes are then merged into the
70 pulled changes. To switch the merge order, use --switch-parent.
70 pulled changes. To switch the merge order, use --switch-parent.
71
71
72 See :hg:`help dates` for a list of formats valid for -d/--date.
72 See :hg:`help dates` for a list of formats valid for -d/--date.
73
73
74 Returns 0 on success.
74 Returns 0 on success.
75 """
75 """
76
76
77 opts = pycompat.byteskwargs(opts)
77 date = opts.get('date')
78 date = opts.get(b'date')
79 if date:
78 if date:
80 opts[b'date'] = dateutil.parsedate(date)
79 opts['date'] = dateutil.parsedate(date)
81
80
82 parent = repo.dirstate.p1()
81 parent = repo.dirstate.p1()
83 branch = repo.dirstate.branch()
82 branch = repo.dirstate.branch()
84 try:
83 try:
85 branchnode = repo.branchtip(branch)
84 branchnode = repo.branchtip(branch)
86 except error.RepoLookupError:
85 except error.RepoLookupError:
87 branchnode = None
86 branchnode = None
88 if parent != branchnode:
87 if parent != branchnode:
89 raise error.Abort(
88 raise error.Abort(
90 _(b'working directory not at branch tip'),
89 _(b'working directory not at branch tip'),
91 hint=_(b"use 'hg update' to check out branch tip"),
90 hint=_(b"use 'hg update' to check out branch tip"),
92 )
91 )
93
92
94 wlock = lock = None
93 wlock = lock = None
95 try:
94 try:
96 wlock = repo.wlock()
95 wlock = repo.wlock()
97 lock = repo.lock()
96 lock = repo.lock()
98
97
99 cmdutil.bailifchanged(repo)
98 cmdutil.bailifchanged(repo)
100
99
101 bheads = repo.branchheads(branch)
100 bheads = repo.branchheads(branch)
102 bheads = [head for head in bheads if len(repo[head].children()) == 0]
101 bheads = [head for head in bheads if len(repo[head].children()) == 0]
103 if len(bheads) > 1:
102 if len(bheads) > 1:
104 raise error.Abort(
103 raise error.Abort(
105 _(
104 _(
106 b'multiple heads in this branch '
105 b'multiple heads in this branch '
107 b'(use "hg heads ." and "hg merge" to merge)'
106 b'(use "hg heads ." and "hg merge" to merge)'
108 )
107 )
109 )
108 )
110
109
111 path = urlutil.get_unique_pull_path_obj(b'fetch', ui, source)
110 path = urlutil.get_unique_pull_path_obj(b'fetch', ui, source)
112 other = hg.peer(repo, opts, path)
111 other = hg.peer(repo, pycompat.byteskwargs(opts), path)
113 ui.status(_(b'pulling from %s\n') % urlutil.hidepassword(path.loc))
112 ui.status(_(b'pulling from %s\n') % urlutil.hidepassword(path.loc))
114 revs = None
113 revs = None
115 if opts[b'rev']:
114 if opts['rev']:
116 try:
115 try:
117 revs = [other.lookup(rev) for rev in opts[b'rev']]
116 revs = [other.lookup(rev) for rev in opts['rev']]
118 except error.CapabilityError:
117 except error.CapabilityError:
119 err = _(
118 err = _(
120 b"other repository doesn't support revision lookup, "
119 b"other repository doesn't support revision lookup, "
121 b"so a rev cannot be specified."
120 b"so a rev cannot be specified."
122 )
121 )
123 raise error.Abort(err)
122 raise error.Abort(err)
124
123
125 # Are there any changes at all?
124 # Are there any changes at all?
126 modheads = exchange.pull(repo, other, heads=revs).cgresult
125 modheads = exchange.pull(repo, other, heads=revs).cgresult
127 if modheads == 0:
126 if modheads == 0:
128 return 0
127 return 0
129
128
130 # Is this a simple fast-forward along the current branch?
129 # Is this a simple fast-forward along the current branch?
131 newheads = repo.branchheads(branch)
130 newheads = repo.branchheads(branch)
132 newchildren = repo.changelog.nodesbetween([parent], newheads)[2]
131 newchildren = repo.changelog.nodesbetween([parent], newheads)[2]
133 if len(newheads) == 1 and len(newchildren):
132 if len(newheads) == 1 and len(newchildren):
134 if newchildren[0] != parent:
133 if newchildren[0] != parent:
135 return hg.update(repo, newchildren[0])
134 return hg.update(repo, newchildren[0])
136 else:
135 else:
137 return 0
136 return 0
138
137
139 # Are there more than one additional branch heads?
138 # Are there more than one additional branch heads?
140 newchildren = [n for n in newchildren if n != parent]
139 newchildren = [n for n in newchildren if n != parent]
141 newparent = parent
140 newparent = parent
142 if newchildren:
141 if newchildren:
143 newparent = newchildren[0]
142 newparent = newchildren[0]
144 hg.clean(repo, newparent)
143 hg.clean(repo, newparent)
145 newheads = [n for n in newheads if n != newparent]
144 newheads = [n for n in newheads if n != newparent]
146 if len(newheads) > 1:
145 if len(newheads) > 1:
147 ui.status(
146 ui.status(
148 _(
147 _(
149 b'not merging with %d other new branch heads '
148 b'not merging with %d other new branch heads '
150 b'(use "hg heads ." and "hg merge" to merge them)\n'
149 b'(use "hg heads ." and "hg merge" to merge them)\n'
151 )
150 )
152 % (len(newheads) - 1)
151 % (len(newheads) - 1)
153 )
152 )
154 return 1
153 return 1
155
154
156 if not newheads:
155 if not newheads:
157 return 0
156 return 0
158
157
159 # Otherwise, let's merge.
158 # Otherwise, let's merge.
160 err = False
159 err = False
161 if newheads:
160 if newheads:
162 # By default, we consider the repository we're pulling
161 # By default, we consider the repository we're pulling
163 # *from* as authoritative, so we merge our changes into
162 # *from* as authoritative, so we merge our changes into
164 # theirs.
163 # theirs.
165 if opts[b'switch_parent']:
164 if opts['switch_parent']:
166 firstparent, secondparent = newparent, newheads[0]
165 firstparent, secondparent = newparent, newheads[0]
167 else:
166 else:
168 firstparent, secondparent = newheads[0], newparent
167 firstparent, secondparent = newheads[0], newparent
169 ui.status(
168 ui.status(
170 _(b'updating to %d:%s\n')
169 _(b'updating to %d:%s\n')
171 % (repo.changelog.rev(firstparent), short(firstparent))
170 % (repo.changelog.rev(firstparent), short(firstparent))
172 )
171 )
173 hg.clean(repo, firstparent)
172 hg.clean(repo, firstparent)
174 p2ctx = repo[secondparent]
173 p2ctx = repo[secondparent]
175 ui.status(
174 ui.status(
176 _(b'merging with %d:%s\n') % (p2ctx.rev(), short(secondparent))
175 _(b'merging with %d:%s\n') % (p2ctx.rev(), short(secondparent))
177 )
176 )
178 err = hg.merge(p2ctx, remind=False)
177 err = hg.merge(p2ctx, remind=False)
179
178
180 if not err:
179 if not err:
181 # we don't translate commit messages
180 # we don't translate commit messages
182 message = cmdutil.logmessage(ui, opts) or (
181 message = cmdutil.logmessage(ui, pycompat.byteskwargs(opts)) or (
183 b'Automated merge with %s' % urlutil.removeauth(other.url())
182 b'Automated merge with %s' % urlutil.removeauth(other.url())
184 )
183 )
185 editopt = opts.get(b'edit') or opts.get(b'force_editor')
184 editopt = opts.get('edit') or opts.get('force_editor')
186 editor = cmdutil.getcommiteditor(edit=editopt, editform=b'fetch')
185 editor = cmdutil.getcommiteditor(edit=editopt, editform=b'fetch')
187 n = repo.commit(
186 n = repo.commit(message, opts['user'], opts['date'], editor=editor)
188 message, opts[b'user'], opts[b'date'], editor=editor
189 )
190 ui.status(
187 ui.status(
191 _(b'new changeset %d:%s merges remote changes with local\n')
188 _(b'new changeset %d:%s merges remote changes with local\n')
192 % (repo.changelog.rev(n), short(n))
189 % (repo.changelog.rev(n), short(n))
193 )
190 )
194
191
195 return err
192 return err
196
193
197 finally:
194 finally:
198 release(lock, wlock)
195 release(lock, wlock)
General Comments 0
You need to be logged in to leave comments. Login now