- theirs_newline_cache = {}
- def get_theirs_newline(file):
- if file not in theirs_newline_cache:
- nl = git_newline_style(theirs_id, file)
- if not isinstance(nl, str):
- if nl is not None:
- # A case of incompetent upstream, unfortunately
- logging.warning("Canonical version (theirs) of %s has mixed newline style, forced to \\n", file)
- else:
- logging.debug("Canonical version (theirs) of %s had no newline style, using \\n", file)
- nl = "\n"
- theirs_newline_cache[file] = nl
- return theirs_newline_cache[file]
+ ours_theirs_diff = git_diff_text(ours_id, theirs_id)
+
+ # What files can the merge fail on? Only if ours is different from
+ # theirs (we don't care about common for this calculation). Of
+ # course, this will be conservative, because we need to apply
+ # prepare_config to ours. Can we miss a file? Not unless
+ # prepare_config introduces a merge conflict, as opposed to
+ # eliminates them; and it is equally likely to do so on common_id as
+ # well. We can deal, since we offer the user the ability to resolve
+ # merges manually.
+ theirs_newlines = {}
+ shell.call("git", "reset", "--hard", theirs_id)
+ for file in ours_theirs_diff:
+ # XXX Should be able to skip stats if file was removed
+ # for the ours tree
+ try:
+ nl = get_newline(file)
+ except IOError:
+ # File not present in theirs, don't bother
+ continue
+ if not isinstance(nl, str):
+ if nl is not None:
+ # A case of incompetent upstream, unfortunately
+ logging.warning("Canonical version (theirs) of %s has mixed newline style, forced to \\n", file)
+ else:
+ logging.debug("Canonical version (theirs) of %s had no newline style, using \\n", file)
+ nl = "\n"
+ theirs_newlines[file] = nl
+