annotate mercurial/merge.py @ 7090:7b5c063b0b94

diff: pass contexts to status Allow status() to take contexts as well as nodes. This lets us avoid unpacking manifests multiple times and intelligently unpack manifests in revision order. Also, we can avoid unpacking manifests at all when there are no changes in the working directory.
author Matt Mackall <mpm@selenic.com>
date Sun, 12 Oct 2008 15:21:08 -0500
parents 865c5be0f8df
children 89207edf3973
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2775
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
1 # merge.py - directory-level update/merge handling for Mercurial
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
2 #
4635
63b9d2deed48 Updated copyright notices and add "and others" to "hg version"
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4633
diff changeset
3 # Copyright 2006, 2007 Matt Mackall <mpm@selenic.com>
2775
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
4 #
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
5 # This software may be used and distributed according to the terms
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
6 # of the GNU General Public License, incorporated herein by reference.
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
7
6518
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
8 from node import nullid, nullrev, hex, bin
3891
6b4127c7d52a Simplify i18n imports
Matt Mackall <mpm@selenic.com>
parents: 3877
diff changeset
9 from i18n import _
6517
fcfb6a0a0a84 python-2.6: use sha wrapper from util for new merge code
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6512
diff changeset
10 import errno, util, os, filemerge, copies, shutil
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
11
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
12 class mergestate(object):
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
13 '''track 3-way merge state of individual files'''
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
14 def __init__(self, repo):
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
15 self._repo = repo
6518
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
16 self._read()
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
17 def reset(self, node):
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
18 self._state = {}
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
19 self._local = node
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
20 shutil.rmtree(self._repo.join("merge"), True)
6518
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
21 def _read(self):
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
22 self._state = {}
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
23 try:
6530
4b92591c69a7 merge: replace readline() call, missing from posixfile_nt
Patrick Mezard <pmezard@gmail.com>
parents: 6518
diff changeset
24 localnode = None
6518
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
25 f = self._repo.opener("merge/state")
6530
4b92591c69a7 merge: replace readline() call, missing from posixfile_nt
Patrick Mezard <pmezard@gmail.com>
parents: 6518
diff changeset
26 for i, l in enumerate(f):
4b92591c69a7 merge: replace readline() call, missing from posixfile_nt
Patrick Mezard <pmezard@gmail.com>
parents: 6518
diff changeset
27 if i == 0:
4b92591c69a7 merge: replace readline() call, missing from posixfile_nt
Patrick Mezard <pmezard@gmail.com>
parents: 6518
diff changeset
28 localnode = l[:-1]
4b92591c69a7 merge: replace readline() call, missing from posixfile_nt
Patrick Mezard <pmezard@gmail.com>
parents: 6518
diff changeset
29 else:
4b92591c69a7 merge: replace readline() call, missing from posixfile_nt
Patrick Mezard <pmezard@gmail.com>
parents: 6518
diff changeset
30 bits = l[:-1].split("\0")
4b92591c69a7 merge: replace readline() call, missing from posixfile_nt
Patrick Mezard <pmezard@gmail.com>
parents: 6518
diff changeset
31 self._state[bits[0]] = bits[1:]
4b92591c69a7 merge: replace readline() call, missing from posixfile_nt
Patrick Mezard <pmezard@gmail.com>
parents: 6518
diff changeset
32 self._local = bin(localnode)
6518
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
33 except IOError, err:
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
34 if err.errno != errno.ENOENT:
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
35 raise
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
36 def _write(self):
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
37 f = self._repo.opener("merge/state", "w")
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
38 f.write(hex(self._local) + "\n")
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
39 for d, v in self._state.items():
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
40 f.write("\0".join([d] + v) + "\n")
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
41 def add(self, fcl, fco, fca, fd, flags):
6517
fcfb6a0a0a84 python-2.6: use sha wrapper from util for new merge code
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6512
diff changeset
42 hash = util.sha1(fcl.path()).hexdigest()
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
43 self._repo.opener("merge/" + hash, "w").write(fcl.data())
6518
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
44 self._state[fd] = ['u', hash, fcl.path(), fca.path(),
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
45 hex(fca.filenode()), fco.path(), flags]
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
46 self._write()
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
47 def __contains__(self, dfile):
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
48 return dfile in self._state
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
49 def __getitem__(self, dfile):
6518
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
50 return self._state[dfile][0]
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
51 def __iter__(self):
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
52 l = self._state.keys()
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
53 l.sort()
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
54 for f in l:
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
55 yield f
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
56 def mark(self, dfile, state):
6518
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
57 self._state[dfile][0] = state
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
58 self._write()
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
59 def resolve(self, dfile, wctx, octx):
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
60 if self[dfile] == 'r':
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
61 return 0
6518
92ccccb55ba3 resolve: new command
Matt Mackall <mpm@selenic.com>
parents: 6517
diff changeset
62 state, hash, lfile, afile, anode, ofile, flags = self._state[dfile]
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
63 f = self._repo.opener("merge/" + hash)
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
64 self._repo.wwrite(dfile, f.read(), flags)
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
65 fcd = wctx[dfile]
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
66 fco = octx[ofile]
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
67 fca = self._repo.filectx(afile, fileid=anode)
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
68 r = filemerge.filemerge(self._repo, self._local, lfile, fcd, fco, fca)
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
69 if not r:
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
70 self.mark(dfile, 'r')
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
71 return r
2775
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
72
6269
ffdf70e74623 merge: privatize some functions, unnest some others
Matt Mackall <mpm@selenic.com>
parents: 6268
diff changeset
73 def _checkunknown(wctx, mctx):
3315
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
74 "check for collisions between unknown files and files in mctx"
3218
8d4855fd9d7b merge: use new working context object in update
Matt Mackall <mpm@selenic.com>
parents: 3212
diff changeset
75 for f in wctx.unknown():
6272
dd9bd227ae9a merge: simplify some helpers
Matt Mackall <mpm@selenic.com>
parents: 6271
diff changeset
76 if f in mctx and mctx[f].cmp(wctx[f].data()):
dd9bd227ae9a merge: simplify some helpers
Matt Mackall <mpm@selenic.com>
parents: 6271
diff changeset
77 raise util.Abort(_("untracked file in working directory differs"
dd9bd227ae9a merge: simplify some helpers
Matt Mackall <mpm@selenic.com>
parents: 6271
diff changeset
78 " from file in requested revision: '%s'") % f)
3107
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
79
6269
ffdf70e74623 merge: privatize some functions, unnest some others
Matt Mackall <mpm@selenic.com>
parents: 6268
diff changeset
80 def _checkcollision(mctx):
3785
6398ff7cb705 imported patch collision
Matt Mackall <mpm@selenic.com>
parents: 3773
diff changeset
81 "check for case folding collisions in the destination context"
6398ff7cb705 imported patch collision
Matt Mackall <mpm@selenic.com>
parents: 3773
diff changeset
82 folded = {}
6272
dd9bd227ae9a merge: simplify some helpers
Matt Mackall <mpm@selenic.com>
parents: 6271
diff changeset
83 for fn in mctx:
3785
6398ff7cb705 imported patch collision
Matt Mackall <mpm@selenic.com>
parents: 3773
diff changeset
84 fold = fn.lower()
6398ff7cb705 imported patch collision
Matt Mackall <mpm@selenic.com>
parents: 3773
diff changeset
85 if fold in folded:
6398ff7cb705 imported patch collision
Matt Mackall <mpm@selenic.com>
parents: 3773
diff changeset
86 raise util.Abort(_("case-folding collision between %s and %s")
6398ff7cb705 imported patch collision
Matt Mackall <mpm@selenic.com>
parents: 3773
diff changeset
87 % (fn, folded[fold]))
6398ff7cb705 imported patch collision
Matt Mackall <mpm@selenic.com>
parents: 3773
diff changeset
88 folded[fold] = fn
6398ff7cb705 imported patch collision
Matt Mackall <mpm@selenic.com>
parents: 3773
diff changeset
89
6269
ffdf70e74623 merge: privatize some functions, unnest some others
Matt Mackall <mpm@selenic.com>
parents: 6268
diff changeset
90 def _forgetremoved(wctx, mctx, branchmerge):
3107
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
91 """
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
92 Forget removed files
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
93
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
94 If we're jumping between revisions (as opposed to merging), and if
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
95 neither the working directory nor the target rev has the file,
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
96 then we need to remove it from the dirstate, to prevent the
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
97 dirstate from listing the file when it is no longer in the
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
98 manifest.
6242
a375ffc2aa1b merge: fix handling of deleted files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 6211
diff changeset
99
a375ffc2aa1b merge: fix handling of deleted files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 6211
diff changeset
100 If we're merging, and the other revision has removed a file
a375ffc2aa1b merge: fix handling of deleted files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 6211
diff changeset
101 that is not present in the working directory, we need to mark it
a375ffc2aa1b merge: fix handling of deleted files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 6211
diff changeset
102 as removed.
3107
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
103 """
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
104
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
105 action = []
6242
a375ffc2aa1b merge: fix handling of deleted files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 6211
diff changeset
106 state = branchmerge and 'r' or 'f'
a375ffc2aa1b merge: fix handling of deleted files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 6211
diff changeset
107 for f in wctx.deleted():
6272
dd9bd227ae9a merge: simplify some helpers
Matt Mackall <mpm@selenic.com>
parents: 6271
diff changeset
108 if f not in mctx:
6242
a375ffc2aa1b merge: fix handling of deleted files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 6211
diff changeset
109 action.append((f, state))
a375ffc2aa1b merge: fix handling of deleted files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 6211
diff changeset
110
a375ffc2aa1b merge: fix handling of deleted files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 6211
diff changeset
111 if not branchmerge:
a375ffc2aa1b merge: fix handling of deleted files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 6211
diff changeset
112 for f in wctx.removed():
6272
dd9bd227ae9a merge: simplify some helpers
Matt Mackall <mpm@selenic.com>
parents: 6271
diff changeset
113 if f not in mctx:
6242
a375ffc2aa1b merge: fix handling of deleted files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 6211
diff changeset
114 action.append((f, "f"))
3107
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
115
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
116 return action
3bd05ad67f45 merge: pull manifest checks and updates into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3106
diff changeset
117
3295
72d1e521da77 merge: use contexts for manifestmerge
Matt Mackall <mpm@selenic.com>
parents: 3292
diff changeset
118 def manifestmerge(repo, p1, p2, pa, overwrite, partial):
3105
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
119 """
3315
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
120 Merge p1 and p2 with ancestor ma and generate merge action list
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
121
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
122 overwrite = whether we clobber working files
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
123 partial = function to filter file lists
3105
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
124 """
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
125
3314
b16456909a0a merge: various tidying
Matt Mackall <mpm@selenic.com>
parents: 3312
diff changeset
126 repo.ui.note(_("resolving manifests\n"))
b16456909a0a merge: various tidying
Matt Mackall <mpm@selenic.com>
parents: 3312
diff changeset
127 repo.ui.debug(_(" overwrite %s partial %s\n") % (overwrite, bool(partial)))
b16456909a0a merge: various tidying
Matt Mackall <mpm@selenic.com>
parents: 3312
diff changeset
128 repo.ui.debug(_(" ancestor %s local %s remote %s\n") % (pa, p1, p2))
b16456909a0a merge: various tidying
Matt Mackall <mpm@selenic.com>
parents: 3312
diff changeset
129
3295
72d1e521da77 merge: use contexts for manifestmerge
Matt Mackall <mpm@selenic.com>
parents: 3292
diff changeset
130 m1 = p1.manifest()
72d1e521da77 merge: use contexts for manifestmerge
Matt Mackall <mpm@selenic.com>
parents: 3292
diff changeset
131 m2 = p2.manifest()
72d1e521da77 merge: use contexts for manifestmerge
Matt Mackall <mpm@selenic.com>
parents: 3292
diff changeset
132 ma = pa.manifest()
72d1e521da77 merge: use contexts for manifestmerge
Matt Mackall <mpm@selenic.com>
parents: 3292
diff changeset
133 backwards = (pa == p2)
3314
b16456909a0a merge: various tidying
Matt Mackall <mpm@selenic.com>
parents: 3312
diff changeset
134 action = []
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents: 6273
diff changeset
135 copy, copied, diverge = {}, {}, {}
3295
72d1e521da77 merge: use contexts for manifestmerge
Matt Mackall <mpm@selenic.com>
parents: 3292
diff changeset
136
3249
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
137 def fmerge(f, f2=None, fa=None):
4007
20da40cc1c73 symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents: 4006
diff changeset
138 """merge flags"""
3249
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
139 if not f2:
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
140 f2 = f
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
141 fa = f
5708
f6bf89722e29 merge: add flag merging intelligence
Matt Mackall <mpm@selenic.com>
parents: 5704
diff changeset
142 a, m, n = ma.flags(fa), m1.flags(f), m2.flags(f2)
f6bf89722e29 merge: add flag merging intelligence
Matt Mackall <mpm@selenic.com>
parents: 5704
diff changeset
143 if m == n: # flags agree
f6bf89722e29 merge: add flag merging intelligence
Matt Mackall <mpm@selenic.com>
parents: 5704
diff changeset
144 return m # unchanged
f6bf89722e29 merge: add flag merging intelligence
Matt Mackall <mpm@selenic.com>
parents: 5704
diff changeset
145 if m and n: # flags are set but don't agree
f6bf89722e29 merge: add flag merging intelligence
Matt Mackall <mpm@selenic.com>
parents: 5704
diff changeset
146 if not a: # both differ from parent
f6bf89722e29 merge: add flag merging intelligence
Matt Mackall <mpm@selenic.com>
parents: 5704
diff changeset
147 r = repo.ui.prompt(
f6bf89722e29 merge: add flag merging intelligence
Matt Mackall <mpm@selenic.com>
parents: 5704
diff changeset
148 _(" conflicting flags for %s\n"
f6bf89722e29 merge: add flag merging intelligence
Matt Mackall <mpm@selenic.com>
parents: 5704
diff changeset
149 "(n)one, e(x)ec or sym(l)ink?") % f, "[nxl]", "n")
f6bf89722e29 merge: add flag merging intelligence
Matt Mackall <mpm@selenic.com>
parents: 5704
diff changeset
150 return r != "n" and r or ''
f6bf89722e29 merge: add flag merging intelligence
Matt Mackall <mpm@selenic.com>
parents: 5704
diff changeset
151 if m == a:
f6bf89722e29 merge: add flag merging intelligence
Matt Mackall <mpm@selenic.com>
parents: 5704
diff changeset
152 return n # changed from m to n
f6bf89722e29 merge: add flag merging intelligence
Matt Mackall <mpm@selenic.com>
parents: 5704
diff changeset
153 return m # changed from n to m
f6bf89722e29 merge: add flag merging intelligence
Matt Mackall <mpm@selenic.com>
parents: 5704
diff changeset
154 if m and m != a: # changed from a to m
f6bf89722e29 merge: add flag merging intelligence
Matt Mackall <mpm@selenic.com>
parents: 5704
diff changeset
155 return m
f6bf89722e29 merge: add flag merging intelligence
Matt Mackall <mpm@selenic.com>
parents: 5704
diff changeset
156 if n and n != a: # changed from a to n
f6bf89722e29 merge: add flag merging intelligence
Matt Mackall <mpm@selenic.com>
parents: 5704
diff changeset
157 return n
f6bf89722e29 merge: add flag merging intelligence
Matt Mackall <mpm@selenic.com>
parents: 5704
diff changeset
158 return '' # flag was cleared
3118
5644a05a608c merge: simplify exec flag handling
Matt Mackall <mpm@selenic.com>
parents: 3117
diff changeset
159
3307
f009a6f12a59 merge: swap file and mode args for act()
Matt Mackall <mpm@selenic.com>
parents: 3306
diff changeset
160 def act(msg, m, f, *args):
3295
72d1e521da77 merge: use contexts for manifestmerge
Matt Mackall <mpm@selenic.com>
parents: 3292
diff changeset
161 repo.ui.debug(" %s: %s -> %s\n" % (f, msg, m))
3121
2ef0b3aae186 merge: simplify actions with helper function
Matt Mackall <mpm@selenic.com>
parents: 3120
diff changeset
162 action.append((f, m) + args)
2ef0b3aae186 merge: simplify actions with helper function
Matt Mackall <mpm@selenic.com>
parents: 3120
diff changeset
163
6275
fda369b5779c diff: use copy smarts from copies.py
Matt Mackall <mpm@selenic.com>
parents: 6274
diff changeset
164 if pa and not (backwards or overwrite):
6425
2d9328a2f81f copies: skip directory rename checks when not merging
Matt Mackall <mpm@selenic.com>
parents: 6381
diff changeset
165 if repo.ui.configbool("merge", "followcopies", True):
2d9328a2f81f copies: skip directory rename checks when not merging
Matt Mackall <mpm@selenic.com>
parents: 6381
diff changeset
166 dirs = repo.ui.configbool("merge", "followdirs", True)
2d9328a2f81f copies: skip directory rename checks when not merging
Matt Mackall <mpm@selenic.com>
parents: 6381
diff changeset
167 copy, diverge = copies.copies(repo, p1, p2, pa, dirs)
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents: 6273
diff changeset
168 copied = dict.fromkeys(copy.values())
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents: 6273
diff changeset
169 for of, fl in diverge.items():
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents: 6273
diff changeset
170 act("divergent renames", "dr", of, fl)
3295
72d1e521da77 merge: use contexts for manifestmerge
Matt Mackall <mpm@selenic.com>
parents: 3292
diff changeset
171
3105
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
172 # Compare manifests
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
173 for f, n in m1.iteritems():
3248
751840e739a1 merge: reduce manifest copying
Matt Mackall <mpm@selenic.com>
parents: 3247
diff changeset
174 if partial and not partial(f):
751840e739a1 merge: reduce manifest copying
Matt Mackall <mpm@selenic.com>
parents: 3247
diff changeset
175 continue
3105
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
176 if f in m2:
5708
f6bf89722e29 merge: add flag merging intelligence
Matt Mackall <mpm@selenic.com>
parents: 5704
diff changeset
177 if overwrite or backwards:
f6bf89722e29 merge: add flag merging intelligence
Matt Mackall <mpm@selenic.com>
parents: 5704
diff changeset
178 rflags = m2.flags(f)
f6bf89722e29 merge: add flag merging intelligence
Matt Mackall <mpm@selenic.com>
parents: 5704
diff changeset
179 else:
f6bf89722e29 merge: add flag merging intelligence
Matt Mackall <mpm@selenic.com>
parents: 5704
diff changeset
180 rflags = fmerge(f)
3105
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
181 # are files different?
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
182 if n != m2[f]:
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
183 a = ma.get(f, nullid)
5700
9cedc3fbbebb merge: simplify merge tests, fix exec flag bug
Matt Mackall <mpm@selenic.com>
parents: 5695
diff changeset
184 # are we clobbering?
9cedc3fbbebb merge: simplify merge tests, fix exec flag bug
Matt Mackall <mpm@selenic.com>
parents: 5695
diff changeset
185 if overwrite:
5708
f6bf89722e29 merge: add flag merging intelligence
Matt Mackall <mpm@selenic.com>
parents: 5704
diff changeset
186 act("clobbering", "g", f, rflags)
5700
9cedc3fbbebb merge: simplify merge tests, fix exec flag bug
Matt Mackall <mpm@selenic.com>
parents: 5695
diff changeset
187 # or are we going back in time and clean?
7066
865c5be0f8df merge: fix bug going backwards for already reverted files (issue1303)
Matt Mackall <mpm@selenic.com>
parents: 6953
diff changeset
188 elif backwards:
865c5be0f8df merge: fix bug going backwards for already reverted files (issue1303)
Matt Mackall <mpm@selenic.com>
parents: 6953
diff changeset
189 if not n[20:] or not p2[f].cmp(p1[f].data()):
865c5be0f8df merge: fix bug going backwards for already reverted files (issue1303)
Matt Mackall <mpm@selenic.com>
parents: 6953
diff changeset
190 act("reverting", "g", f, rflags)
3105
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
191 # are both different from the ancestor?
5700
9cedc3fbbebb merge: simplify merge tests, fix exec flag bug
Matt Mackall <mpm@selenic.com>
parents: 5695
diff changeset
192 elif n != a and m2[f] != a:
5708
f6bf89722e29 merge: add flag merging intelligence
Matt Mackall <mpm@selenic.com>
parents: 5704
diff changeset
193 act("versions differ", "m", f, f, f, rflags, False)
3105
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
194 # is remote's version newer?
5700
9cedc3fbbebb merge: simplify merge tests, fix exec flag bug
Matt Mackall <mpm@selenic.com>
parents: 5695
diff changeset
195 elif m2[f] != a:
5708
f6bf89722e29 merge: add flag merging intelligence
Matt Mackall <mpm@selenic.com>
parents: 5704
diff changeset
196 act("remote is newer", "g", f, rflags)
3113
d1d1cd5b9484 merge: eliminate confusing queued variable
Matt Mackall <mpm@selenic.com>
parents: 3112
diff changeset
197 # local is newer, not overwrite, check mode bits
5708
f6bf89722e29 merge: add flag merging intelligence
Matt Mackall <mpm@selenic.com>
parents: 5704
diff changeset
198 elif m1.flags(f) != rflags:
f6bf89722e29 merge: add flag merging intelligence
Matt Mackall <mpm@selenic.com>
parents: 5704
diff changeset
199 act("update permissions", "e", f, rflags)
3113
d1d1cd5b9484 merge: eliminate confusing queued variable
Matt Mackall <mpm@selenic.com>
parents: 3112
diff changeset
200 # contents same, check mode bits
5708
f6bf89722e29 merge: add flag merging intelligence
Matt Mackall <mpm@selenic.com>
parents: 5704
diff changeset
201 elif m1.flags(f) != rflags:
f6bf89722e29 merge: add flag merging intelligence
Matt Mackall <mpm@selenic.com>
parents: 5704
diff changeset
202 act("update permissions", "e", f, rflags)
3730
d377f8d25662 merge: only store one direction of copies in the copy map
Matt Mackall <mpm@selenic.com>
parents: 3729
diff changeset
203 elif f in copied:
d377f8d25662 merge: only store one direction of copies in the copy map
Matt Mackall <mpm@selenic.com>
parents: 3729
diff changeset
204 continue
3249
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
205 elif f in copy:
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
206 f2 = copy[f]
3733
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
207 if f2 not in m2: # directory rename
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
208 act("remote renamed directory to " + f2, "d",
4007
20da40cc1c73 symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents: 4006
diff changeset
209 f, None, f2, m1.flags(f))
3733
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
210 elif f2 in m1: # case 2 A,B/B/B
3730
d377f8d25662 merge: only store one direction of copies in the copy map
Matt Mackall <mpm@selenic.com>
parents: 3729
diff changeset
211 act("local copied to " + f2, "m",
d377f8d25662 merge: only store one direction of copies in the copy map
Matt Mackall <mpm@selenic.com>
parents: 3729
diff changeset
212 f, f2, f, fmerge(f, f2, f2), False)
d377f8d25662 merge: only store one direction of copies in the copy map
Matt Mackall <mpm@selenic.com>
parents: 3729
diff changeset
213 else: # case 4,21 A/B/B
d377f8d25662 merge: only store one direction of copies in the copy map
Matt Mackall <mpm@selenic.com>
parents: 3729
diff changeset
214 act("local moved to " + f2, "m",
d377f8d25662 merge: only store one direction of copies in the copy map
Matt Mackall <mpm@selenic.com>
parents: 3729
diff changeset
215 f, f2, f, fmerge(f, f2, f2), False)
3105
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
216 elif f in ma:
3117
7a635ef25132 merge: simplify tests for local changed/remote deleted
Matt Mackall <mpm@selenic.com>
parents: 3116
diff changeset
217 if n != ma[f] and not overwrite:
3295
72d1e521da77 merge: use contexts for manifestmerge
Matt Mackall <mpm@selenic.com>
parents: 3292
diff changeset
218 if repo.ui.prompt(
5670
840e2b315c1f Fix misleading error and prompts during update/merge (issue556)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5489
diff changeset
219 _(" local changed %s which remote deleted\n"
840e2b315c1f Fix misleading error and prompts during update/merge (issue556)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5489
diff changeset
220 "use (c)hanged version or (d)elete?") % f,
840e2b315c1f Fix misleading error and prompts during update/merge (issue556)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5489
diff changeset
221 _("[cd]"), _("c")) == _("d"):
3307
f009a6f12a59 merge: swap file and mode args for act()
Matt Mackall <mpm@selenic.com>
parents: 3306
diff changeset
222 act("prompt delete", "r", f)
3105
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
223 else:
3307
f009a6f12a59 merge: swap file and mode args for act()
Matt Mackall <mpm@selenic.com>
parents: 3306
diff changeset
224 act("other deleted", "r", f)
3105
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
225 else:
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
226 # file is created on branch or in working directory
3120
1c1e59aac82a merge: simplify local created logic
Matt Mackall <mpm@selenic.com>
parents: 3119
diff changeset
227 if (overwrite and n[20:] != "u") or (backwards and not n[20:]):
3307
f009a6f12a59 merge: swap file and mode args for act()
Matt Mackall <mpm@selenic.com>
parents: 3306
diff changeset
228 act("remote deleted", "r", f)
3105
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
229
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
230 for f, n in m2.iteritems():
3248
751840e739a1 merge: reduce manifest copying
Matt Mackall <mpm@selenic.com>
parents: 3247
diff changeset
231 if partial and not partial(f):
751840e739a1 merge: reduce manifest copying
Matt Mackall <mpm@selenic.com>
parents: 3247
diff changeset
232 continue
751840e739a1 merge: reduce manifest copying
Matt Mackall <mpm@selenic.com>
parents: 3247
diff changeset
233 if f in m1:
751840e739a1 merge: reduce manifest copying
Matt Mackall <mpm@selenic.com>
parents: 3247
diff changeset
234 continue
3729
581d20773326 merge: add copied hash to simplify copy logic
Matt Mackall <mpm@selenic.com>
parents: 3728
diff changeset
235 if f in copied:
581d20773326 merge: add copied hash to simplify copy logic
Matt Mackall <mpm@selenic.com>
parents: 3728
diff changeset
236 continue
3249
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
237 if f in copy:
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
238 f2 = copy[f]
3733
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
239 if f2 not in m1: # directory rename
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
240 act("local renamed directory to " + f2, "d",
4007
20da40cc1c73 symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents: 4006
diff changeset
241 None, f, f2, m2.flags(f))
3733
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
242 elif f2 in m2: # rename case 1, A/A,B/A
3730
d377f8d25662 merge: only store one direction of copies in the copy map
Matt Mackall <mpm@selenic.com>
parents: 3729
diff changeset
243 act("remote copied to " + f, "m",
d377f8d25662 merge: only store one direction of copies in the copy map
Matt Mackall <mpm@selenic.com>
parents: 3729
diff changeset
244 f2, f, f, fmerge(f2, f, f2), False)
d377f8d25662 merge: only store one direction of copies in the copy map
Matt Mackall <mpm@selenic.com>
parents: 3729
diff changeset
245 else: # case 3,20 A/B/A
d377f8d25662 merge: only store one direction of copies in the copy map
Matt Mackall <mpm@selenic.com>
parents: 3729
diff changeset
246 act("remote moved to " + f, "m",
d377f8d25662 merge: only store one direction of copies in the copy map
Matt Mackall <mpm@selenic.com>
parents: 3729
diff changeset
247 f2, f, f, fmerge(f2, f, f2), True)
3249
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
248 elif f in ma:
3116
920f54a2249e merge: more simplification of m2 manifest scanning
Matt Mackall <mpm@selenic.com>
parents: 3115
diff changeset
249 if overwrite or backwards:
4007
20da40cc1c73 symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents: 4006
diff changeset
250 act("recreating", "g", f, m2.flags(f))
3116
920f54a2249e merge: more simplification of m2 manifest scanning
Matt Mackall <mpm@selenic.com>
parents: 3115
diff changeset
251 elif n != ma[f]:
3295
72d1e521da77 merge: use contexts for manifestmerge
Matt Mackall <mpm@selenic.com>
parents: 3292
diff changeset
252 if repo.ui.prompt(
5670
840e2b315c1f Fix misleading error and prompts during update/merge (issue556)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5489
diff changeset
253 _("remote changed %s which local deleted\n"
840e2b315c1f Fix misleading error and prompts during update/merge (issue556)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5489
diff changeset
254 "use (c)hanged version or leave (d)eleted?") % f,
840e2b315c1f Fix misleading error and prompts during update/merge (issue556)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5489
diff changeset
255 _("[cd]"), _("c")) == _("c"):
4007
20da40cc1c73 symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents: 4006
diff changeset
256 act("prompt recreating", "g", f, m2.flags(f))
3115
bb74f809bc95 merge: reorder tests on m2 items in manifestmerge
Matt Mackall <mpm@selenic.com>
parents: 3114
diff changeset
257 else:
4007
20da40cc1c73 symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents: 4006
diff changeset
258 act("remote created", "g", f, m2.flags(f))
3105
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
259
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
260 return action
7c7469d41ade merge: pull manifest comparison out into separate function
Matt Mackall <mpm@selenic.com>
parents: 3104
diff changeset
261
6805
482581431dcd Sort removes first when applying updates (fixes issues 750 and 912)
Paul Moore <p.f.moore@gmail.com>
parents: 6762
diff changeset
262 def actioncmp(a1, a2):
482581431dcd Sort removes first when applying updates (fixes issues 750 and 912)
Paul Moore <p.f.moore@gmail.com>
parents: 6762
diff changeset
263 m1 = a1[1]
482581431dcd Sort removes first when applying updates (fixes issues 750 and 912)
Paul Moore <p.f.moore@gmail.com>
parents: 6762
diff changeset
264 m2 = a2[1]
482581431dcd Sort removes first when applying updates (fixes issues 750 and 912)
Paul Moore <p.f.moore@gmail.com>
parents: 6762
diff changeset
265 if m1 == m2:
482581431dcd Sort removes first when applying updates (fixes issues 750 and 912)
Paul Moore <p.f.moore@gmail.com>
parents: 6762
diff changeset
266 return cmp(a1, a2)
482581431dcd Sort removes first when applying updates (fixes issues 750 and 912)
Paul Moore <p.f.moore@gmail.com>
parents: 6762
diff changeset
267 if m1 == 'r':
482581431dcd Sort removes first when applying updates (fixes issues 750 and 912)
Paul Moore <p.f.moore@gmail.com>
parents: 6762
diff changeset
268 return -1
482581431dcd Sort removes first when applying updates (fixes issues 750 and 912)
Paul Moore <p.f.moore@gmail.com>
parents: 6762
diff changeset
269 if m2 == 'r':
482581431dcd Sort removes first when applying updates (fixes issues 750 and 912)
Paul Moore <p.f.moore@gmail.com>
parents: 6762
diff changeset
270 return 1
482581431dcd Sort removes first when applying updates (fixes issues 750 and 912)
Paul Moore <p.f.moore@gmail.com>
parents: 6762
diff changeset
271 return cmp(a1, a2)
482581431dcd Sort removes first when applying updates (fixes issues 750 and 912)
Paul Moore <p.f.moore@gmail.com>
parents: 6762
diff changeset
272
3297
69b9471f26bb merge: pass contexts to applyupdates
Matt Mackall <mpm@selenic.com>
parents: 3296
diff changeset
273 def applyupdates(repo, action, wctx, mctx):
3315
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
274 "apply the merge action list to the working directory"
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
275
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
276 updated, merged, removed, unresolved = 0, 0, 0, 0
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
277 ms = mergestate(repo)
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
278 ms.reset(wctx.parents()[0].node())
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
279 moves = []
6805
482581431dcd Sort removes first when applying updates (fixes issues 750 and 912)
Paul Moore <p.f.moore@gmail.com>
parents: 6762
diff changeset
280 action.sort(actioncmp)
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
281
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
282 # prescan for merges
5042
f191bc3916f7 merge: do early copy to deal with issue636
Matt Mackall <mpm@selenic.com>
parents: 4997
diff changeset
283 for a in action:
f191bc3916f7 merge: do early copy to deal with issue636
Matt Mackall <mpm@selenic.com>
parents: 4997
diff changeset
284 f, m = a[:2]
f191bc3916f7 merge: do early copy to deal with issue636
Matt Mackall <mpm@selenic.com>
parents: 4997
diff changeset
285 if m == 'm': # merge
f191bc3916f7 merge: do early copy to deal with issue636
Matt Mackall <mpm@selenic.com>
parents: 4997
diff changeset
286 f2, fd, flags, move = a[2:]
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
287 repo.ui.debug(_("preserving %s for resolve of %s\n") % (f, fd))
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
288 fcl = wctx[f]
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
289 fco = mctx[f2]
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
290 fca = fcl.ancestor(fco) or repo.filectx(f, fileid=nullrev)
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
291 ms.add(fcl, fco, fca, fd, flags)
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
292 if f != fd and move:
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
293 moves.append(f)
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
294
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
295 # remove renamed files after safely stored
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
296 for f in moves:
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
297 if util.lexists(repo.wjoin(f)):
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
298 repo.ui.debug(_("removing %s\n") % f)
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
299 os.unlink(repo.wjoin(f))
5042
f191bc3916f7 merge: do early copy to deal with issue636
Matt Mackall <mpm@selenic.com>
parents: 4997
diff changeset
300
5158
d316124ebbea Make audit_path more stringent.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5060
diff changeset
301 audit_path = util.path_auditor(repo.root)
d316124ebbea Make audit_path more stringent.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5060
diff changeset
302
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
303 for a in action:
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
304 f, m = a[:2]
3733
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
305 if f and f[0] == "/":
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
306 continue
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
307 if m == "r": # remove
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
308 repo.ui.note(_("removing %s\n") % f)
5158
d316124ebbea Make audit_path more stringent.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5060
diff changeset
309 audit_path(f)
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
310 try:
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
311 util.unlink(repo.wjoin(f))
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
312 except OSError, inst:
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
313 if inst.errno != errno.ENOENT:
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
314 repo.ui.warn(_("update failed to remove %s: %s!\n") %
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
315 (f, inst.strerror))
3673
eb0b4a2d70a9 white space and line break cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3618
diff changeset
316 removed += 1
3308
ecc1bf27378c merge: unify merge and copy actions
Matt Mackall <mpm@selenic.com>
parents: 3307
diff changeset
317 elif m == "m": # merge
4007
20da40cc1c73 symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents: 4006
diff changeset
318 f2, fd, flags, move = a[2:]
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
319 r = ms.resolve(fd, wctx, mctx)
3400
d2b55e3c4e25 merge: if filemerge skips merge, report as updated
Matt Mackall <mpm@selenic.com>
parents: 3372
diff changeset
320 if r > 0:
3249
f05c182430a0 merge: add rename following
Matt Mackall <mpm@selenic.com>
parents: 3248
diff changeset
321 unresolved += 1
3309
e8be5942335d merge: pull file copy/move out of filemerge
Matt Mackall <mpm@selenic.com>
parents: 3308
diff changeset
322 else:
3400
d2b55e3c4e25 merge: if filemerge skips merge, report as updated
Matt Mackall <mpm@selenic.com>
parents: 3372
diff changeset
323 if r is None:
d2b55e3c4e25 merge: if filemerge skips merge, report as updated
Matt Mackall <mpm@selenic.com>
parents: 3372
diff changeset
324 updated += 1
d2b55e3c4e25 merge: if filemerge skips merge, report as updated
Matt Mackall <mpm@selenic.com>
parents: 3372
diff changeset
325 else:
d2b55e3c4e25 merge: if filemerge skips merge, report as updated
Matt Mackall <mpm@selenic.com>
parents: 3372
diff changeset
326 merged += 1
6877
1d38f3605b20 util: set_flags shouldn't know about repo flag formats
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
327 util.set_flags(repo.wjoin(fd), 'l' in flags, 'x' in flags)
5059
8d9bdcbb2b18 merge: avoid double deletion mentioned in issue636
Matt Mackall <mpm@selenic.com>
parents: 5042
diff changeset
328 if f != fd and move and util.lexists(repo.wjoin(f)):
5042
f191bc3916f7 merge: do early copy to deal with issue636
Matt Mackall <mpm@selenic.com>
parents: 4997
diff changeset
329 repo.ui.debug(_("removing %s\n") % f)
f191bc3916f7 merge: do early copy to deal with issue636
Matt Mackall <mpm@selenic.com>
parents: 4997
diff changeset
330 os.unlink(repo.wjoin(f))
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
331 elif m == "g": # get
4007
20da40cc1c73 symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents: 4006
diff changeset
332 flags = a[2]
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
333 repo.ui.note(_("getting %s\n") % f)
3303
488d3062d225 merge: eliminate nodes from action list
Matt Mackall <mpm@selenic.com>
parents: 3299
diff changeset
334 t = mctx.filectx(f).data()
4007
20da40cc1c73 symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents: 4006
diff changeset
335 repo.wwrite(f, t, flags)
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
336 updated += 1
3733
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
337 elif m == "d": # directory rename
4007
20da40cc1c73 symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents: 4006
diff changeset
338 f2, fd, flags = a[2:]
3733
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
339 if f:
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
340 repo.ui.note(_("moving %s to %s\n") % (f, fd))
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
341 t = wctx.filectx(f).data()
4007
20da40cc1c73 symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents: 4006
diff changeset
342 repo.wwrite(fd, t, flags)
3733
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
343 util.unlink(repo.wjoin(f))
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
344 if f2:
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
345 repo.ui.note(_("getting %s to %s\n") % (f2, fd))
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
346 t = mctx.filectx(f2).data()
4007
20da40cc1c73 symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents: 4006
diff changeset
347 repo.wwrite(fd, t, flags)
3733
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
348 updated += 1
4674
723e0ddb6ada merge: warn user about divergent renames
Matt Mackall <mpm@selenic.com>
parents: 4635
diff changeset
349 elif m == "dr": # divergent renames
723e0ddb6ada merge: warn user about divergent renames
Matt Mackall <mpm@selenic.com>
parents: 4635
diff changeset
350 fl = a[2]
6953
63b5f4c73c98 i18n: mark strings for translation in Mercurial
Martin Geisler <mg@daimi.au.dk>
parents: 6884
diff changeset
351 repo.ui.warn(_("warning: detected divergent renames of %s to:\n") % f)
4674
723e0ddb6ada merge: warn user about divergent renames
Matt Mackall <mpm@selenic.com>
parents: 4635
diff changeset
352 for nf in fl:
723e0ddb6ada merge: warn user about divergent renames
Matt Mackall <mpm@selenic.com>
parents: 4635
diff changeset
353 repo.ui.warn(" %s\n" % nf)
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
354 elif m == "e": # exec
4007
20da40cc1c73 symlinks: minimal support for symlinks in merge/update
Matt Mackall <mpm@selenic.com>
parents: 4006
diff changeset
355 flags = a[2]
6877
1d38f3605b20 util: set_flags shouldn't know about repo flag formats
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
356 util.set_flags(repo.wjoin(f), 'l' in flags, 'x' in flags)
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
357
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
358 return updated, merged, removed, unresolved
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
359
3372
ba7c74081861 merge: update dirstate correctly for non-branchmerge updates
Matt Mackall <mpm@selenic.com>
parents: 3371
diff changeset
360 def recordupdates(repo, action, branchmerge):
3315
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
361 "record merge actions to the dirstate"
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
362
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
363 for a in action:
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
364 f, m = a[:2]
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
365 if m == "r": # remove
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
366 if branchmerge:
4904
6fd953d5faea dirstate: break update into separate functions
Matt Mackall <mpm@selenic.com>
parents: 4884
diff changeset
367 repo.dirstate.remove(f)
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
368 else:
4904
6fd953d5faea dirstate: break update into separate functions
Matt Mackall <mpm@selenic.com>
parents: 4884
diff changeset
369 repo.dirstate.forget(f)
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
370 elif m == "f": # forget
4904
6fd953d5faea dirstate: break update into separate functions
Matt Mackall <mpm@selenic.com>
parents: 4884
diff changeset
371 repo.dirstate.forget(f)
4997
60c54154ec4c merge: don't forget to update the dirstate for exec bit changes
Matt Mackall <mpm@selenic.com>
parents: 4884
diff changeset
372 elif m in "ge": # get or exec change
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
373 if branchmerge:
4904
6fd953d5faea dirstate: break update into separate functions
Matt Mackall <mpm@selenic.com>
parents: 4884
diff changeset
374 repo.dirstate.normaldirty(f)
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
375 else:
4904
6fd953d5faea dirstate: break update into separate functions
Matt Mackall <mpm@selenic.com>
parents: 4884
diff changeset
376 repo.dirstate.normal(f)
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
377 elif m == "m": # merge
3303
488d3062d225 merge: eliminate nodes from action list
Matt Mackall <mpm@selenic.com>
parents: 3299
diff changeset
378 f2, fd, flag, move = a[2:]
3251
c93ce7f10f85 merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents: 3249
diff changeset
379 if branchmerge:
c93ce7f10f85 merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents: 3249
diff changeset
380 # We've done a branch merge, mark this file as merged
c93ce7f10f85 merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents: 3249
diff changeset
381 # so that we properly record the merger later
4904
6fd953d5faea dirstate: break update into separate functions
Matt Mackall <mpm@selenic.com>
parents: 4884
diff changeset
382 repo.dirstate.merge(fd)
3372
ba7c74081861 merge: update dirstate correctly for non-branchmerge updates
Matt Mackall <mpm@selenic.com>
parents: 3371
diff changeset
383 if f != f2: # copy/rename
ba7c74081861 merge: update dirstate correctly for non-branchmerge updates
Matt Mackall <mpm@selenic.com>
parents: 3371
diff changeset
384 if move:
4904
6fd953d5faea dirstate: break update into separate functions
Matt Mackall <mpm@selenic.com>
parents: 4884
diff changeset
385 repo.dirstate.remove(f)
3372
ba7c74081861 merge: update dirstate correctly for non-branchmerge updates
Matt Mackall <mpm@selenic.com>
parents: 3371
diff changeset
386 if f != fd:
ba7c74081861 merge: update dirstate correctly for non-branchmerge updates
Matt Mackall <mpm@selenic.com>
parents: 3371
diff changeset
387 repo.dirstate.copy(f, fd)
ba7c74081861 merge: update dirstate correctly for non-branchmerge updates
Matt Mackall <mpm@selenic.com>
parents: 3371
diff changeset
388 else:
ba7c74081861 merge: update dirstate correctly for non-branchmerge updates
Matt Mackall <mpm@selenic.com>
parents: 3371
diff changeset
389 repo.dirstate.copy(f2, fd)
3251
c93ce7f10f85 merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents: 3249
diff changeset
390 else:
c93ce7f10f85 merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents: 3249
diff changeset
391 # We've update-merged a locally modified file, so
c93ce7f10f85 merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents: 3249
diff changeset
392 # we set the dirstate to emulate a normal checkout
c93ce7f10f85 merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents: 3249
diff changeset
393 # of that file some time in the past. Thus our
c93ce7f10f85 merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents: 3249
diff changeset
394 # merge will appear as a normal local file
c93ce7f10f85 merge: fixes for merge+rename
Matt Mackall <mpm@selenic.com>
parents: 3249
diff changeset
395 # modification.
5210
90d9ec0dc69d merge: forcefully mark files that we get from the second parent as dirty
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5161
diff changeset
396 repo.dirstate.normallookup(fd)
3308
ecc1bf27378c merge: unify merge and copy actions
Matt Mackall <mpm@selenic.com>
parents: 3307
diff changeset
397 if move:
4904
6fd953d5faea dirstate: break update into separate functions
Matt Mackall <mpm@selenic.com>
parents: 4884
diff changeset
398 repo.dirstate.forget(f)
3733
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
399 elif m == "d": # directory rename
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
400 f2, fd, flag = a[2:]
4819
9797124581c9 merge: fix adding untracked files on directory rename (issue612)
Matt Mackall <mpm@selenic.com>
parents: 4748
diff changeset
401 if not f2 and f not in repo.dirstate:
9797124581c9 merge: fix adding untracked files on directory rename (issue612)
Matt Mackall <mpm@selenic.com>
parents: 4748
diff changeset
402 # untracked file moved
9797124581c9 merge: fix adding untracked files on directory rename (issue612)
Matt Mackall <mpm@selenic.com>
parents: 4748
diff changeset
403 continue
3733
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
404 if branchmerge:
4904
6fd953d5faea dirstate: break update into separate functions
Matt Mackall <mpm@selenic.com>
parents: 4884
diff changeset
405 repo.dirstate.add(fd)
3733
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
406 if f:
4904
6fd953d5faea dirstate: break update into separate functions
Matt Mackall <mpm@selenic.com>
parents: 4884
diff changeset
407 repo.dirstate.remove(f)
3733
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
408 repo.dirstate.copy(f, fd)
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
409 if f2:
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
410 repo.dirstate.copy(f2, fd)
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
411 else:
4904
6fd953d5faea dirstate: break update into separate functions
Matt Mackall <mpm@selenic.com>
parents: 4884
diff changeset
412 repo.dirstate.normal(fd)
3733
9e67fecbfd16 merge: handle directory renames
Matt Mackall <mpm@selenic.com>
parents: 3732
diff changeset
413 if f:
4904
6fd953d5faea dirstate: break update into separate functions
Matt Mackall <mpm@selenic.com>
parents: 4884
diff changeset
414 repo.dirstate.forget(f)
3111
5cc62d99b785 merge: move apply and dirstate code into separate functions
Matt Mackall <mpm@selenic.com>
parents: 3110
diff changeset
415
4917
126f527b3ba3 Make repo locks recursive, eliminate all passing of lock/wlock
Matt Mackall <mpm@selenic.com>
parents: 4915
diff changeset
416 def update(repo, node, branchmerge, force, partial):
3315
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
417 """
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
418 Perform a merge between the working directory and the given node
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
419
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
420 branchmerge = whether to merge between branches
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
421 force = whether to force branch merging or file overwriting
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
422 partial = a function to filter file lists (dirstate not updated)
38be819a1225 merge: update some docstrings
Matt Mackall <mpm@selenic.com>
parents: 3314
diff changeset
423 """
2815
4870f795f681 Merge: combine force and forcemerge arguments
Matt Mackall <mpm@selenic.com>
parents: 2814
diff changeset
424
4917
126f527b3ba3 Make repo locks recursive, eliminate all passing of lock/wlock
Matt Mackall <mpm@selenic.com>
parents: 4915
diff changeset
425 wlock = repo.wlock()
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
426 try:
6747
f6c00b17387c use repo[changeid] to get a changectx
Matt Mackall <mpm@selenic.com>
parents: 6746
diff changeset
427 wc = repo[None]
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
428 if node is None:
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
429 # tip of current branch
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
430 try:
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
431 node = repo.branchtags()[wc.branch()]
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
432 except KeyError:
5570
78a6b985882f update: default to tipmost branch if default branch doesn't exist
Matt Mackall <mpm@selenic.com>
parents: 5489
diff changeset
433 if wc.branch() == "default": # no default branch!
78a6b985882f update: default to tipmost branch if default branch doesn't exist
Matt Mackall <mpm@selenic.com>
parents: 5489
diff changeset
434 node = repo.lookup("tip") # update to tip
78a6b985882f update: default to tipmost branch if default branch doesn't exist
Matt Mackall <mpm@selenic.com>
parents: 5489
diff changeset
435 else:
78a6b985882f update: default to tipmost branch if default branch doesn't exist
Matt Mackall <mpm@selenic.com>
parents: 5489
diff changeset
436 raise util.Abort(_("branch %s not found") % wc.branch())
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
437 overwrite = force and not branchmerge
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
438 pl = wc.parents()
6747
f6c00b17387c use repo[changeid] to get a changectx
Matt Mackall <mpm@selenic.com>
parents: 6746
diff changeset
439 p1, p2 = pl[0], repo[node]
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
440 pa = p1.ancestor(p2)
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
441 fp1, fp2, xp1, xp2 = p1.node(), p2.node(), str(p1), str(p2)
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
442 fastforward = False
3314
b16456909a0a merge: various tidying
Matt Mackall <mpm@selenic.com>
parents: 3312
diff changeset
443
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
444 ### check phase
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
445 if not overwrite and len(pl) > 1:
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
446 raise util.Abort(_("outstanding uncommitted merges"))
6375
cdc458b12f0f update: better logic and messages for updates
Matt Mackall <mpm@selenic.com>
parents: 6350
diff changeset
447 if branchmerge:
cdc458b12f0f update: better logic and messages for updates
Matt Mackall <mpm@selenic.com>
parents: 6350
diff changeset
448 if pa == p2:
cdc458b12f0f update: better logic and messages for updates
Matt Mackall <mpm@selenic.com>
parents: 6350
diff changeset
449 raise util.Abort(_("can't merge with ancestor"))
cdc458b12f0f update: better logic and messages for updates
Matt Mackall <mpm@selenic.com>
parents: 6350
diff changeset
450 elif pa == p1:
cdc458b12f0f update: better logic and messages for updates
Matt Mackall <mpm@selenic.com>
parents: 6350
diff changeset
451 if p1.branch() != p2.branch():
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
452 fastforward = True
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
453 else:
6375
cdc458b12f0f update: better logic and messages for updates
Matt Mackall <mpm@selenic.com>
parents: 6350
diff changeset
454 raise util.Abort(_("nothing to merge (use 'hg update'"
cdc458b12f0f update: better logic and messages for updates
Matt Mackall <mpm@selenic.com>
parents: 6350
diff changeset
455 " or check 'hg heads')"))
cdc458b12f0f update: better logic and messages for updates
Matt Mackall <mpm@selenic.com>
parents: 6350
diff changeset
456 if not force and (wc.files() or wc.deleted()):
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
457 raise util.Abort(_("outstanding uncommitted changes"))
6375
cdc458b12f0f update: better logic and messages for updates
Matt Mackall <mpm@selenic.com>
parents: 6350
diff changeset
458 elif not overwrite:
cdc458b12f0f update: better logic and messages for updates
Matt Mackall <mpm@selenic.com>
parents: 6350
diff changeset
459 if pa == p1 or pa == p2: # linear
cdc458b12f0f update: better logic and messages for updates
Matt Mackall <mpm@selenic.com>
parents: 6350
diff changeset
460 pass # all good
cdc458b12f0f update: better logic and messages for updates
Matt Mackall <mpm@selenic.com>
parents: 6350
diff changeset
461 elif p1.branch() == p2.branch():
cdc458b12f0f update: better logic and messages for updates
Matt Mackall <mpm@selenic.com>
parents: 6350
diff changeset
462 if wc.files() or wc.deleted():
cdc458b12f0f update: better logic and messages for updates
Matt Mackall <mpm@selenic.com>
parents: 6350
diff changeset
463 raise util.Abort(_("crosses branches (use 'hg merge' or "
cdc458b12f0f update: better logic and messages for updates
Matt Mackall <mpm@selenic.com>
parents: 6350
diff changeset
464 "'hg update -C' to discard changes)"))
6381
0b89315d5de2 Fix missing space in one of the new update messages.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6375
diff changeset
465 raise util.Abort(_("crosses branches (use 'hg merge' "
6375
cdc458b12f0f update: better logic and messages for updates
Matt Mackall <mpm@selenic.com>
parents: 6350
diff changeset
466 "or 'hg update -C')"))
cdc458b12f0f update: better logic and messages for updates
Matt Mackall <mpm@selenic.com>
parents: 6350
diff changeset
467 elif wc.files() or wc.deleted():
cdc458b12f0f update: better logic and messages for updates
Matt Mackall <mpm@selenic.com>
parents: 6350
diff changeset
468 raise util.Abort(_("crosses named branches (use "
cdc458b12f0f update: better logic and messages for updates
Matt Mackall <mpm@selenic.com>
parents: 6350
diff changeset
469 "'hg update -C' to discard changes)"))
cdc458b12f0f update: better logic and messages for updates
Matt Mackall <mpm@selenic.com>
parents: 6350
diff changeset
470 else:
cdc458b12f0f update: better logic and messages for updates
Matt Mackall <mpm@selenic.com>
parents: 6350
diff changeset
471 # Allow jumping branches if there are no changes
cdc458b12f0f update: better logic and messages for updates
Matt Mackall <mpm@selenic.com>
parents: 6350
diff changeset
472 overwrite = True
2814
0f787997e3c2 Merge: move most tests to the beginning
Matt Mackall <mpm@selenic.com>
parents: 2813
diff changeset
473
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
474 ### calculate phase
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
475 action = []
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
476 if not force:
6269
ffdf70e74623 merge: privatize some functions, unnest some others
Matt Mackall <mpm@selenic.com>
parents: 6268
diff changeset
477 _checkunknown(wc, p2)
6746
1dca460e7d1e rename checkfolding to checkcase
Matt Mackall <mpm@selenic.com>
parents: 6740
diff changeset
478 if not util.checkcase(repo.path):
6269
ffdf70e74623 merge: privatize some functions, unnest some others
Matt Mackall <mpm@selenic.com>
parents: 6268
diff changeset
479 _checkcollision(p2)
ffdf70e74623 merge: privatize some functions, unnest some others
Matt Mackall <mpm@selenic.com>
parents: 6268
diff changeset
480 action += _forgetremoved(wc, p2, branchmerge)
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
481 action += manifestmerge(repo, wc, p2, pa, overwrite, partial)
2775
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
482
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
483 ### apply phase
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
484 if not branchmerge: # just jump to the new rev
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
485 fp1, fp2, xp1, xp2 = fp2, nullid, xp2, ''
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
486 if not partial:
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
487 repo.hook('preupdate', throw=True, parent1=xp1, parent2=xp2)
2775
b550cd82f92a Move merge code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
488
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
489 stats = applyupdates(repo, action, wc, p2)
2899
8743188f4d2e merge: consolidate dirstate updates
Matt Mackall <mpm@selenic.com>
parents: 2898
diff changeset
490
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
491 if not partial:
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
492 recordupdates(repo, action, branchmerge)
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
493 repo.dirstate.setparents(fp1, fp2)
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
494 if not branchmerge and not fastforward:
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
495 repo.dirstate.setbranch(p2.branch())
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
496 repo.hook('update', parent1=xp1, parent2=xp2, error=stats[3])
3314
b16456909a0a merge: various tidying
Matt Mackall <mpm@selenic.com>
parents: 3312
diff changeset
497
4915
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
498 return stats
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
499 finally:
97b734fb9c6f Use try/finally pattern to cleanup locks and transactions
Matt Mackall <mpm@selenic.com>
parents: 4904
diff changeset
500 del wlock