Mercurial > hg
changeset 146:4a828422247d
Handle merge with deletions
If you merge with a repo that has deleted a file after editing it, hg
attempted to resolve the file. This (correctly) resulted in hg verify
errors because the resolved version didn't show up in the manifests.
This moves the manifest resolution before file resolution and decides
which files to resolve based on the (partially) resolved manifest.
After files are resolved, the final manifest is committed.
author | mpm@selenic.com |
---|---|
date | Tue, 24 May 2005 20:30:35 -0800 |
parents | fbce9fc531d2 |
children | b6d8ed7aeba0 |
files | mercurial/hg.py |
diffstat | 1 files changed, 66 insertions(+), 59 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/hg.py Tue May 24 20:29:38 2005 -0800 +++ b/mercurial/hg.py Tue May 24 20:30:35 2005 -0800 @@ -612,6 +612,7 @@ tr = self.transaction() simple = True + need = {} self.ui.status("adding changesets\n") # pull off the changeset group @@ -634,9 +635,62 @@ simple = False resolverev = self.changelog.count() + # resolve the manifest to determine which files + # we care about merging + self.ui.status("resolving manifests\n") + ma = self.manifest.ancestor(mm, mo) + omap = self.manifest.read(mo) # other + amap = self.manifest.read(ma) # ancestor + mmap = self.manifest.read(mm) # mine + nmap = {} + + self.ui.debug(" ancestor %s local %s remote %s\n" % + (short(ma), short(mm), short(mo))) + + for f, mid in mmap.iteritems(): + if f in omap: + if mid != omap[f]: + self.ui.debug(" %s versions differ, do resolve\n" % f) + need[f] = mid # use merged version or local version + else: + nmap[f] = mid # keep ours + del omap[f] + elif f in amap: + if mid != amap[f]: + r = self.ui.prompt( + (" local changed %s which remote deleted\n" % f) + + "(k)eep or (d)elete?", "[kd]", "k") + if r == "k": nmap[f] = mid + else: + self.ui.debug("other deleted %s\n" % f) + pass # other deleted it + else: + self.ui.debug("local created %s\n" %f) + nmap[f] = mid # we created it + + del mmap + + for f, oid in omap.iteritems(): + if f in amap: + if oid != amap[f]: + r = self.ui.prompt( + ("remote changed %s which local deleted\n" % f) + + "(k)eep or (d)elete?", "[kd]", "k") + if r == "k": nmap[f] = oid + else: + pass # probably safe + else: + self.ui.debug("remote created %s, do resolve\n" % f) + need[f] = oid + + del omap + del amap + + new = need.keys() + new.sort() + # process the files self.ui.status("adding files\n") - new = {} while 1: f = getchunk(4) if not f: break @@ -645,11 +699,17 @@ fl = self.file(f) o = fl.tip() n = fl.addgroup(fg, lambda x: self.changelog.rev(x), tr) - if not simple: - if o == n: continue - # this file has changed between branches, so it must be - # represented in the merge changeset - new[f] = self.merge3(fl, f, o, n, tr, resolverev) + if f in need: + del need[f] + # manifest resolve determined we need to merge the tips + nmap[f] = self.merge3(fl, f, o, n, tr, resolverev) + + if need: + # we need to do trivial merges on local files + for f in new: + if f not in need: continue + fl = self.file(f) + nmap[f] = self.merge3(fl, f, need[f], fl.tip(), tr, resolverev) # For simple merges, we don't need to resolve manifests or changesets if simple: @@ -657,64 +717,11 @@ tr.close() return - # resolve the manifest to point to all the merged files - self.ui.status("resolving manifests\n") - ma = self.manifest.ancestor(mm, mo) - omap = self.manifest.read(mo) # other - amap = self.manifest.read(ma) # ancestor - mmap = self.manifest.read(mm) # mine - self.ui.debug("ancestor %s local %s remote %s\n" % - (short(ma), short(mm), short(mo))) - nmap = {} - - for f, mid in mmap.iteritems(): - if f in omap: - if mid != omap[f]: - self.ui.debug("%s versions differ\n" % f) - if f in new: self.ui.debug("%s updated in resolve\n" % f) - # use merged version or local version - nmap[f] = new.get(f, mid) - else: - nmap[f] = mid # keep ours - del omap[f] - elif f in amap: - if mid != amap[f]: - r = self.ui.prompt( - ("local changed %s which remote deleted\n" % f) + - "(k)eep or (d)elete?", "[kd]", "k") - if r == "k": nmap[f] = mid - else: - self.ui.debug("other deleted %s\n" % f) - pass # other deleted it - else: - self.ui.debug("local created %s\n" %f) - nmap[f] = mid # we created it - - del mmap - - for f, oid in omap.iteritems(): - if f in amap: - if oid != amap[f]: - r = self.ui.prompt( - ("remote changed %s which local deleted\n" % f) + - "(k)eep or (d)elete?", "[kd]", "k") - if r == "k": nmap[f] = oid - else: - pass # probably safe - else: - self.ui.debug("remote created %s\n" % f) - nmap[f] = new.get(f, oid) # remote created it - - del omap - del amap - node = self.manifest.add(nmap, tr, resolverev, mm, mo) # Now all files and manifests are merged, we add the changed files # and manifest id to the changelog self.ui.status("committing merge changeset\n") - new = new.keys() - new.sort() if co == cn: cn = -1 edittext = "\nHG: merge resolve\n" + \