3636)
3737from git .util import IndexFileSHA1Writer , finalize_process
3838
39- from .typ import BaseIndexEntry , IndexEntry , CE_NAMEMASK , CE_STAGESHIFT
39+ from .typ import CE_EXTENDED , BaseIndexEntry , IndexEntry , CE_NAMEMASK , CE_STAGESHIFT
4040from .util import pack , unpack
4141
4242# typing -----------------------------------------------------------------------------
@@ -158,7 +158,7 @@ def write_cache(
158158 write = stream_sha .write
159159
160160 # Header
161- version = 2
161+ version = 3 if any ( entry . extended_flags for entry in entries ) else 2
162162 write (b"DIRC" )
163163 write (pack (">LL" , version , len (entries )))
164164
@@ -172,6 +172,8 @@ def write_cache(
172172 plen = len (path ) & CE_NAMEMASK # Path length
173173 assert plen == len (path ), "Path %s too long to fit into index" % entry .path
174174 flags = plen | (entry .flags & CE_NAMEMASK_INV ) # Clear possible previous values.
175+ if entry .extended_flags :
176+ flags |= CE_EXTENDED
175177 write (
176178 pack (
177179 ">LLLLLL20sH" ,
@@ -185,6 +187,8 @@ def write_cache(
185187 flags ,
186188 )
187189 )
190+ if entry .extended_flags :
191+ write (pack (">H" , entry .extended_flags ))
188192 write (path )
189193 real_size = (tell () - beginoffset + 8 ) & ~ 7
190194 write (b"\0 " * ((beginoffset + real_size ) - tell ()))
@@ -206,8 +210,7 @@ def read_header(stream: IO[bytes]) -> Tuple[int, int]:
206210 unpacked = cast (Tuple [int , int ], unpack (">LL" , stream .read (4 * 2 )))
207211 version , num_entries = unpacked
208212
209- # TODO: Handle version 3: extended data, see read-cache.c.
210- assert version in (1 , 2 ), "Unsupported git index version %i, only 1 and 2 are supported" % version
213+ assert version in (1 , 2 , 3 ), "Unsupported git index version %i, only 1, 2, and 3 are supported" % version
211214 return version , num_entries
212215
213216
@@ -260,12 +263,15 @@ def read_cache(
260263 ctime = unpack (">8s" , read (8 ))[0 ]
261264 mtime = unpack (">8s" , read (8 ))[0 ]
262265 (dev , ino , mode , uid , gid , size , sha , flags ) = unpack (">LLLLLL20sH" , read (20 + 4 * 6 + 2 ))
266+ extended_flags = 0
267+ if flags & CE_EXTENDED :
268+ extended_flags = unpack (">H" , read (2 ))[0 ]
263269 path_size = flags & CE_NAMEMASK
264270 path = read (path_size ).decode (defenc )
265271
266272 real_size = (tell () - beginoffset + 8 ) & ~ 7
267273 read ((beginoffset + real_size ) - tell ())
268- entry = IndexEntry ((mode , sha , flags , path , ctime , mtime , dev , ino , uid , gid , size ))
274+ entry = IndexEntry ((mode , sha , flags , path , ctime , mtime , dev , ino , uid , gid , size , extended_flags ))
269275 # entry_key would be the method to use, but we save the effort.
270276 entries [(path , entry .stage )] = entry
271277 count += 1
0 commit comments