@@ -29,13 +29,18 @@ class CheckoutError( Exception ):
29
29
changes.
30
30
31
31
The .failed_files attribute contains a list of relative paths that failed
32
- to be checked out as they contained changes that did not exist in the index"""
33
- def __init__ (self , message , failed_files ):
34
- super (CheckoutError , self ).__init__ (message )
32
+ to be checked out as they contained changes that did not exist in the index.
33
+
34
+ The .valid_files attribute contains a list of relative paths to files that
35
+ were checked out successfully and hence match the version stored in the
36
+ index"""
37
+ def __init__ (self , message , failed_files , valid_files ):
38
+ Exception .__init__ (self , message )
35
39
self .failed_files = failed_files
40
+ self .valid_files = valid_files
36
41
37
42
def __str__ (self ):
38
- return super ( CheckoutError , self ) .__str__ () + ":%s" % self .failed_files
43
+ return Exception .__str__ (self ) + ":%s" % self .failed_files
39
44
40
45
41
46
class _TemporaryFileSwap (object ):
@@ -1009,29 +1014,34 @@ def _flush_stdin_and_wait(cls, proc):
1009
1014
@default_index
1010
1015
def checkout (self , paths = None , force = False , fprogress = lambda * args : None , ** kwargs ):
1011
1016
"""
1012
- Checkout the given paths or all files from the version in the index.
1017
+ Checkout the given paths or all files from the version known to the index into
1018
+ the working tree.
1013
1019
1014
1020
``paths``
1015
1021
If None, all paths in the index will be checked out. Otherwise an iterable
1016
- of relative or absolute paths or a single path pointing to files in the index
1017
- is expected.
1018
- The command will raise of files do not exist in the index ( as opposed to the
1019
- original git command who ignores them )
1020
- The provided progress information will contain None as path and item if no
1021
- explicit paths are given.
1022
+ of relative or absolute paths or a single path pointing to files or directories
1023
+ in the index is expected.
1024
+ The command will raise of files or directories do not exist in the index
1025
+ ( as opposed to the original git command who ignores them ). Additionally
1026
+ this command allows to checkout directories which is an extension to git-update-index.
1027
+
1022
1028
1023
1029
``force``
1024
1030
If True, existing files will be overwritten even if they contain local modifications.
1025
1031
If False, these will trigger a CheckoutError.
1026
1032
1027
1033
``fprogress``
1028
- see Index.add_ for signature and explanation
1034
+ see Index.add_ for signature and explanation.
1035
+ The provided progress information will contain None as path and item if no
1036
+ explicit paths are given. Otherwise progress information will be send
1037
+ prior and after a file has been checked out
1029
1038
1030
1039
``**kwargs``
1031
1040
Additional arguments to be pasesd to git-checkout-index
1032
1041
1033
1042
Returns
1034
- self
1043
+ iterable yielding paths to files which have been checked out and are
1044
+ guaranteed to match the version stored in the index
1035
1045
1036
1046
Raise CheckoutError
1037
1047
If at least one file failed to be checked out. This is a summary,
@@ -1043,7 +1053,7 @@ def checkout(self, paths=None, force=False, fprogress=lambda *args: None, **kwar
1043
1053
if force :
1044
1054
args .append ("--force" )
1045
1055
1046
- def handle_stderr (proc ):
1056
+ def handle_stderr (proc , iter_checked_out_files ):
1047
1057
stderr = proc .stderr .read ()
1048
1058
if not stderr :
1049
1059
return
@@ -1075,32 +1085,63 @@ def handle_stderr(proc):
1075
1085
if unknown_lines :
1076
1086
raise GitCommandError (("git-checkout-index" , ), 128 , stderr )
1077
1087
if failed_files :
1078
- raise CheckoutError ("Some files could not be checked out from the index due to local modifications" , failed_files )
1088
+ valid_files = list (set (iter_checked_out_files ) - set (failed_files ))
1089
+ raise CheckoutError ("Some files could not be checked out from the index due to local modifications" , failed_files , valid_files )
1079
1090
# END stderr handler
1080
1091
1092
+
1081
1093
if paths is None :
1082
1094
args .append ("--all" )
1083
1095
kwargs ['as_process' ] = 1
1084
1096
fprogress (None , False , None )
1085
1097
proc = self .repo .git .checkout_index (* args , ** kwargs )
1086
1098
proc .wait ()
1087
1099
fprogress (None , True , None )
1088
- handle_stderr (proc )
1100
+ rval_iter = ( e .path for e in self .entries .itervalues () )
1101
+ handle_stderr (proc , rval_iter )
1102
+ return rval_iter
1089
1103
else :
1090
1104
if isinstance (paths , basestring ):
1091
1105
paths = [paths ]
1092
1106
1093
1107
args .append ("--stdin" )
1094
- proc = self .repo .git .checkout_index (args , as_process = True , istream = subprocess .PIPE , ** kwargs )
1108
+ kwargs ['as_process' ] = True
1109
+ kwargs ['istream' ] = subprocess .PIPE
1110
+ proc = self .repo .git .checkout_index (args , ** kwargs )
1095
1111
make_exc = lambda : GitCommandError (("git-checkout-index" ,)+ args , 128 , proc .stderr .read ())
1112
+ checked_out_files = list ()
1096
1113
for path in paths :
1097
1114
path = self ._to_relative_path (path )
1098
- self ._write_path_to_stdin (proc , path , path , make_exc , fprogress , read_from_stdout = False )
1115
+ # if the item is not in the index, it could be a directory
1116
+ path_is_directory = False
1117
+ try :
1118
+ self .entries [(path , 0 )]
1119
+ except KeyError :
1120
+ dir = path
1121
+ if not dir .endswith ('/' ):
1122
+ dir += '/'
1123
+ for entry in self .entries .itervalues ():
1124
+ if entry .path .startswith (dir ):
1125
+ p = entry .path
1126
+ self ._write_path_to_stdin (proc , p , p , make_exc , fprogress , read_from_stdout = False )
1127
+ checked_out_files .append (p )
1128
+ path_is_directory = True
1129
+ # END if entry is in directory
1130
+ # END for each entry
1131
+ # END path exception handlnig
1132
+
1133
+ if not path_is_directory :
1134
+ self ._write_path_to_stdin (proc , path , path , make_exc , fprogress , read_from_stdout = False )
1135
+ checked_out_files .append (path )
1136
+ # END path is a file
1099
1137
# END for each path
1100
1138
self ._flush_stdin_and_wait (proc )
1101
- handle_stderr (proc )
1139
+
1140
+ handle_stderr (proc , checked_out_files )
1141
+ return checked_out_files
1142
+ # END directory handling
1102
1143
# END paths handling
1103
- return self
1144
+ assert "Should not reach this point"
1104
1145
1105
1146
@clear_cache
1106
1147
@default_index
0 commit comments