comparison hgext/imerge.py @ 5063:86327d13d916

imerge: handle renames
author Brendan Cully <brendan@kublai.com>
date Fri, 03 Aug 2007 18:05:20 -0700
parents ec70fd08e16c
children 420e1166a876
comparison
equal deleted inserted replaced
5054:ec70fd08e16c 5063:86327d13d916
21 21
22 st = os.path.join(self.im.path, 'status') 22 st = os.path.join(self.im.path, 'status')
23 tf.add(st, os.path.join('.hg', 'imerge', 'status')) 23 tf.add(st, os.path.join('.hg', 'imerge', 'status'))
24 24
25 for f in self.im.resolved: 25 for f in self.im.resolved:
26 abssrc = self.im.repo.wjoin(f) 26 (fd, fo) = self.im.conflicts[f]
27 tf.add(abssrc, f) 27 abssrc = self.im.repo.wjoin(fd)
28 tf.add(abssrc, fd)
28 29
29 tf.close() 30 tf.close()
30 31
31 def load(self, source): 32 def load(self, source):
32 wlock = self.im.repo.wlock() 33 wlock = self.im.repo.wlock()
37 statusfile = os.path.join('.hg', 'imerge', 'status') 38 statusfile = os.path.join('.hg', 'imerge', 'status')
38 if statusfile not in contents: 39 if statusfile not in contents:
39 raise InvalidStateFileException('no status file') 40 raise InvalidStateFileException('no status file')
40 41
41 tf.extract(statusfile, self.im.repo.root) 42 tf.extract(statusfile, self.im.repo.root)
42 self.im.load() 43 p1, p2 = self.im.load()
43 p1 = self.im.parents[0].node() 44 if self.im.repo.dirstate.parents()[0] != p1.node():
44 p2 = self.im.parents[1].node() 45 hg.clean(self.im.repo, p1.node())
45 if self.im.repo.dirstate.parents()[0] != p1: 46 self.im.start(p2.node())
46 hg.clean(self.im.repo, self.im.parents[0].node())
47 self.im.start(p2)
48 tf.extractall(self.im.repo.root) 47 tf.extractall(self.im.repo.root)
49 self.im.load() 48 self.im.load()
50 49
51 class Imerge(object): 50 class Imerge(object):
52 def __init__(self, ui, repo): 51 def __init__(self, ui, repo):
54 self.repo = repo 53 self.repo = repo
55 54
56 self.path = repo.join('imerge') 55 self.path = repo.join('imerge')
57 self.opener = util.opener(self.path) 56 self.opener = util.opener(self.path)
58 57
59 self.parents = [self.repo.changectx(n) 58 self.wctx = self.repo.workingctx()
60 for n in self.repo.dirstate.parents()]
61 self.conflicts = {} 59 self.conflicts = {}
62 self.resolved = [] 60 self.resolved = []
63 61
64 def merging(self): 62 def merging(self):
65 return self.parents[1].node() != nullid 63 return len(self.wctx.parents()) > 1
66 64
67 def load(self): 65 def load(self):
68 # status format. \0-delimited file, fields are 66 # status format. \0-delimited file, fields are
69 # p1, p2, conflict count, conflict filenames, resolved filenames 67 # p1, p2, conflict count, conflict filenames, resolved filenames
70 # conflict filenames are tuples of localname, remoteorig, remotenew 68 # conflict filenames are tuples of localname, remoteorig, remotenew
74 status = statusfile.read().split('\0') 72 status = statusfile.read().split('\0')
75 if len(status) < 3: 73 if len(status) < 3:
76 raise util.Abort('invalid imerge status file') 74 raise util.Abort('invalid imerge status file')
77 75
78 try: 76 try:
79 self.parents = [self.repo.changectx(n) for n in status[:2]] 77 parents = [self.repo.changectx(n) for n in status[:2]]
80 except LookupError: 78 except LookupError:
81 raise util.Abort('merge parent %s not in repository' % short(p)) 79 raise util.Abort('merge parent %s not in repository' % short(p))
82 80
83 status = status[2:] 81 status = status[2:]
84 conflicts = int(status.pop(0)) * 3 82 conflicts = int(status.pop(0)) * 3
85 self.resolved = status[conflicts:] 83 self.resolved = status[conflicts:]
86 for i in xrange(0, conflicts, 3): 84 for i in xrange(0, conflicts, 3):
87 self.conflicts[status[i]] = (status[i+1], status[i+2]) 85 self.conflicts[status[i]] = (status[i+1], status[i+2])
88 86
87 return parents
88
89 def save(self): 89 def save(self):
90 lock = self.repo.lock() 90 lock = self.repo.lock()
91 91
92 if not os.path.isdir(self.path): 92 if not os.path.isdir(self.path):
93 os.mkdir(self.path) 93 os.mkdir(self.path)
94 fd = self.opener('status', 'wb') 94 fd = self.opener('status', 'wb')
95 95
96 out = [hex(n.node()) for n in self.parents] 96 out = [hex(n.node()) for n in self.wctx.parents()]
97 out.append(str(len(self.conflicts))) 97 out.append(str(len(self.conflicts)))
98 for f in sorted(self.conflicts): 98 for f in sorted(self.conflicts):
99 out.append(f) 99 out.append(f)
100 out.extend(self.conflicts[f]) 100 out.extend(self.conflicts[f])
101 out.extend(self.resolved) 101 out.extend(self.resolved)
107 107
108 def filemerge(self, fn): 108 def filemerge(self, fn):
109 wlock = self.repo.wlock() 109 wlock = self.repo.wlock()
110 110
111 (fd, fo) = self.conflicts[fn] 111 (fd, fo) = self.conflicts[fn]
112 return merge.filemerge(self.repo, fn, fd, fo, self.parents[0], 112 p2 = self.wctx.parents()[1]
113 self.parents[1]) 113 return merge.filemerge(self.repo, fn, fd, fo, self.wctx, p2)
114 114
115 def start(self, rev=None): 115 def start(self, rev=None):
116 _filemerge = merge.filemerge 116 _filemerge = merge.filemerge
117 def filemerge(repo, fw, fd, fo, wctx, mctx): 117 def filemerge(repo, fw, fd, fo, wctx, mctx):
118 self.conflicts[fw] = (fd, fo) 118 self.conflicts[fw] = (fd, fo)
119 119
120 merge.filemerge = filemerge 120 merge.filemerge = filemerge
121 commands.merge(self.ui, self.repo, rev=rev) 121 commands.merge(self.ui, self.repo, rev=rev)
122 merge.filemerge = _filemerge 122 merge.filemerge = _filemerge
123 123
124 self.parents = [self.repo.changectx(n) 124 self.wctx = self.repo.workingctx()
125 for n in self.repo.dirstate.parents()]
126 self.save() 125 self.save()
127 126
128 def resume(self): 127 def resume(self):
129 self.load() 128 self.load()
130 129
131 dp = self.repo.dirstate.parents() 130 dp = self.repo.dirstate.parents()
132 if self.parents[0].node() != dp[0] or self.parents[1].node() != dp[1]: 131 p1, p2 = self.wctx.parents()
132 if p1.node() != dp[0] or p2.node() != dp[1]:
133 raise util.Abort('imerge state does not match working directory') 133 raise util.Abort('imerge state does not match working directory')
134 134
135 def status(self): 135 def status(self):
136 p1, p2 = self.wctx.parents()
136 self.ui.write('merging %s and %s\n' % \ 137 self.ui.write('merging %s and %s\n' % \
137 (short(self.parents[0].node()), 138 (short(p1.node()), short(p2.node())))
138 short(self.parents[1].node())))
139 139
140 if self.resolved: 140 if self.resolved:
141 self.ui.write('resolved:\n') 141 self.ui.write('resolved:\n')
142 for fn in self.resolved: 142 for fn in self.resolved:
143 self.ui.write(' %s\n' % fn) 143 self.ui.write(' %s\n' % fn)