Mercurial > hg > mercurial-crew-with-dirclash
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) |