7 |
7 |
8 from node import * |
8 from node import * |
9 from i18n import gettext as _ |
9 from i18n import gettext as _ |
10 from demandload import * |
10 from demandload import * |
11 demandload(globals(), "errno util os tempfile") |
11 demandload(globals(), "errno util os tempfile") |
12 |
|
13 def fmerge(f, local, other, ancestor): |
|
14 """merge executable flags""" |
|
15 a, b, c = ancestor.execf(f), local.execf(f), other.execf(f) |
|
16 return ((a^b) | (a^c)) ^ a |
|
17 |
12 |
18 def merge3(repo, fn, my, other, p1, p2): |
13 def merge3(repo, fn, my, other, p1, p2): |
19 """perform a 3-way merge in the working directory""" |
14 """perform a 3-way merge in the working directory""" |
20 |
15 |
21 def temp(prefix, node): |
16 def temp(prefix, node): |
102 def manifestmerge(ui, m1, m2, ma, overwrite, backwards, partial): |
97 def manifestmerge(ui, m1, m2, ma, overwrite, backwards, partial): |
103 """ |
98 """ |
104 Merge manifest m1 with m2 using ancestor ma and generate merge action list |
99 Merge manifest m1 with m2 using ancestor ma and generate merge action list |
105 """ |
100 """ |
106 |
101 |
|
102 def fmerge(f): |
|
103 """merge executable flags""" |
|
104 a, b, c = ma.execf(f), m1.execf(f), m2.execf(f) |
|
105 return ((a^b) | (a^c)) ^ a |
|
106 |
107 action = [] |
107 action = [] |
108 |
108 |
109 # Filter manifests |
109 # Filter manifests |
110 if partial: |
110 if partial: |
111 for f in m1.keys(): |
111 for f in m1.keys(): |
120 if n != m2[f]: |
120 if n != m2[f]: |
121 a = ma.get(f, nullid) |
121 a = ma.get(f, nullid) |
122 # are both different from the ancestor? |
122 # are both different from the ancestor? |
123 if not overwrite and n != a and m2[f] != a: |
123 if not overwrite and n != a and m2[f] != a: |
124 ui.debug(_(" %s versions differ, resolve\n") % f) |
124 ui.debug(_(" %s versions differ, resolve\n") % f) |
125 action.append((f, "m", fmerge(f, m1, m2, ma), n[:20], m2[f])) |
125 action.append((f, "m", fmerge(f), n[:20], m2[f])) |
126 # are we clobbering? |
126 # are we clobbering? |
127 # is remote's version newer? |
127 # is remote's version newer? |
128 # or are we going back in time and clean? |
128 # or are we going back in time and clean? |
129 elif overwrite or m2[f] != a or (backwards and not n[20:]): |
129 elif overwrite or m2[f] != a or (backwards and not n[20:]): |
130 ui.debug(_(" remote %s is newer, get\n") % f) |
130 ui.debug(_(" remote %s is newer, get\n") % f) |
131 action.append((f, "g", m2.execf(f), m2[f])) |
131 action.append((f, "g", m2.execf(f), m2[f])) |
132 # local is newer, not overwrite, check mode bits |
132 # local is newer, not overwrite, check mode bits |
133 elif m1.execf(f) != m2.execf(f): |
133 elif fmerge(f) != m1.execf(f): |
134 mode = fmerge(f, m1, m2, ma) |
134 ui.debug(_(" updating permissions for %s\n") % f) |
135 if mode != m1.execf(f): |
135 action.append((f, "e", m2.execf(f))) |
136 ui.debug(_(" updating permissions for %s\n") % f) |
|
137 action.append((f, "e", m2.execf(f))) |
|
138 |
136 |
139 # contents same, check mode bits |
137 # contents same, check mode bits |
140 elif m1.execf(f) != m2.execf(f): |
138 elif m1.execf(f) != m2.execf(f): |
141 if overwrite: |
139 if overwrite or fmerge(f) != m1.execf(f) |
142 ui.debug(_(" updating permissions for %s\n") % f) |
140 ui.debug(_(" updating permissions for %s\n") % f) |
143 action.append((f, "e", m2.execf(f))) |
141 action.append((f, "e", m2.execf(f))) |
144 else: |
|
145 mode = fmerge(f, m1, m2, ma) |
|
146 if mode != m1.execf(f): |
|
147 ui.debug(_(" updating permissions for %s\n") % f) |
|
148 action.append((f, "e", m2.execf(f))) |
|
149 del m2[f] |
142 del m2[f] |
150 elif f in ma: |
143 elif f in ma: |
151 if n != ma[f] and not overwrite: |
144 if n != ma[f] and not overwrite: |
152 r = ui.prompt( |
145 r = ui.prompt( |
153 (_(" local changed %s which remote deleted\n") % f) + |
146 (_(" local changed %s which remote deleted\n") % f) + |