No, the patch-id doesn't just care about the diff, it cares about the context before the diff too.
See this patch:
$ git diff-tree --src-prefix=x/ --dst-prefix=y/ -p HEAD~..
diff --git x/refs/files-backend.c y/refs/files-backend.c
index 9183875dad..dd8abe9185 100644
--- x/refs/files-backend.c
+++ y/refs/files-backend.c
@@ -180,7 +180,8 @@ static void files_reflog_path(struct files_ref_store *refs,
break;
case REF_TYPE_OTHER_PSEUDOREF:
case REF_TYPE_MAIN_PSEUDOREF:
- return files_reflog_path_other_worktrees(refs, sb, refname);
+ files_reflog_path_other_worktrees(refs, sb, refname);
+ break;
case REF_TYPE_NORMAL:
strbuf_addf(sb, "%s/logs/%s", refs->gitcommondir, refname);
break;Observe that the diff --git line matters, we hash it:
$ git diff-tree -p HEAD~.. | git patch-id
5870d115b7e2a9a936ab8fdc254932234413c710 0000000000000000000000000000000000000000
$ git diff-tree --src-prefix=a/ --dst-prefix=b/ -p HEAD~.. | git patch-id --stable
5870d115b7e2a9a936ab8fdc254932234413c710 0000000000000000000000000000000000000000
$ git diff-tree --src-prefix=x/ --dst-prefix=y/ -p HEAD~.. | git patch-id --stable
4cd136f2b98760150f700ac6a5b126389d6d05a7 0000000000000000000000000000000000000000The thing it doesn't care about is the "index" between the "diff" and patch:
$ git diff-tree --src-prefix=x/ --dst-prefix=y/ -p HEAD~.. | grep -v ^index | git patch-id --stable
4cd136f2b98760150f700ac6a5b126389d6d05a7 0000000000000000000000000000000000000000We also care about the +++ and --- lines:
$ git diff-tree --src-prefix=x/ --dst-prefix=y/ -p HEAD~.. | grep -v ^index | perl -pe 's/^(\+\+\+|---).*/$1/g' | git patch-id
56985c2c38cce6079de2690082e1770a8e81214c 0000000000000000000000000000000000000000Then we normalize the @@ line, e.g.:
$ git diff-tree --src-prefix=x/ --dst-prefix=y/ -p HEAD~.. | grep -v ^index | git patch-id
4cd136f2b98760150f700ac6a5b126389d6d05a7 0000000000000000000000000000000000000000
$ git diff-tree --src-prefix=x/ --dst-prefix=y/ -p HEAD~.. | grep -v ^index | perl -pe 's/\d+/123/g' | git patch-id
4cd136f2b98760150f700ac6a5b126389d6d05a7 0000000000000000000000000000000000000000There's other caveats (see the code, e.g. "strip space") but to a first
approximation a patch id is a hash of something that looks like this:
diff --git x/refs/files-backend.c y/refs/files-backend.c
--- x/refs/files-backend.c
+++ y/refs/files-backend.c
@@ -123,123 +123,123 @@ static void files_reflog_path(struct files_ref_store *refs,
break;
case REF_TYPE_OTHER_PSEUDOREF:
case REF_TYPE_MAIN_PSEUDOREF:
- return files_reflog_path_other_worktrees(refs, sb, refname);
+ files_reflog_path_other_worktrees(refs, sb, refname);
+ break;
case REF_TYPE_NORMAL:
strbuf_addf(sb, "%s/logs/%s", refs->gitcommondir, refname);
break;Which means that accepting a patch like this as input would actually give you a different patch-id than if it had the proper header.
So it seems most sensible to me if this is going to be supported that we go a bit beyond the call of duty and fake up the start of it, namely:
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.cTo be:
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.cIt'll make the state machine a bit more complex, but IMO it would suck more if we generate a different hash depending on the tool generating the diff. OTOH the "diff --git" line was never there, and it *does* matter, so should we be faking it up? Maybe not, bah!