patching: rewrite: fully stabilize patch index stanzas as well as From lines

- `git format-patch --zero-commit` doesn't affect `index xxx...yyy` lines, only `From: `
  - so use the _classy_ "use a regex with a callback" solution as git format-patch doesn't offer one
- this will make _all_ patches change when rewritten, but hopefully _for the last time_ !
- we need to preserve `index 000000000000..xxx` as zeros, which indicate new file creation, thus:
  - new file creations are rewritten as `index 000000000000..111111111111`
  - non-creations are rewritten as `index 111111111111..222222222222`
- this is the final version of #6455
This commit is contained in:
Ricardo Pardini
2024-04-01 13:24:16 +02:00
parent d7068fabc9
commit 282fb964e5

View File

@@ -28,6 +28,19 @@ MAGIC_MBOX_MARKER_B4 = "git@z Thu Jan 1 00:00:00 1970"
REGEX_PATCH_FILENAMES = r"^patching file \"(.+)\""
log: logging.Logger = logging.getLogger("patching_utils")
# Magic strings and regex for rewriting patches' "index xxx....yyyy" lines
index_zero = f"{'0' * 12}"
index_from_zero = f"index {'0' * 12}..{'1' * 12}"
index_not_zero = f"index {'1' * 12}..{'2' * 12}"
index_rewrite_regexp: re.Pattern = re.compile(r"index ([0-9a-f]{12})\.\.([0-9a-f]{12})")
# Callback used for rewriting index lines.
def rewrite_indexes_callback(x: re.Match): # Preserve zero from's for new file creations.
if x.group(1) == index_zero:
return index_from_zero
return index_not_zero
class PatchRootDir:
def __init__(self, abs_dir, root_type, patch_type, root_dir):
@@ -808,7 +821,7 @@ def export_commit_as_patch(repo: git.Repo, commit: str):
'--zero-commit', # do not use the git revision, instead 000000...0000
'--stat=120', # 'wider' stat output; default is 80
'--stat-graph-width=10', # shorten the diffgraph graph part, it's too long
'--abbrev=12', # force index length to 12
'--abbrev=12', # force index length to 12 - essential for the regex below to work
"-1", "--stdout", commit
],
cwd=repo.working_tree_dir,
@@ -823,7 +836,17 @@ def export_commit_as_patch(repo: git.Repo, commit: str):
raise Exception(f"Failed to export commit {commit} to patch: {stderr_output}")
if stdout_output == "":
raise Exception(f"Failed to export commit {commit} to patch: no output")
return stdout_output
# Now, massage the output. We don't want the "index 08c33ec7e9f1..528741fcc0ec 100644" lines changing every time.
# We do need to preserve "0000000000.." ones as that indicates new file creation.
# Use a regular expression and a callback to decide. Check the top of this file for the regex and callback.
rewritten_indexes = re.sub(index_rewrite_regexp, rewrite_indexes_callback, stdout_output)
# If rewritten is same as original this didn't work, surely.
if rewritten_indexes == stdout_output:
raise Exception(f"Failed to rewrite indexes in patch output: {stdout_output}")
return rewritten_indexes
# Hack