annotate hgext/fetch.py @ 2816:2a0c599f7bb0

fetch: hold lock and wlock across all operations
author Vadim Gelfer <vadim.gelfer@gmail.com>
date Tue, 08 Aug 2006 17:08:59 -0700
parents 0496cfb05243
children 49988d9f0758
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2795
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
1 # fetch.py - pull and merge remote changes
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
2 #
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
3 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
4 #
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
5 # This software may be used and distributed according to the terms
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
6 # of the GNU General Public License, incorporated herein by reference.
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
7
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
8 from mercurial.demandload import *
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
9 from mercurial.i18n import gettext as _
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
10 from mercurial.node import *
2797
df220d0974dd fetch: add missing import.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2796
diff changeset
11 demandload(globals(), 'mercurial:commands,hg,node,util')
2795
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
12
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
13 def fetch(ui, repo, source='default', **opts):
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
14 '''Pull changes from a remote repository, merge new changes if needed.
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
15
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
16 This finds all changes from the repository at the specified path
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
17 or URL and adds them to the local repository.
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
18
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
19 If the pulled changes add a new head, the head is automatically
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
20 merged, and the result of the merge is committed. Otherwise, the
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
21 working directory is updated.'''
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
22
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
23 def postincoming(other, modheads):
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
24 if modheads == 0:
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
25 return 0
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
26 if modheads == 1:
2816
2a0c599f7bb0 fetch: hold lock and wlock across all operations
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2814
diff changeset
27 return hg.update(repo, repo.changelog.tip(), wlock=wlock)
2795
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
28 newheads = repo.heads(parent)
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
29 newchildren = [n for n in repo.heads(parent) if n != parent]
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
30 newparent = parent
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
31 if newchildren:
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
32 newparent = newchildren[0]
2816
2a0c599f7bb0 fetch: hold lock and wlock across all operations
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2814
diff changeset
33 hg.update(repo, newparent, wlock=wlock)
2795
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
34 newheads = [n for n in repo.heads() if n != newparent]
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
35 err = False
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
36 if newheads:
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
37 ui.status(_('merging with new head %d:%s\n') %
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
38 (repo.changelog.rev(newheads[0]), short(newheads[0])))
2816
2a0c599f7bb0 fetch: hold lock and wlock across all operations
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2814
diff changeset
39 err = hg.update(repo, newheads[0], allow=True, remind=False,
2a0c599f7bb0 fetch: hold lock and wlock across all operations
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2814
diff changeset
40 wlock=wlock)
2795
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
41 if not err and len(newheads) > 1:
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
42 ui.status(_('not merging with %d other new heads '
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
43 '(use "hg heads" and "hg merge" to merge them)') %
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
44 (len(newheads) - 1))
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
45 if not err:
2816
2a0c599f7bb0 fetch: hold lock and wlock across all operations
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2814
diff changeset
46 mod, add, rem = repo.status(wlock=wlock)[:3]
2795
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
47 message = (commands.logmessage(opts) or
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
48 (_('Automated merge with %s') % other.url()))
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
49 n = repo.commit(mod + add + rem, message,
2816
2a0c599f7bb0 fetch: hold lock and wlock across all operations
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2814
diff changeset
50 opts['user'], opts['date'], lock=lock, wlock=wlock,
2795
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
51 force_editor=opts.get('force_editor'))
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
52 ui.status(_('new changeset %d:%s merges remote changes '
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
53 'with local\n') % (repo.changelog.rev(n),
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
54 short(n)))
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
55 def pull():
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
56 commands.setremoteconfig(ui, opts)
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
57
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
58 other = hg.repository(ui, ui.expandpath(source))
2816
2a0c599f7bb0 fetch: hold lock and wlock across all operations
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2814
diff changeset
59 ui.status(_('pulling from %s\n') % ui.expandpath(source))
2795
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
60 revs = None
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
61 if opts['rev'] and not other.local():
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
62 raise util.Abort(_("fetch -r doesn't work for remote repositories yet"))
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
63 elif opts['rev']:
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
64 revs = [other.lookup(rev) for rev in opts['rev']]
2814
0496cfb05243 fetch: lock repo across pull and commit
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2813
diff changeset
65 modheads = repo.pull(other, heads=revs, lock=lock)
2795
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
66 return postincoming(other, modheads)
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
67
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
68 parent, p2 = repo.dirstate.parents()
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
69 if parent != repo.changelog.tip():
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
70 raise util.Abort(_('working dir not at tip '
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
71 '(use "hg update" to check out tip)'))
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
72 if p2 != nullid:
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
73 raise util.Abort(_('outstanding uncommitted merge'))
2816
2a0c599f7bb0 fetch: hold lock and wlock across all operations
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2814
diff changeset
74 wlock = repo.wlock()
2814
0496cfb05243 fetch: lock repo across pull and commit
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2813
diff changeset
75 lock = repo.lock()
0496cfb05243 fetch: lock repo across pull and commit
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2813
diff changeset
76 try:
2816
2a0c599f7bb0 fetch: hold lock and wlock across all operations
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2814
diff changeset
77 mod, add, rem = repo.status(wlock=wlock)[:3]
2a0c599f7bb0 fetch: hold lock and wlock across all operations
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2814
diff changeset
78 if mod or add or rem:
2a0c599f7bb0 fetch: hold lock and wlock across all operations
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2814
diff changeset
79 raise util.Abort(_('outstanding uncommitted changes'))
2a0c599f7bb0 fetch: hold lock and wlock across all operations
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2814
diff changeset
80 if len(repo.heads()) > 1:
2a0c599f7bb0 fetch: hold lock and wlock across all operations
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2814
diff changeset
81 raise util.Abort(_('multiple heads in this repository '
2a0c599f7bb0 fetch: hold lock and wlock across all operations
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2814
diff changeset
82 '(use "hg heads" and "hg merge" to merge)'))
2814
0496cfb05243 fetch: lock repo across pull and commit
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2813
diff changeset
83 return pull()
0496cfb05243 fetch: lock repo across pull and commit
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2813
diff changeset
84 finally:
0496cfb05243 fetch: lock repo across pull and commit
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2813
diff changeset
85 lock.release()
2816
2a0c599f7bb0 fetch: hold lock and wlock across all operations
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2814
diff changeset
86 wlock.release()
2795
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
87
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
88 cmdtable = {
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
89 'fetch':
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
90 (fetch,
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
91 [('e', 'ssh', '', _('specify ssh command to use')),
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
92 ('m', 'message', '', _('use <text> as commit message')),
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
93 ('l', 'logfile', '', _('read the commit message from <file>')),
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
94 ('d', 'date', '', _('record datecode as commit date')),
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
95 ('u', 'user', '', _('record user as commiter')),
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
96 ('r', 'rev', [], _('a specific revision you would like to pull')),
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
97 ('f', 'force-editor', None, _('edit commit message')),
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
98 ('', 'remotecmd', '', _('hg command to run on the remote side'))],
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
99 'hg fetch [SOURCE]'),
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
100 }