@@ -41,7 +41,57 @@ def __del__(self):
4141 # END temp file exists
4242
4343
44- class IndexEntry (tuple ):
44+ class BaseIndexEntry (tuple ):
45+ """
46+ Small Brother of an index entry which can be created to describe changes
47+ done to the index in which case plenty of additional information is not requried.
48+
49+ As the first 4 data members match exactly to the IndexEntry type, methods
50+ expecting a BaseIndexEntry can also handle full IndexEntries even if they
51+ use numeric indices for performance reasons.
52+ """
53+
54+ @property
55+ def mode (self ):
56+ """
57+ File Mode, compatible to stat module constants
58+ """
59+ return self [0 ]
60+
61+ @property
62+ def sha (self ):
63+ """
64+ hex sha of the blob
65+ """
66+ return self [1 ]
67+
68+ @property
69+ def stage (self ):
70+ """
71+ Stage of the entry, either:
72+ 0 = default stage
73+ 1 = stage before a merge or common ancestor entry in case of a 3 way merge
74+ 2 = stage of entries from the 'left' side of the merge
75+ 3 = stage of entries from the right side of the merge
76+ Note:
77+ For more information, see http://www.kernel.org/pub/software/scm/git/docs/git-read-tree.html
78+ """
79+ return self [2 ]
80+
81+ @property
82+ def path (self ):
83+ return self [3 ]
84+
85+ @classmethod
86+ def from_blob (cls , blob , stage = 0 ):
87+ """
88+ Returns
89+ Fully equipped BaseIndexEntry at the given stage
90+ """
91+ return cls ((blob .mode , blob .id , stage , blob .path ))
92+
93+
94+ class IndexEntry (BaseIndexEntry ):
4595 """
4696 Allows convenient access to IndexEntry data without completely unpacking it.
4797
@@ -57,49 +107,42 @@ def ctime(self):
57107 Tuple(int_time_seconds_since_epoch, int_nano_seconds) of the
58108 file's creation time
59109 """
60- return struct .unpack (">LL" , self [0 ])
110+ return struct .unpack (">LL" , self [4 ])
61111
62112 @property
63113 def mtime (self ):
64114 """
65115 See ctime property, but returns modification time
66116 """
67- return struct .unpack (">LL" , self [1 ])
117+ return struct .unpack (">LL" , self [5 ])
68118
69119 @property
70120 def dev (self ):
71121 """
72122 Device ID
73123 """
74- return self [2 ]
124+ return self [6 ]
75125
76126 @property
77127 def inode (self ):
78128 """
79129 Inode ID
80130 """
81- return self [3 ]
82-
83- @property
84- def mode (self ):
85- """
86- File Mode, compatible to stat module constants
87- """
88- return self [4 ]
89-
131+ return self [7 ]
132+
90133 @property
91134 def uid (self ):
92135 """
93136 User ID
94137 """
95- return self [5 ]
138+ return self [8 ]
96139
97140 @property
98141 def gid (self ):
99142 """
100143 Group ID
101144 """
102- return self [6 ]
145+ return self [9 ]
103146
104147 @property
105148 def size (self ):
@@ -109,41 +152,16 @@ def size(self):
109152 Note
110153 Will be 0 if the stage is not 0 ( hence it is an unmerged entry )
111154 """
112- return self [7 ]
113-
114- @property
115- def sha (self ):
116- """
117- hex sha of the blob
118- """
119- return self [8 ]
120-
121- @property
122- def stage (self ):
123- """
124- Stage of the entry, either:
125- 0 = default stage
126- 1 = stage before a merge or common ancestor entry in case of a 3 way merge
127- 2 = stage of entries from the 'left' side of the merge
128- 3 = stage of entries from the right side of the merge
129- Note:
130- For more information, see http://www.kernel.org/pub/software/scm/git/docs/git-read-tree.html
131- """
132- return self [9 ]
133-
134- @property
135- def path (self ):
136155 return self [10 ]
137156
138-
139157 @classmethod
140158 def from_blob (cls , blob ):
141159 """
142160 Returns
143161 Minimal entry resembling the given blob objecft
144162 """
145163 time = struct .pack (">LL" , 0 , 0 )
146- return IndexEntry ((time , time , 0 , 0 , blob .mode , 0 , 0 , blob . size , blob . id , 0 , blob .path ))
164+ return IndexEntry ((blob . mode , blob . id , 0 , blob .path , time , time , 0 , 0 , 0 , 0 , blob .size ))
147165
148166
149167def default_index (func ):
@@ -243,8 +261,7 @@ def _read_entry(cls, stream):
243261
244262 real_size = ((stream .tell () - beginoffset + 8 ) & ~ 7 )
245263 data = stream .read ((beginoffset + real_size ) - stream .tell ())
246- return IndexEntry ((ctime , mtime , dev , ino , mode , uid , gid , size ,
247- binascii .hexlify (sha ), flags >> 12 , path ))
264+ return IndexEntry ((mode , binascii .hexlify (sha ), flags >> 12 , path , ctime , mtime , dev , ino , uid , gid , size ))
248265
249266 @classmethod
250267 def _read_header (cls , stream ):
@@ -286,14 +303,14 @@ def _write_cache_entry(cls, stream, entry):
286303 Write an IndexEntry to a stream
287304 """
288305 beginoffset = stream .tell ()
289- stream .write (entry [0 ]) # ctime
290- stream .write (entry [1 ]) # mtime
291- path = entry [10 ]
306+ stream .write (entry [4 ]) # ctime
307+ stream .write (entry [5 ]) # mtime
308+ path = entry [3 ]
292309 plen = len (path ) & 0x0fff # path length
293- assert plen == len (path ), "Path %s too long to fit into index" % entry [10 ]
294- flags = plen | (entry [9 ] << 12 )# stage and path length are 2 byte flags
295- stream .write (struct .pack (">LLLLLL20sH" , entry [2 ], entry [3 ], entry [4 ],
296- entry [5 ], entry [6 ], entry [7 ], binascii .unhexlify (entry [8 ]), flags ))
310+ assert plen == len (path ), "Path %s too long to fit into index" % entry [3 ]
311+ flags = plen | (entry [2 ] << 12 )# stage and path length are 2 byte flags
312+ stream .write (struct .pack (">LLLLLL20sH" , entry [6 ], entry [7 ], entry [0 ],
313+ entry [8 ], entry [9 ], entry [10 ], binascii .unhexlify (entry [1 ]), flags ))
297314 stream .write (path )
298315 real_size = ((stream .tell () - beginoffset + 8 ) & ~ 7 )
299316 stream .write ("\0 " * ((beginoffset + real_size ) - stream .tell ()))
@@ -325,7 +342,7 @@ def write(self, file_path = None):
325342
326343 # body
327344 entries_sorted = self .entries .values ()
328- entries_sorted .sort (key = lambda e : (e [10 ], e [9 ])) # use path/stage as sort key
345+ entries_sorted .sort (key = lambda e : (e [3 ], e [2 ])) # use path/stage as sort key
329346 for entry in entries_sorted :
330347 self ._write_cache_entry (stream , entry )
331348 # END for each entry
@@ -623,7 +640,7 @@ def reset(self, commit='HEAD', working_tree=False, **kwargs):
623640 ``**kwargs``
624641 Additional keyword arguments passed to git-reset
625642 """
626- raise NotImplementedError ("todo" )
643+ raise NotImplementedError ("todo: use git-read-tree if there is no working tree to update " )
627644
628645 @default_index
629646 def diff (self , other = diff .Diffable .Index , paths = None , create_patch = False , ** kwargs ):
0 commit comments