Beispiel #1
0
	def iter_items(cls, repo, common_path = None, remote=None):
		"""Iterate remote references, and if given, constrain them to the given remote"""
		common_path = common_path or cls._common_path_default
		if remote is not None:
			common_path = join_path(common_path, str(remote))
		# END handle remote constraint
		return super(RemoteReference, cls).iter_items(repo, common_path)
Beispiel #2
0
	def __div__(self, file):
		"""Find the named object in this tree's contents
		:return: ``git.Blob`` or ``git.Tree`` or ``git.Submodule``
		
		:raise KeyError: if given file or tree does not exist in tree"""
		msg = "Blob or Tree named %r not found"
		if '/' in file:
			tree = self
			item = self
			tokens = file.split('/')
			for i,token in enumerate(tokens):
				item = tree[token]
				if item.type == 'tree':
					tree = item
				else:
					# safety assertion - blobs are at the end of the path
					if i != len(tokens)-1:
						raise KeyError(msg % file)
					return item
				# END handle item type
			# END for each token of split path
			if item == self:
				raise KeyError(msg % file)
			return item
		else:
			for info in self._cache:
				if info[2] == file:		# [2] == name
					return self._map_id_to_type[info[1] >> 12](self.repo, info[0], info[1], join_path(self.path, info[2]))
			# END for each obj
			raise KeyError( msg % file )
Beispiel #3
0
	def _iter_items(cls, repo, common_path = None):
		if common_path is None:
			common_path = cls._common_path_default
		rela_paths = set()
		
		# walk loose refs
		# Currently we do not follow links 
		for root, dirs, files in os.walk(join_path_native(repo.git_dir, common_path)):
			if 'refs/' not in root: # skip non-refs subfolders
				refs_id = [ i for i,d in enumerate(dirs) if d == 'refs' ]
				if refs_id:
					dirs[0:] = ['refs']
			# END prune non-refs folders
			
			for f in files:
				abs_path = to_native_path_linux(join_path(root, f))
				rela_paths.add(abs_path.replace(to_native_path_linux(repo.git_dir) + '/', ""))
			# END for each file in root directory
		# END for each directory to walk
		
		# read packed refs
		for sha, rela_path in cls._iter_packed_refs(repo):
			if rela_path.startswith(common_path):
				rela_paths.add(rela_path)
			# END relative path matches common path
		# END packed refs reading
		
		# return paths in sorted order
		for path in sorted(rela_paths):
			try:
				yield cls.from_path(repo, path)
			except ValueError:
				continue
Beispiel #4
0
	def _iter_convert_to_object(self, iterable):
		"""Iterable yields tuples of (binsha, mode, name), which will be converted
		to the respective object representation"""
		for binsha, mode, name in iterable:
			path = join_path(self.path, name)
			try:
				yield self._map_id_to_type[mode >> 12](self.repo, binsha, mode, path)
			except KeyError:
				raise TypeError("Unknown mode %o found in tree data for path '%s'" % (mode, path))
Beispiel #5
0
	def __getitem__(self, item):
		if isinstance(item, int):
			info = self._cache[item]
			return self._map_id_to_type[info[1] >> 12](self.repo, info[0], info[1], join_path(self.path, info[2]))
		
		if isinstance(item, basestring):
			# compatability
			return self.__div__(item)
		# END index is basestring 
		
		raise TypeError( "Invalid index type: %r" % item )
Beispiel #6
0
	def tracking_branch(self):
		"""
		:return: The remote_reference we are tracking, or None if we are 
			not a tracking branch"""
		reader = self.config_reader()
		if reader.has_option(self.k_config_remote) and reader.has_option(self.k_config_remote_ref):
			ref = Head(self.repo, Head.to_full_path(reader.get_value(self.k_config_remote_ref)))
			remote_refpath = RemoteReference.to_full_path(join_path(reader.get_value(self.k_config_remote), ref.name))
			return RemoteReference(self.repo, remote_refpath)
		# END handle have tracking branch
		
		# we are not a tracking branch
		return None
Beispiel #7
0
	def __contains__(self, item):
		if isinstance(item, IndexObject):
			for info in self._cache:
				if item.binsha == info[0]:
					return True
				# END compare sha
			# END for each entry
		# END handle item is index object
		# compatability
		
		# treat item as repo-relative path
		path = self.path
		for info in self._cache:
			if item == join_path(path, info[2]):
				return True
		# END for each item
		return False
Beispiel #8
0
	def _from_line(cls, repo, line, fetch_line):
		"""Parse information from the given line as returned by pygit-fetch -v
		and return a new FetchInfo object representing this information.
		
		We can handle a line as follows
		"%c %-*s %-*s -> %s%s"
		
		Where c is either ' ', !, +, -, *, or =
		! means error
		+ means success forcing update
		- means a tag was updated
		* means birth of new branch or tag
		= means the head was up to date ( and not moved )
		' ' means a fast-forward
		
		fetch line is the corresponding line from FETCH_HEAD, like
		acb0fa8b94ef421ad60c8507b634759a472cd56c	not-for-merge	branch '0.1.7RC' of /tmp/tmpya0vairemote_repo"""
		match = cls.re_fetch_result.match(line)
		if match is None:
			raise ValueError("Failed to parse line: %r" % line)
			
		# parse lines
		control_character, operation, local_remote_ref, remote_local_ref, note = match.groups()
		try:
			new_hex_sha, fetch_operation, fetch_note = fetch_line.split("\t")
			ref_type_name, fetch_note = fetch_note.split(' ', 1)
		except ValueError:	# unpack error
			raise ValueError("Failed to parse FETCH__HEAD line: %r" % fetch_line)
		
		# handle FETCH_HEAD and figure out ref type
		# If we do not specify a target branch like master:refs/remotes/origin/master, 
		# the fetch result is stored in FETCH_HEAD which destroys the rule we usually
		# have. In that case we use a symbolic reference which is detached 
		ref_type = None
		if remote_local_ref == "FETCH_HEAD":
			ref_type = SymbolicReference
		elif ref_type_name	== "branch":
			ref_type = RemoteReference
		elif ref_type_name == "tag":
			ref_type = TagReference
		else:
			raise TypeError("Cannot handle reference type: %r" % ref_type_name)
			
		# create ref instance
		if ref_type is SymbolicReference:
			remote_local_ref = ref_type(repo, "FETCH_HEAD") 
		else:
			remote_local_ref = Reference.from_path(repo, join_path(ref_type._common_path_default, remote_local_ref.strip()))
		# END create ref instance 
		
		note = ( note and note.strip() ) or ''
		
		# parse flags from control_character
		flags = 0
		try:
			flags |= cls._flag_map[control_character]
		except KeyError:
			raise ValueError("Control character %r unknown as parsed from line %r" % (control_character, line))
		# END control char exception hanlding 
		
		# parse operation string for more info - makes no sense for symbolic refs
		old_commit = None
		if isinstance(remote_local_ref, Reference):
			if 'rejected' in operation:
				flags |= cls.REJECTED
			if 'new tag' in operation:
				flags |= cls.NEW_TAG
			if 'new branch' in operation:
				flags |= cls.NEW_HEAD
			if '...' in operation or '..' in operation:
				split_token = '...'
				if control_character == ' ':
					split_token = split_token[:-1]
				old_commit = repo.rev_parse(operation.split(split_token)[0])
			# END handle refspec
		# END reference flag handling
		
		return cls(remote_local_ref, flags, note, old_commit)