annotate hgext/fetch.py @ 4531:b51a8138292a

Avoid extra filelogs entries. Right now, there are some situations in which localrepo.filecommit can create filelog entries even though they're not needed. For example: - permissions for a file have changed; - qrefresh can create a filelog entry identical to its parent (see the added test); - convert-repo creates extra filelog entries in every merge where the first parent has added files (for example, changeset ebebe9577a1a of the kernel repo added extra filelog entries to files in the arch/blackfin directory, even though the merge should only touch the drivers/ata directory). This makes "hg log file" in a converted repo less useful than it could be, since it may mention many merges that don't actually touch that specific file. They all come from the same basic problem: localrepo.commit (through filecommit) creates new filelog entries for all files passed to it (except for some cases during a merge). Patch and test case provided by Benoit. This should fix issue351.
author Alexis S. L. Carvalho <alexis@cecm.usp.br>
date Sat, 09 Jun 2007 01:04:28 -0300
parents 6b4127c7d52a
children 0c61124ad877
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2800
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
3891
6b4127c7d52a Simplify i18n imports
Matt Mackall <mpm@selenic.com>
parents: 3877
diff changeset
8 from mercurial.i18n import _
2800
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
9 from mercurial.node import *
3877
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents: 3223
diff changeset
10 from mercurial import commands, hg, node, util
2800
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
11
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
12 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
13 '''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
14
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
15 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
16 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
17
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
18 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
19 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
20 working directory is updated.'''
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
21
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
22 def postincoming(other, modheads):
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
23 if modheads == 0:
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
24 return 0
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
25 if modheads == 1:
2849
3b21013e7680 fetch: fix test fail
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2830
diff changeset
26 return hg.clean(repo, repo.changelog.tip(), wlock=wlock)
2800
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
27 newheads = repo.heads(parent)
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
28 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
29 newparent = parent
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
30 if newchildren:
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
31 newparent = newchildren[0]
2849
3b21013e7680 fetch: fix test fail
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2830
diff changeset
32 hg.clean(repo, newparent, wlock=wlock)
2800
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
33 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
34 err = False
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
35 if newheads:
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
36 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
37 (repo.changelog.rev(newheads[0]), short(newheads[0])))
2830
49988d9f0758 Merge with crew, fix most tests
Matt Mackall <mpm@selenic.com>
parents: 2808 2827
diff changeset
38 err = hg.merge(repo, newheads[0], remind=False, wlock=wlock)
2800
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
39 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
40 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
41 '(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
42 (len(newheads) - 1))
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
43 if not err:
2827
2a0c599f7bb0 fetch: hold lock and wlock across all operations
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2825
diff changeset
44 mod, add, rem = repo.status(wlock=wlock)[:3]
2800
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
45 message = (commands.logmessage(opts) or
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
46 (_('Automated merge with %s') % other.url()))
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
47 n = repo.commit(mod + add + rem, message,
2827
2a0c599f7bb0 fetch: hold lock and wlock across all operations
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2825
diff changeset
48 opts['user'], opts['date'], lock=lock, wlock=wlock,
2800
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
49 force_editor=opts.get('force_editor'))
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
50 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
51 '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
52 short(n)))
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
53 def pull():
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
54 commands.setremoteconfig(ui, opts)
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
55
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
56 other = hg.repository(ui, ui.expandpath(source))
2827
2a0c599f7bb0 fetch: hold lock and wlock across all operations
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2825
diff changeset
57 ui.status(_('pulling from %s\n') % ui.expandpath(source))
2800
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
58 revs = None
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
59 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
60 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
61 elif opts['rev']:
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
62 revs = [other.lookup(rev) for rev in opts['rev']]
2825
0496cfb05243 fetch: lock repo across pull and commit
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2824
diff changeset
63 modheads = repo.pull(other, heads=revs, lock=lock)
2800
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
64 return postincoming(other, modheads)
3223
53e843840349 Whitespace/Tab cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2849
diff changeset
65
2800
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
66 parent, p2 = repo.dirstate.parents()
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
67 if parent != repo.changelog.tip():
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
68 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
69 '(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
70 if p2 != nullid:
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
71 raise util.Abort(_('outstanding uncommitted merge'))
2827
2a0c599f7bb0 fetch: hold lock and wlock across all operations
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2825
diff changeset
72 wlock = repo.wlock()
2825
0496cfb05243 fetch: lock repo across pull and commit
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2824
diff changeset
73 lock = repo.lock()
0496cfb05243 fetch: lock repo across pull and commit
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2824
diff changeset
74 try:
2827
2a0c599f7bb0 fetch: hold lock and wlock across all operations
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2825
diff changeset
75 mod, add, rem = repo.status(wlock=wlock)[:3]
2a0c599f7bb0 fetch: hold lock and wlock across all operations
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2825
diff changeset
76 if mod or add or rem:
2a0c599f7bb0 fetch: hold lock and wlock across all operations
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2825
diff changeset
77 raise util.Abort(_('outstanding uncommitted changes'))
2a0c599f7bb0 fetch: hold lock and wlock across all operations
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2825
diff changeset
78 if len(repo.heads()) > 1:
2a0c599f7bb0 fetch: hold lock and wlock across all operations
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2825
diff changeset
79 raise util.Abort(_('multiple heads in this repository '
2a0c599f7bb0 fetch: hold lock and wlock across all operations
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2825
diff changeset
80 '(use "hg heads" and "hg merge" to merge)'))
2825
0496cfb05243 fetch: lock repo across pull and commit
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2824
diff changeset
81 return pull()
0496cfb05243 fetch: lock repo across pull and commit
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2824
diff changeset
82 finally:
0496cfb05243 fetch: lock repo across pull and commit
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2824
diff changeset
83 lock.release()
2827
2a0c599f7bb0 fetch: hold lock and wlock across all operations
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2825
diff changeset
84 wlock.release()
2800
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
85
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
86 cmdtable = {
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
87 'fetch':
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
88 (fetch,
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
89 [('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
90 ('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
91 ('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
92 ('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
93 ('u', 'user', '', _('record user as commiter')),
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
94 ('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
95 ('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
96 ('', '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
97 'hg fetch [SOURCE]'),
135823f37304 new extension: fetch -> combine pull and merge/update
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
98 }