diff options
Diffstat (limited to 'lib/git/index.py')
| -rw-r--r-- | lib/git/index.py | 81 | 
1 files changed, 61 insertions, 20 deletions
| diff --git a/lib/git/index.py b/lib/git/index.py index 0a7bfe6e..f0da4b64 100644 --- a/lib/git/index.py +++ b/lib/git/index.py @@ -29,13 +29,18 @@ class CheckoutError( Exception ):  	changes.  	The .failed_files attribute contains a list of relative paths that failed  -	to be checked out as they contained changes that did not exist in the index""" -	def __init__(self, message, failed_files): -		super(CheckoutError, self).__init__(message) +	to be checked out as they contained changes that did not exist in the index. +	 +	The .valid_files attribute contains a list of relative paths to files that  +	were checked out successfully and hence match the version stored in the  +	index""" +	def __init__(self, message, failed_files, valid_files): +		Exception.__init__(self, message)  		self.failed_files = failed_files +		self.valid_files = valid_files  	def __str__(self): -		return super(CheckoutError, self).__str__() + ":%s" % self.failed_files  +		return Exception.__str__(self) + ":%s" % self.failed_files   class _TemporaryFileSwap(object): @@ -1009,29 +1014,34 @@ class IndexFile(LazyMixin, diff.Diffable):  	@default_index  	def checkout(self, paths=None, force=False, fprogress=lambda *args: None, **kwargs):  		""" -		Checkout the given paths or all files from the version in the index. +		Checkout the given paths or all files from the version known to the index into +		the working tree.  		``paths``  			If None, all paths in the index will be checked out. Otherwise an iterable -			of relative or absolute paths or a single path pointing to files in the index  -			is expected. -			The command will raise of files do not exist in the index ( as opposed to the  -			original git command who ignores them ) -			The provided progress information will contain None as path and item if no  -			explicit paths are given. +			of relative or absolute paths or a single path pointing to files or directories +			in the index is expected. +			The command will raise of files or directories do not exist in the index  +			( as opposed to the  original git command who ignores them ). Additionally  +			this command allows to checkout directories which is an extension to git-update-index. +			  		``force``  			If True, existing files will be overwritten even if they contain local modifications.   			If False, these will trigger a CheckoutError.  		``fprogress`` -			see Index.add_ for signature and explanation +			see Index.add_ for signature and explanation. +			The provided progress information will contain None as path and item if no  +			explicit paths are given. Otherwise progress information will be send +			prior and after a file has been checked out  		``**kwargs``  			Additional arguments to be pasesd to git-checkout-index  		Returns -			self +			iterable yielding paths to files which have been checked out and are  +			guaranteed to match the version stored in the index  		Raise CheckoutError  			If at least one file failed to be checked out. This is a summary,  @@ -1043,7 +1053,7 @@ class IndexFile(LazyMixin, diff.Diffable):  		if force:  			args.append("--force") -		def handle_stderr(proc): +		def handle_stderr(proc, iter_checked_out_files):  			stderr = proc.stderr.read()  			if not stderr:  				return @@ -1075,9 +1085,11 @@ class IndexFile(LazyMixin, diff.Diffable):  			if unknown_lines:  				raise GitCommandError(("git-checkout-index", ), 128, stderr)  			if failed_files: -				raise CheckoutError("Some files could not be checked out from the index due to local modifications", failed_files) +				valid_files = list(set(iter_checked_out_files) - set(failed_files)) +				raise CheckoutError("Some files could not be checked out from the index due to local modifications", failed_files, valid_files)  		# END stderr handler  +		  		if paths is None:  			args.append("--all")  			kwargs['as_process'] = 1 @@ -1085,22 +1097,51 @@ class IndexFile(LazyMixin, diff.Diffable):  			proc = self.repo.git.checkout_index(*args, **kwargs)  			proc.wait()  			fprogress(None, True, None) -			handle_stderr(proc) +			rval_iter = ( e.path for e in self.entries.itervalues() )  +			handle_stderr(proc, rval_iter) +			return rval_iter  		else:  			if isinstance(paths, basestring):  				paths = [paths]  			args.append("--stdin") -			proc = self.repo.git.checkout_index(args, as_process=True, istream=subprocess.PIPE, **kwargs) +			kwargs['as_process'] = True +			kwargs['istream'] = subprocess.PIPE +			proc = self.repo.git.checkout_index(args, **kwargs)  			make_exc = lambda : GitCommandError(("git-checkout-index",)+args, 128, proc.stderr.read()) +			checked_out_files = list()  			for path in paths:  				path = self._to_relative_path(path) -				self._write_path_to_stdin(proc, path, path, make_exc, fprogress, read_from_stdout=False)   +				# if the item is not in the index, it could be a directory +				path_is_directory = False +				try: +					self.entries[(path, 0)] +				except KeyError: +					dir = path +					if not dir.endswith('/'): +						dir += '/' +					for entry in self.entries.itervalues(): +						if entry.path.startswith(dir): +							p = entry.path +							self._write_path_to_stdin(proc, p, p, make_exc, fprogress, read_from_stdout=False) +							checked_out_files.append(p) +							path_is_directory = True +						# END if entry is in directory +					# END for each entry +				# END path exception handlnig +				 +				if not path_is_directory: +					self._write_path_to_stdin(proc, path, path, make_exc, fprogress, read_from_stdout=False) +					checked_out_files.append(path) +				# END path is a file  			# END for each path  			self._flush_stdin_and_wait(proc) -			handle_stderr(proc) +			 +			handle_stderr(proc, checked_out_files) +			return checked_out_files +			# END directory handling  		# END paths handling  -		return self +		assert "Should not reach this point"  	@clear_cache  	@default_index | 
