3131 TemporaryFileSwap ,
3232 post_clear_cache ,
3333 default_index ,
34+ git_working_dir
3435 )
3536
3637import git .objects
@@ -122,7 +123,7 @@ def _set_cache_(self, attr):
122123 # END exception handling
123124
124125 stream = file_contents_ro (fd , stream = True , allow_mmap = True )
125-
126+
126127 try :
127128 self ._deserialize (stream )
128129 finally :
@@ -192,6 +193,10 @@ def write(self, file_path = None, ignore_tree_extension_data=False):
192193 automatically
193194
194195 :return: self"""
196+ # make sure we have our entries read before getting a write lock
197+ # else it would be done when streaming. This can happen
198+ # if one doesn't change the index, but writes it right away
199+ self .entries
195200 lfd = LockedFD (file_path or self ._file_path )
196201 stream = lfd .open (write = True , stream = True )
197202
@@ -345,7 +350,7 @@ def _stat_mode_to_index_mode(cls, mode):
345350 return S_IFLNK
346351 if S_ISDIR (mode ) or S_IFMT (mode ) == cls .S_IFGITLINK : # submodules
347352 return cls .S_IFGITLINK
348- return S_IFREG | 644 | (mode & 0100 ) # blobs with or without executable bit
353+ return S_IFREG | 0644 | (mode & 0100 ) # blobs with or without executable bit
349354
350355 # UTILITIES
351356 def _iter_expand_paths (self , paths ):
@@ -577,6 +582,7 @@ def _preprocess_add_items(self, items):
577582 # END for each item
578583 return (paths , entries )
579584
585+ @git_working_dir
580586 def add (self , items , force = True , fprogress = lambda * args : None , path_rewriter = None ):
581587 """Add files from the working tree, specific blobs or BaseIndexEntries
582588 to the index. The underlying index file will be written immediately, hence
@@ -688,7 +694,6 @@ def store_path(filepath):
688694 fprogress (filepath , False , filepath )
689695 istream = self .repo .odb .store (IStream (Blob .type , st .st_size , stream ))
690696 fprogress (filepath , True , filepath )
691-
692697 return BaseIndexEntry ((self ._stat_mode_to_index_mode (st .st_mode ),
693698 istream .binsha , 0 , filepath ))
694699 # END utility method
@@ -706,8 +711,6 @@ def store_path(filepath):
706711
707712 # HANDLE ENTRIES
708713 if entries :
709- # TODO: Add proper IndexEntries to ourselves, and write the index
710- # just once. Currently its done twice at least
711714 null_mode_entries = [ e for e in entries if e .mode == 0 ]
712715 if null_mode_entries :
713716 raise ValueError ("At least one Entry has a null-mode - please use index.remove to remove files for clarity" )
@@ -750,6 +753,7 @@ def store_path(filepath):
750753 # add the new entries to this instance, and write it
751754 for entry in entries_added :
752755 self .entries [(entry .path , 0 )] = IndexEntry .from_base (entry )
756+
753757 self .write ()
754758
755759 return entries_added
@@ -902,8 +906,8 @@ def commit(self, message, parent_commits=None, head=True):
902906 Returns
903907 Commit object representing the new commit
904908 """
905- tree_sha = self . repo . git .write_tree ()
906- return Commit .create_from_tree (self .repo , tree_sha , message , parent_commits , head )
909+ tree = self .write_tree ()
910+ return Commit .create_from_tree (self .repo , tree , message , parent_commits , head )
907911
908912 @classmethod
909913 def _flush_stdin_and_wait (cls , proc , ignore_stdout = False ):
@@ -1012,6 +1016,11 @@ def handle_stderr(proc, iter_checked_out_files):
10121016 if isinstance (paths , basestring ):
10131017 paths = [paths ]
10141018
1019+ # make sure we have our entries loaded before we start checkout_index
1020+ # which will hold a lock on it. We try to get the lock as well during
1021+ # our entries initialization
1022+ self .entries
1023+
10151024 args .append ("--stdin" )
10161025 kwargs ['as_process' ] = True
10171026 kwargs ['istream' ] = subprocess .PIPE
0 commit comments