'\" t
.\" Title: git-patch-id
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot
.\" Date: 2026-06-29
.\" Manual: Git Manual
.\" Source: Git 2.55.0
.\" Language: English
.\"
.TH "GIT\-PATCH\-ID" "1" "2026\-06\-29" "Git 2\&.55\&.0" "Git Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.\" http://bugs.debian.org/507673
.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
.\" disable hyphenation
.nh
.\" disable justification (adjust text to left margin only)
.ad l
.\" -----------------------------------------------------------------
.\" * MAIN CONTENT STARTS HERE *
.\" -----------------------------------------------------------------
.SH "NAME"
git-patch-id \- Compute unique IDs for patches
.SH "SYNOPSIS"
.sp
.nf
\fBgit\fR \fBpatch\-id\fR [\fB\-\-stable\fR | \fB\-\-unstable\fR | \fB\-\-verbatim\fR]
.fi
.sp
.SH "DESCRIPTION"
.sp
Read patches from standard input and compute the patch IDs\&.
.sp
A "patch ID" is nothing but a sum of SHA\-1 of the file diffs associated with a patch, with line numbers ignored\&. As such, it\(cqs "reasonably stable", but at the same time also reasonably unique, i\&.e\&., two patches that have the same "patch ID" are almost guaranteed to be the same thing\&.
.sp
The main usecase for this command is to look for likely duplicate commits\&.
.sp
When dealing with \fBgit\fR \fBdiff\-tree\fR \fB\-\-patch\fR output, it takes advantage of the fact that the patch is prefixed with the object name of the commit, and outputs two 40\-byte hexadecimal strings\&. The first string is the patch ID, and the second string is the commit ID\&. This can be used to make a mapping from patch ID to commit ID for a set or range of commits\&.
.SH "OPTIONS"
.PP
\fB\-\-verbatim\fR
.RS 4
Calculate the patch ID of the input as it is given, do not strip any whitespace\&. Implies
\fB\-\-stable\fR
and forbids
\fB\-\-unstable\fR\&.
.sp
This is the default if
\fBpatchid\&.verbatim\fR
is
\fBtrue\fR\&.
.RE
.PP
\fB\-\-stable\fR
.RS 4
Use a "stable" sum of hashes as the patch ID\&. With this option:
.sp
.RS 4
.ie n \{\
\h'-04'\(bu\h'+03'\c
.\}
.el \{\
.sp -1
.IP \(bu 2.3
.\}
Reordering file diffs that make up a patch does not affect the ID\&. In particular, two patches produced by comparing the same two trees with two different settings for
\fB\-O\fR\fI\fR
result in the same patch ID signature, thereby allowing the computed result to be used as a key to index some meta\-information about the change between the two trees\&.
.RE
.sp
.RS 4
.ie n \{\
\h'-04'\(bu\h'+03'\c
.\}
.el \{\
.sp -1
.IP \(bu 2.3
.\}
The result is different from the value produced by Git 1\&.9 and older or produced when an "unstable" hash (see
\fB\-\-unstable\fR
below) is configured \- even when used on a diff output taken without any use of
\fB\-O\fR\fI\fR, thereby making existing databases storing such "unstable" or historical patch IDs unusable\&.
.RE
.sp
.RS 4
.ie n \{\
\h'-04'\(bu\h'+03'\c
.\}
.el \{\
.sp -1
.IP \(bu 2.3
.\}
All whitespace within the patch is ignored and does not affect the ID\&.
.RE
.sp
This is the default if
\fBpatchid\&.stable\fR
is set to
\fBtrue\fR\&.
.RE
.PP
\fB\-\-unstable\fR
.RS 4
Use an "unstable" hash as the patch ID\&. With this option, the result produced is compatible with the patch ID value produced by Git 1\&.9 and older and whitespace is ignored\&. Users with pre\-existing databases storing patch IDs produced by Git 1\&.9 and older (who do not deal with reordered patches) may want to use this option\&.
.sp
This is the default\&.
.RE
.SH "EXAMPLES"
.sp
\fBgit-cherry\fR(1) shows what commits from a branch have patch ID equivalent commits in some upstream branch\&. But it only tells you whether such a commit exists or not\&. What if you wanted to know the relevant commits in the upstream? We can use this command to make a mapping between your branch and the upstream branch:
.sp
.if n \{\
.RS 4
.\}
.nf
#!/bin/sh
upstream="$1"
branch="$2"
test \-z "$branch" && branch=HEAD
limit="$3"
if test \-n "$limit"
then
tail_opts="$limit"\&.\&."$upstream"
else
since=$(git log \-\-format=%aI "$upstream"\&.\&."$branch" | tail \-1)
tail_opts=\-\-since="$since"\*(Aq \*(Aq"$upstream"
fi
for_branch=$(mktemp)
for_upstream=$(mktemp)
git rev\-list \-\-no\-merges "$upstream"\&.\&."$branch" |
git diff\-tree \-\-patch \-\-stdin |
git patch\-id \-\-stable | sort >"$for_branch"
git rev\-list \-\-no\-merges $tail_opts |
git diff\-tree \-\-patch \-\-stdin |
git patch\-id \-\-stable | sort >"$for_upstream"
join \-a1 "$for_branch" "$for_upstream" | cut \-d\*(Aq \*(Aq \-f2,3
rm "$for_branch"
rm "$for_upstream"
.fi
.if n \{\
.RE
.\}
.sp
.sp
Now the first column shows the commit from your branch and the second column shows the patch ID equivalent commit, if it exists\&.
.SH "SEE ALSO"
.sp
\fBgit-cherry\fR(1)
.SH "GIT"
.sp
Part of the \fBgit\fR(1) suite