31
31
TemporaryFileSwap ,
32
32
post_clear_cache ,
33
33
default_index ,
34
+ git_working_dir
34
35
)
35
36
36
37
import git .objects
@@ -122,7 +123,7 @@ def _set_cache_(self, attr):
122
123
# END exception handling
123
124
124
125
stream = file_contents_ro (fd , stream = True , allow_mmap = True )
125
-
126
+
126
127
try :
127
128
self ._deserialize (stream )
128
129
finally :
@@ -192,6 +193,10 @@ def write(self, file_path = None, ignore_tree_extension_data=False):
192
193
automatically
193
194
194
195
: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
195
200
lfd = LockedFD (file_path or self ._file_path )
196
201
stream = lfd .open (write = True , stream = True )
197
202
@@ -345,7 +350,7 @@ def _stat_mode_to_index_mode(cls, mode):
345
350
return S_IFLNK
346
351
if S_ISDIR (mode ) or S_IFMT (mode ) == cls .S_IFGITLINK : # submodules
347
352
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
349
354
350
355
# UTILITIES
351
356
def _iter_expand_paths (self , paths ):
@@ -577,6 +582,7 @@ def _preprocess_add_items(self, items):
577
582
# END for each item
578
583
return (paths , entries )
579
584
585
+ @git_working_dir
580
586
def add (self , items , force = True , fprogress = lambda * args : None , path_rewriter = None ):
581
587
"""Add files from the working tree, specific blobs or BaseIndexEntries
582
588
to the index. The underlying index file will be written immediately, hence
@@ -688,7 +694,6 @@ def store_path(filepath):
688
694
fprogress (filepath , False , filepath )
689
695
istream = self .repo .odb .store (IStream (Blob .type , st .st_size , stream ))
690
696
fprogress (filepath , True , filepath )
691
-
692
697
return BaseIndexEntry ((self ._stat_mode_to_index_mode (st .st_mode ),
693
698
istream .binsha , 0 , filepath ))
694
699
# END utility method
@@ -706,8 +711,6 @@ def store_path(filepath):
706
711
707
712
# HANDLE ENTRIES
708
713
if entries :
709
- # TODO: Add proper IndexEntries to ourselves, and write the index
710
- # just once. Currently its done twice at least
711
714
null_mode_entries = [ e for e in entries if e .mode == 0 ]
712
715
if null_mode_entries :
713
716
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):
750
753
# add the new entries to this instance, and write it
751
754
for entry in entries_added :
752
755
self .entries [(entry .path , 0 )] = IndexEntry .from_base (entry )
756
+
753
757
self .write ()
754
758
755
759
return entries_added
@@ -902,8 +906,8 @@ def commit(self, message, parent_commits=None, head=True):
902
906
Returns
903
907
Commit object representing the new commit
904
908
"""
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 )
907
911
908
912
@classmethod
909
913
def _flush_stdin_and_wait (cls , proc , ignore_stdout = False ):
@@ -1012,6 +1016,11 @@ def handle_stderr(proc, iter_checked_out_files):
1012
1016
if isinstance (paths , basestring ):
1013
1017
paths = [paths ]
1014
1018
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
+
1015
1024
args .append ("--stdin" )
1016
1025
kwargs ['as_process' ] = True
1017
1026
kwargs ['istream' ] = subprocess .PIPE
0 commit comments