object-file: update object_info_extended to reencode objects
oid_object_info_extended is updated to detect an oid encoding that does not match the current repository, use repo_oid_to_algop to find the correspoding oid in the current repository and to return the data for the oid. Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Eric W. Biederman committed
Oct 1, 2023 at 21:40 UTC
2328ebaa4ef7a921c7021db9e83e122dbe2ac7ad
1 file changed
+91
object-file.c
+91
@@ -1662,10 +1662,101 @@ static int do_oid_object_info_extended(struct repository *r,
1662
return 0;
1663
}
1664
1665
+static int oid_object_info_convert(struct repository *r,
1666
+ const struct object_id *input_oid,
1667
+ struct object_info *input_oi, unsigned flags)
1668
+{
1669
+ const struct git_hash_algo *input_algo = &hash_algos[input_oid->algo];
1670
+ int do_die = flags & OBJECT_INFO_DIE_IF_CORRUPT;
1671
+ struct strbuf type_name = STRBUF_INIT;
1672
+ struct object_id oid, delta_base_oid;
1673
+ struct object_info new_oi, *oi;
1674
+ unsigned long size;
1675
+ void *content;
1676
+ int ret;
1677
+
1678
+ if (repo_oid_to_algop(r, input_oid, the_hash_algo, &oid)) {
1679
+ if (do_die)
1680
+ die(_("missing mapping of %s to %s"),
1681
+ oid_to_hex(input_oid), the_hash_algo->name);
1682
+ return -1;
1683
+ }
1684
+
1685
+ /* Is new_oi needed? */
1686
+ oi = input_oi;
1687
+ if (input_oi && (input_oi->delta_base_oid || input_oi->sizep ||
1688
+ input_oi->contentp)) {
1689
+ new_oi = *input_oi;
1690
+ /* Does delta_base_oid need to be converted? */
1691
+ if (input_oi->delta_base_oid)
1692
+ new_oi.delta_base_oid = &delta_base_oid;
1693
+ /* Will the attributes differ when converted? */
1694
+ if (input_oi->sizep || input_oi->contentp) {
1695
+ new_oi.contentp = &content;
1696
+ new_oi.sizep = &size;
1697
+ new_oi.type_name = &type_name;
1698
+ }
1699
+ oi = &new_oi;
1700
+ }
1701
+
1702
+ ret = oid_object_info_extended(r, &oid, oi, flags);
1703
+ if (ret)
1704
+ return -1;
1705
+ if (oi == input_oi)
1706
+ return ret;
1707
+
1708
+ if (new_oi.contentp) {
1709
+ struct strbuf outbuf = STRBUF_INIT;
1710
+ enum object_type type;
1711
+
1712
+ type = type_from_string_gently(type_name.buf, type_name.len,
1713
+ !do_die);
1714
+ if (type == -1)
1715
+ return -1;
1716
+ if (type != OBJ_BLOB) {
1717
+ ret = convert_object_file(&outbuf,
1718
+ the_hash_algo, input_algo,
1719
+ content, size, type, !do_die);
1720
+ if (ret == -1)
1721
+ return -1;
1722
+ free(content);
1723
+ size = outbuf.len;
1724
+ content = strbuf_detach(&outbuf, NULL);
1725
+ }
1726
+ if (input_oi->sizep)
1727
+ *input_oi->sizep = size;
1728
+ if (input_oi->contentp)
1729
+ *input_oi->contentp = content;
1730
+ else
1731
+ free(content);
1732
+ if (input_oi->type_name)
1733
+ *input_oi->type_name = type_name;
1734
+ else
1735
+ strbuf_release(&type_name);
1736
+ }
1737
+ if (new_oi.delta_base_oid == &delta_base_oid) {
1738
+ if (repo_oid_to_algop(r, &delta_base_oid, input_algo,
1739
+ input_oi->delta_base_oid)) {
1740
+ if (do_die)
1741
+ die(_("missing mapping of %s to %s"),
1742
+ oid_to_hex(&delta_base_oid),
1743
+ input_algo->name);
1744
+ return -1;
1745
+ }
1746
+ }
1747
+ input_oi->whence = new_oi.whence;
1748
+ input_oi->u = new_oi.u;
1749
+ return ret;
1750
+}
1751
+
1752
int oid_object_info_extended(struct repository *r, const struct object_id *oid,
1753
struct object_info *oi, unsigned flags)
1754
{
1755
int ret;
1756
+
1757
+ if (oid->algo && (hash_algo_by_ptr(r->hash_algo) != oid->algo))
1758
+ return oid_object_info_convert(r, oid, oi, flags);
1759
+
1760
obj_read_lock();
1761
ret = do_oid_object_info_extended(r, oid, oi, flags);
1762
obj_read_unlock();