4 #include "sha1-lookup.h"
7 int commit_patch_id(struct commit
*commit
, struct diff_options
*options
,
8 unsigned char *sha1
, int diff_header_only
)
11 diff_tree_sha1(commit
->parents
->item
->object
.oid
.hash
,
12 commit
->object
.oid
.hash
, "", options
);
14 diff_root_tree_sha1(commit
->object
.oid
.hash
, "", options
);
15 diffcore_std(options
);
16 return diff_flush_patch_id(options
, sha1
, diff_header_only
);
20 * When we cannot load the full patch-id for both commits for whatever
21 * reason, the function returns -1 (i.e. return error(...)). Despite
22 * the "cmp" in the name of this function, the caller only cares about
23 * the return value being zero (a and b are equivalent) or non-zero (a
24 * and b are different), and returning non-zero would keep both in the
25 * result, even if they actually were equivalent, in order to err on
26 * the side of safety. The actual value being negative does not have
27 * any significance; only that it is non-zero matters.
29 static int patch_id_cmp(struct patch_id
*a
,
31 struct diff_options
*opt
)
33 if (is_null_sha1(a
->patch_id
) &&
34 commit_patch_id(a
->commit
, opt
, a
->patch_id
, 0))
35 return error("Could not get patch ID for %s",
36 oid_to_hex(&a
->commit
->object
.oid
));
37 if (is_null_sha1(b
->patch_id
) &&
38 commit_patch_id(b
->commit
, opt
, b
->patch_id
, 0))
39 return error("Could not get patch ID for %s",
40 oid_to_hex(&b
->commit
->object
.oid
));
41 return hashcmp(a
->patch_id
, b
->patch_id
);
44 int init_patch_ids(struct patch_ids
*ids
)
46 memset(ids
, 0, sizeof(*ids
));
47 diff_setup(&ids
->diffopts
);
48 DIFF_OPT_SET(&ids
->diffopts
, RECURSIVE
);
49 diff_setup_done(&ids
->diffopts
);
50 hashmap_init(&ids
->patches
, (hashmap_cmp_fn
)patch_id_cmp
, 256);
54 int free_patch_ids(struct patch_ids
*ids
)
56 hashmap_free(&ids
->patches
, 1);
60 static int init_patch_id_entry(struct patch_id
*patch
,
61 struct commit
*commit
,
62 struct patch_ids
*ids
)
64 unsigned char header_only_patch_id
[GIT_SHA1_RAWSZ
];
66 patch
->commit
= commit
;
67 if (commit_patch_id(commit
, &ids
->diffopts
, header_only_patch_id
, 1))
70 hashmap_entry_init(patch
, sha1hash(header_only_patch_id
));
74 struct patch_id
*has_commit_patch_id(struct commit
*commit
,
75 struct patch_ids
*ids
)
77 struct patch_id patch
;
79 memset(&patch
, 0, sizeof(patch
));
80 if (init_patch_id_entry(&patch
, commit
, ids
))
83 return hashmap_get(&ids
->patches
, &patch
, &ids
->diffopts
);
86 struct patch_id
*add_commit_patch_id(struct commit
*commit
,
87 struct patch_ids
*ids
)
89 struct patch_id
*key
= xcalloc(1, sizeof(*key
));
91 if (init_patch_id_entry(key
, commit
, ids
)) {
96 hashmap_add(&ids
->patches
, key
);