Skip to content

Commit 7ab02c6

Browse files
committed
index: write blobs via git hash-object, not gitdb's odb.store
1 parent 9729ed3 commit 7ab02c6

1 file changed

Lines changed: 17 additions & 14 deletions

File tree

git/index/base.py

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,13 @@
1111
import contextlib
1212
import datetime
1313
import glob
14-
from io import BytesIO
1514
import os
1615
import os.path as osp
1716
from stat import S_ISLNK
1817
import subprocess
1918
import sys
2019
import tempfile
2120

22-
from gitdb.base import IStream
2321
from gitdb.db import MemoryDB
2422

2523
from git.compat import defenc, force_bytes
@@ -34,6 +32,7 @@
3432
LockedFD,
3533
join_path_native,
3634
file_contents_ro,
35+
hex_to_bin,
3736
_is_path_rooted,
3837
_to_relative_path,
3938
to_native_path_linux,
@@ -58,7 +57,6 @@
5857

5958
from typing import (
6059
Any,
61-
BinaryIO,
6260
Callable,
6361
cast,
6462
Dict,
@@ -726,24 +724,29 @@ def _store_path(self, filepath: PathLike, fprogress: Callable) -> BaseIndexEntry
726724
"""
727725
st = os.lstat(filepath) # Handles non-symlinks as well.
728726

727+
fprogress(filepath, False, filepath)
729728
if S_ISLNK(st.st_mode):
730729
# In PY3, readlink is a string, but we need bytes.
731730
# In PY2, it was just OS encoded bytes, we assumed UTF-8.
732-
def open_stream() -> BinaryIO:
733-
return BytesIO(force_bytes(os.readlink(filepath), encoding=defenc))
731+
#
732+
# `git hash-object <path>` follows symlinks and would hash the target
733+
# file's content, not the link itself. Hash the target string from a
734+
# temp file instead, with filters off since it isn't real file content.
735+
target = force_bytes(os.readlink(filepath), encoding=defenc)
736+
fd, tmp_path = tempfile.mkstemp()
737+
try:
738+
os.write(fd, target)
739+
os.close(fd)
740+
hexsha = self.repo.git.hash_object(tmp_path, w=True, no_filters=True)
741+
finally:
742+
os.remove(tmp_path)
734743
else:
735-
736-
def open_stream() -> BinaryIO:
737-
return open(filepath, "rb")
738-
739-
with open_stream() as stream:
740-
fprogress(filepath, False, filepath)
741-
istream = self.repo.odb.store(IStream(Blob.type, st.st_size, stream))
742-
fprogress(filepath, True, filepath)
744+
hexsha = self.repo.git.hash_object(filepath, w=True)
745+
fprogress(filepath, True, filepath)
743746
return BaseIndexEntry(
744747
(
745748
stat_mode_to_index_mode(st.st_mode),
746-
istream.binsha,
749+
hex_to_bin(hexsha),
747750
0,
748751
to_native_path_linux(filepath),
749752
)

0 commit comments

Comments
 (0)