Example #1
0
    def _get_fetch_info_from_stderr(self, proc, progress):
        # skip first line as it is some remote info we are not interested in
        output = IterableList('name')

        # lines which are no progress are fetch info lines
        # this also waits for the command to finish
        # Skip some progress lines that don't provide relevant information
        fetch_info_lines = list()
        for line in self._digest_process_messages(proc.stderr, progress):
            if line.startswith('From') or line.startswith('remote: Total'):
                continue
            fetch_info_lines.append(line)
        # END for each line

        # read head information
        fp = open(join(self.repo.git_dir, 'FETCH_HEAD'), 'r')
        fetch_head_info = fp.readlines()
        fp.close()

        assert len(fetch_info_lines) == len(fetch_head_info)

        output.extend(
            FetchInfo._from_line(self.repo, err_line, fetch_line)
            for err_line, fetch_line in zip(fetch_info_lines, fetch_head_info))

        self._finalize_proc(proc)
        return output
Example #2
0
 def list_traverse(self, *args, **kwargs):
     """
     :return: IterableList with the results of the traversal as produced by
         traverse()"""
     out = IterableList(self._id_attribute_)
     out.extend(self.traverse(*args, **kwargs))
     return out
Example #3
0
 def list_traverse(self, *args, **kwargs):
     """
     :return: IterableList with the results of the traversal as produced by
         traverse()"""
     out = IterableList(self._id_attribute_)
     out.extend(self.traverse(*args, **kwargs))
     return out
Example #4
0
    def _list_traverse(
        self,
        as_edge: bool = False,
        *args: Any,
        **kwargs: Any
    ) -> IterableList[Union['Commit', 'Submodule', 'Tree', 'Blob']]:
        """
        :return: IterableList with the results of the traversal as produced by
            traverse()
            Commit -> IterableList['Commit']
            Submodule ->  IterableList['Submodule']
            Tree -> IterableList[Union['Submodule', 'Tree', 'Blob']]
        """
        # Commit and Submodule have id.__attribute__ as IterableObj
        # Tree has id.__attribute__ inherited from IndexObject
        if isinstance(self, Has_id_attribute):
            id = self._id_attribute_
        else:
            id = ""  # shouldn't reach here, unless Traversable subclass created with no _id_attribute_
            # could add _id_attribute_ to Traversable, or make all Traversable also Iterable?

        if not as_edge:
            out: IterableList[Union['Commit', 'Submodule', 'Tree',
                                    'Blob']] = IterableList(id)
            out.extend(self.traverse(as_edge=as_edge, *args, **kwargs))
            return out
            # overloads in subclasses (mypy does't allow typing self: subclass)
            # Union[IterableList['Commit'], IterableList['Submodule'], IterableList[Union['Submodule', 'Tree', 'Blob']]]
        else:
            # Raise deprecationwarning, doesn't make sense to use this
            out_list: IterableList = IterableList(
                self.traverse(*args, **kwargs))
            return out_list
Example #5
0
    def stale_refs(self):
        """
        :return:
            IterableList RemoteReference objects that do not have a corresponding
            head in the remote reference anymore as they have been deleted on the
            remote side, but are still available locally.

            The IterableList is prefixed, hence the 'origin' must be omitted. See
            'refs' property for an example.

            To make things more complicated, it can be possble for the list to include
            other kinds of references, for example, tag references, if these are stale
            as well. This is a fix for the issue described here:
            https://github.com/gitpython-developers/GitPython/issues/260
            """
        out_refs = IterableList(RemoteReference._id_attribute_, "%s/" % self.name)
        for line in self.repo.git.remote("prune", "--dry-run", self).splitlines()[2:]:
            # expecting
            # * [would prune] origin/new_branch
            token = " * [would prune] "
            if not line.startswith(token):
                raise ValueError("Could not parse git-remote prune result: %r" % line)
            ref_name = line.replace(token, "")
            # sometimes, paths start with a full ref name, like refs/tags/foo, see #260
            if ref_name.startswith(Reference._common_path_default + '/'):
                out_refs.append(SymbolicReference.from_path(self.repo, ref_name))
            else:
                fqhn = "%s/%s" % (RemoteReference._common_path_default, ref_name)
                out_refs.append(RemoteReference(self.repo, fqhn))
            # end special case handlin
        # END for each line
        return out_refs
Example #6
0
def get_fetch_info_from_stderr(repo, proc, progress):
    # skip first line as it is some remote info we are not interested in
    output = IterableList('name')

    # lines which are no progress are fetch info lines
    # this also waits for the command to finish
    # Skip some progress lines that don't provide relevant information
    fetch_info_lines = list()
    for line in digest_process_messages(proc.stderr, progress):
        if line.startswith('From') or line.startswith('remote: Total'):
            continue
        elif line.startswith('warning:'):
            print >> sys.stderr, line
            continue
        elif line.startswith('fatal:'):
            raise GitCommandError(("Error when fetching: %s" % line, ), 2)
        # END handle special messages
        fetch_info_lines.append(line)
    # END for each line

    # read head information
    fp = open(join(repo.git_dir, 'FETCH_HEAD'), 'r')
    fetch_head_info = fp.readlines()
    fp.close()

    assert len(fetch_info_lines) == len(fetch_head_info)

    output.extend(
        CmdFetchInfo._from_line(repo, err_line, fetch_line)
        for err_line, fetch_line in zip(fetch_info_lines, fetch_head_info))

    finalize_process(proc)
    return output
	def _get_fetch_info_from_stderr(self, proc, progress):
		# skip first line as it is some remote info we are not interested in
		output = IterableList('name')
		
		
		# lines which are no progress are fetch info lines
		# this also waits for the command to finish
		# Skip some progress lines that don't provide relevant information
		fetch_info_lines = list()
		for line in self._digest_process_messages(proc.stderr, progress):
			if line.startswith('From') or line.startswith('remote: Total'):
				continue
			fetch_info_lines.append(line)
		# END for each line
		
		# read head information 
		fp = open(join(self.repo.git_dir, 'FETCH_HEAD'),'r')
		fetch_head_info = fp.readlines()
		fp.close()
		
		assert len(fetch_info_lines) == len(fetch_head_info)
		
		output.extend(FetchInfo._from_line(self.repo, err_line, fetch_line) 
						for err_line,fetch_line in zip(fetch_info_lines, fetch_head_info))
		
		self._finalize_proc(proc)
		return output
Example #8
0
def get_fetch_info_from_stderr(repo, proc, progress):
    # skip first line as it is some remote info we are not interested in
    output = IterableList('name')

    # lines which are no progress are fetch info lines
    # this also waits for the command to finish
    # Skip some progress lines that don't provide relevant information
    fetch_info_lines = list()
    for line in digest_process_messages(proc.stderr, progress):
        if line.startswith('From') or line.startswith('remote: Total'):
            continue
        elif line.startswith('warning:'):
            print >> sys.stderr, line
            continue
        elif line.startswith('fatal:'):
            raise GitCommandError(("Error when fetching: %s" % line,), 2)
        # END handle special messages
        fetch_info_lines.append(line)
    # END for each line

    # read head information
    fp = open(join(repo.git_dir, 'FETCH_HEAD'), 'r')
    fetch_head_info = fp.readlines()
    fp.close()

    assert len(fetch_info_lines) == len(fetch_head_info)

    output.extend(CmdFetchInfo._from_line(repo, err_line, fetch_line)
                  for err_line, fetch_line in zip(fetch_info_lines, fetch_head_info))

    finalize_process(proc)
    return output
Example #9
0
    def _get_fetch_info_from_stderr(self, proc, progress):
        progress = to_progress_instance(progress)

        # skip first line as it is some remote info we are not interested in
        output = IterableList('name')

        # lines which are no progress are fetch info lines
        # this also waits for the command to finish
        # Skip some progress lines that don't provide relevant information
        fetch_info_lines = []
        # Basically we want all fetch info lines which appear to be in regular form, and thus have a
        # command character. Everything else we ignore,
        cmds = set(FetchInfo._flag_map.keys())

        progress_handler = progress.new_message_handler()
        handle_process_output(proc,
                              None,
                              progress_handler,
                              finalizer=None,
                              decode_streams=False)

        stderr_text = progress.error_lines and '\n'.join(
            progress.error_lines) or ''
        proc.wait(stderr=stderr_text)
        if stderr_text:
            log.warning("Error lines received while fetching: %s", stderr_text)

        for line in progress.other_lines:
            line = force_text(line)
            for cmd in cmds:
                if len(line) > 1 and line[0] == ' ' and line[1] == cmd:
                    fetch_info_lines.append(line)
                    continue

        # read head information
        with open(osp.join(self.repo.common_dir, 'FETCH_HEAD'), 'rb') as fp:
            fetch_head_info = [l.decode(defenc) for l in fp.readlines()]

        l_fil = len(fetch_info_lines)
        l_fhi = len(fetch_head_info)
        if l_fil != l_fhi:
            msg = "Fetch head lines do not match lines provided via progress information\n"
            msg += "length of progress lines %i should be equal to lines in FETCH_HEAD file %i\n"
            msg += "Will ignore extra progress lines or fetch head lines."
            msg %= (l_fil, l_fhi)
            log.debug(msg)
            log.debug("info lines: " + str(fetch_info_lines))
            log.debug("head info : " + str(fetch_head_info))
            if l_fil < l_fhi:
                fetch_head_info = fetch_head_info[:l_fil]
            else:
                fetch_info_lines = fetch_info_lines[:l_fhi]
            # end truncate correct list
        # end sanity check + sanitization

        output.extend(
            FetchInfo._from_line(self.repo, err_line, fetch_line)
            for err_line, fetch_line in zip(fetch_info_lines, fetch_head_info))
        return output
Example #10
0
    def _get_fetch_info_from_stderr(self, proc, progress):
        progress = to_progress_instance(progress)

        # skip first line as it is some remote info we are not interested in
        output = IterableList('name')

        # lines which are no progress are fetch info lines
        # this also waits for the command to finish
        # Skip some progress lines that don't provide relevant information
        fetch_info_lines = list()
        # Basically we want all fetch info lines which appear to be in regular form, and thus have a
        # command character. Everything else we ignore,
        cmds = set(PushInfo._flag_map.keys()) & set(FetchInfo._flag_map.keys())

        progress_handler = progress.new_message_handler()

        stderr_text = None

        for line in proc.stderr:
            line = force_text(line)
            for pline in progress_handler(line):
                # END handle special messages
                for cmd in cmds:
                    if len(line) > 1 and line[0] == ' ' and line[1] == cmd:
                        fetch_info_lines.append(line)
                        continue
                    # end find command code
                # end for each comand code we know
            # end for each line progress didn't handle
        # end
        if progress.error_lines():
            stderr_text = '\n'.join(progress.error_lines())

        finalize_process(proc, stderr=stderr_text)

        # read head information
        fp = open(join(self.repo.git_dir, 'FETCH_HEAD'), 'rb')
        fetch_head_info = [l.decode(defenc) for l in fp.readlines()]
        fp.close()

        l_fil = len(fetch_info_lines)
        l_fhi = len(fetch_head_info)
        if l_fil != l_fhi:
            msg = "Fetch head lines do not match lines provided via progress information\n"
            msg += "length of progress lines %i should be equal to lines in FETCH_HEAD file %i\n"
            msg += "Will ignore extra progress lines or fetch head lines."
            msg %= (l_fil, l_fhi)
            log.debug(msg)
            if l_fil < l_fhi:
                fetch_head_info = fetch_head_info[:l_fil]
            else:
                fetch_info_lines = fetch_info_lines[:l_fhi]
            # end truncate correct list
        # end sanity check + sanitization

        output.extend(
            FetchInfo._from_line(self.repo, err_line, fetch_line)
            for err_line, fetch_line in zip(fetch_info_lines, fetch_head_info))
        return output
Example #11
0
    def _get_fetch_info_from_stderr(self, proc, progress):
        progress = to_progress_instance(progress)

        # skip first line as it is some remote info we are not interested in
        output = IterableList('name')

        # lines which are no progress are fetch info lines
        # this also waits for the command to finish
        # Skip some progress lines that don't provide relevant information
        fetch_info_lines = list()
        # Basically we want all fetch info lines which appear to be in regular form, and thus have a
        # command character. Everything else we ignore,
        cmds = set(PushInfo._flag_map.keys()) & set(FetchInfo._flag_map.keys())

        progress_handler = progress.new_message_handler()

        stderr_text = None

        for line in proc.stderr:
            line = force_text(line)
            for pline in progress_handler(line):
                # END handle special messages
                for cmd in cmds:
                    if len(line) > 1 and line[0] == ' ' and line[1] == cmd:
                        fetch_info_lines.append(line)
                        continue
                    # end find command code
                # end for each comand code we know
            # end for each line progress didn't handle
        # end
        if progress.error_lines():
            stderr_text = '\n'.join(progress.error_lines())
            
        finalize_process(proc, stderr=stderr_text)

        # read head information
        fp = open(join(self.repo.git_dir, 'FETCH_HEAD'), 'rb')
        fetch_head_info = [l.decode(defenc) for l in fp.readlines()]
        fp.close()

        l_fil = len(fetch_info_lines)
        l_fhi = len(fetch_head_info)
        if l_fil != l_fhi:
            msg = "Fetch head lines do not match lines provided via progress information\n"
            msg += "length of progress lines %i should be equal to lines in FETCH_HEAD file %i\n"
            msg += "Will ignore extra progress lines or fetch head lines."
            msg %= (l_fil, l_fhi)
            log.debug(msg)
            if l_fil < l_fhi:
                fetch_head_info = fetch_head_info[:l_fil]
            else:
                fetch_info_lines = fetch_info_lines[:l_fhi]
            # end truncate correct list
        # end sanity check + sanitization
        
        output.extend(FetchInfo._from_line(self.repo, err_line, fetch_line)
                      for err_line, fetch_line in zip(fetch_info_lines, fetch_head_info))
        return output
Example #12
0
 def refs(self):
     """
     :return:
         IterableList of RemoteReference objects. It is prefixed, allowing
         you to omit the remote path portion, i.e.::
         remote.refs.master # yields RemoteReference('/refs/remotes/origin/master')"""
     out_refs = IterableList(RemoteReference._id_attribute_, "%s/" % self.name)
     out_refs.extend(RemoteReference.list_items(self.repo, remote=self.name))
     return out_refs
Example #13
0
 def refs(self):
     """
     :return:
         IterableList of RemoteReference objects. It is prefixed, allowing
         you to omit the remote path portion, i.e.::
         remote.refs.master # yields RemoteReference('/refs/remotes/origin/master')"""
     out_refs = IterableList(RemoteReference._id_attribute_, "%s/" % self.name)
     out_refs.extend(RemoteReference.list_items(self.repo, remote=self.name))
     return out_refs
    def _get_fetch_info_from_stderr(self, proc, progress):
        # skip first line as it is some remote info we are not interested in
        # TODO: Use poll() to process stdout and stderr at same time
        output = IterableList('name')

        # lines which are no progress are fetch info lines
        # this also waits for the command to finish
        # Skip some progress lines that don't provide relevant information
        fetch_info_lines = list()
        # Basically we want all fetch info lines which appear to be in regular form, and thus have a
        # command character. Everything else we ignore,
        cmds = set(PushInfo._flag_map.keys()) & set(FetchInfo._flag_map.keys())

        progress_handler = progress.new_message_handler()

        for line in proc.stderr:
            line = line.decode(defenc)
            line = line.rstrip()
            for pline in progress_handler(line):
                if line.startswith('fatal:'):
                    raise GitCommandError(("Error when fetching: %s" % line, ),
                                          2)
                # END handle special messages
                for cmd in cmds:
                    if len(line) > 1 and line[0] == ' ' and line[1] == cmd:
                        fetch_info_lines.append(line)
                        continue
                    # end find command code
                # end for each comand code we know
            # end for each line progress didn't handle
        # end

        # We are only interested in stderr here ...
        try:
            finalize_process(proc)
        except Exception:
            if len(fetch_info_lines) == 0:
                raise
        # end exception handler

        # read head information
        fp = open(join(self.repo.git_dir, 'FETCH_HEAD'), 'rb')
        fetch_head_info = [l.decode(defenc) for l in fp.readlines()]
        fp.close()

        # NOTE: We assume to fetch at least enough progress lines to allow matching each fetch head line with it.
        assert len(fetch_info_lines) >= len(
            fetch_head_info), "len(%s) <= len(%s)" % (fetch_head_info,
                                                      fetch_info_lines)

        output.extend(
            FetchInfo._from_line(self.repo, err_line, fetch_line)
            for err_line, fetch_line in zip(fetch_info_lines, fetch_head_info))
        return output
Example #15
0
    def _get_fetch_info_from_stderr(self, proc, progress):
        progress = to_progress_instance(progress)

        # skip first line as it is some remote info we are not interested in
        output = IterableList('name')

        # lines which are no progress are fetch info lines
        # this also waits for the command to finish
        # Skip some progress lines that don't provide relevant information
        fetch_info_lines = []
        # Basically we want all fetch info lines which appear to be in regular form, and thus have a
        # command character. Everything else we ignore,
        cmds = set(FetchInfo._flag_map.keys())

        progress_handler = progress.new_message_handler()
        handle_process_output(proc, None, progress_handler, finalizer=None, decode_streams=False)

        stderr_text = progress.error_lines and '\n'.join(progress.error_lines) or ''
        proc.wait(stderr=stderr_text)
        if stderr_text:
            log.warning("Error lines received while fetching: %s", stderr_text)

        for line in progress.other_lines:
            line = force_text(line)
            for cmd in cmds:
                if len(line) > 1 and line[0] == ' ' and line[1] == cmd:
                    fetch_info_lines.append(line)
                    continue

        # read head information
        with open(osp.join(self.repo.common_dir, 'FETCH_HEAD'), 'rb') as fp:
            fetch_head_info = [l.decode(defenc) for l in fp.readlines()]

        l_fil = len(fetch_info_lines)
        l_fhi = len(fetch_head_info)
        if l_fil != l_fhi:
            msg = "Fetch head lines do not match lines provided via progress information\n"
            msg += "length of progress lines %i should be equal to lines in FETCH_HEAD file %i\n"
            msg += "Will ignore extra progress lines or fetch head lines."
            msg %= (l_fil, l_fhi)
            log.debug(msg)
            log.debug("info lines: " + str(fetch_info_lines))
            log.debug("head info : " + str(fetch_head_info))
            if l_fil < l_fhi:
                fetch_head_info = fetch_head_info[:l_fil]
            else:
                fetch_info_lines = fetch_info_lines[:l_fhi]
            # end truncate correct list
        # end sanity check + sanitization

        output.extend(FetchInfo._from_line(self.repo, err_line, fetch_line)
                      for err_line, fetch_line in zip(fetch_info_lines, fetch_head_info))
        return output
Example #16
0
    def _get_fetch_info_from_stderr(self, proc, progress):
        # skip first line as it is some remote info we are not interested in
        # TODO: Use poll() to process stdout and stderr at same time
        output = IterableList('name')

        # lines which are no progress are fetch info lines
        # this also waits for the command to finish
        # Skip some progress lines that don't provide relevant information
        fetch_info_lines = list()
        # Basically we want all fetch info lines which appear to be in regular form, and thus have a
        # command character. Everything else we ignore,
        cmds = set(PushInfo._flag_map.keys()) & set(FetchInfo._flag_map.keys())

        progress_handler = progress.new_message_handler()

        for line in proc.stderr:
            line = line.decode(defenc)
            line = line.rstrip()
            for pline in progress_handler(line):
                if line.startswith('fatal:') or line.startswith('error:'):
                    raise GitCommandError(("Error when fetching: %s" % line,), 2)
                # END handle special messages
                for cmd in cmds:
                    if len(line) > 1 and line[0] == ' ' and line[1] == cmd:
                        fetch_info_lines.append(line)
                        continue
                    # end find command code
                # end for each comand code we know
            # end for each line progress didn't handle
        # end

        # We are only interested in stderr here ...
        try:
            finalize_process(proc)
        except Exception:
            if len(fetch_info_lines) == 0:
                raise
        # end exception handler

        # read head information
        fp = open(join(self.repo.git_dir, 'FETCH_HEAD'), 'rb')
        fetch_head_info = [l.decode(defenc) for l in fp.readlines()]
        fp.close()

        # NOTE: We assume to fetch at least enough progress lines to allow matching each fetch head line with it.
        assert len(fetch_info_lines) >= len(fetch_head_info), "len(%s) <= len(%s)" % (fetch_head_info,
                                                                                      fetch_info_lines)

        output.extend(FetchInfo._from_line(self.repo, err_line, fetch_line)
                      for err_line, fetch_line in zip(fetch_info_lines, fetch_head_info))
        return output
	def refs(self):
		"""
		:return:
			IterableList of RemoteReference objects. It is prefixed, allowing 
			you to omit the remote path portion, i.e.::
			 remote.refs.master # yields RemoteReference('/refs/remotes/origin/master')"""
		out_refs = IterableList(RemoteReference._id_attribute_, "%s/" % self.name)
		for ref in RemoteReference.list_items(self.repo):
			if ref.remote_name == self.name:
				out_refs.append(ref)
			# END if names match
		# END for each ref
		assert out_refs, "Remote %s did not have any references" % self.name
		return out_refs
Example #18
0
    def refs(self):
        """
		:return:
			IterableList of RemoteReference objects. It is prefixed, allowing 
			you to omit the remote path portion, i.e.::
			 remote.refs.master # yields RemoteReference('/refs/remotes/origin/master')"""
        out_refs = IterableList(RemoteReference._id_attribute_,
                                "%s/" % self.name)
        for ref in RemoteReference.list_items(self.repo):
            if ref.remote_name == self.name:
                out_refs.append(ref)
            # END if names match
        # END for each ref
        assert out_refs, "Remote %s did not have any references" % self.name
        return out_refs
Example #19
0
def mock_repo():
    """repo mock fixture"""
    repo_mock = Mock()
    repo_git_mock = Mock()
    repo_mock.attach_mock(repo_git_mock, 'git')

    remote = Mock(spec=git.Remote)
    remote.configure_mock(name="origin", url="http://example.com")
    remote_list = IterableList("name")
    remote_list.extend([remote])

    repo_mock.remotes = remote_list
    repo_mock.branches = []

    return repo_mock
Example #20
0
    def test_iterable_list(self, case):
        name, prefix = case
        l = IterableList(name, prefix)

        name1 = "one"
        name2 = "two"
        m1 = TestIterableMember(prefix + name1)
        m2 = TestIterableMember(prefix + name2)

        l.extend((m1, m2))

        self.assertEqual(len(l), 2)

        # contains works with name and identity
        self.assertIn(name1, l)
        self.assertIn(name2, l)
        self.assertIn(m2, l)
        self.assertIn(m2, l)
        self.assertNotIn('invalid', l)

        # with string index
        self.assertIs(l[name1], m1)
        self.assertIs(l[name2], m2)

        # with int index
        self.assertIs(l[0], m1)
        self.assertIs(l[1], m2)

        # with getattr
        self.assertIs(l.one, m1)
        self.assertIs(l.two, m2)

        # test exceptions
        self.failUnlessRaises(AttributeError, getattr, l, 'something')
        self.failUnlessRaises(IndexError, l.__getitem__, 'something')

        # delete by name and index
        self.failUnlessRaises(IndexError, l.__delitem__, 'something')
        del(l[name2])
        self.assertEqual(len(l), 1)
        self.assertNotIn(name2, l)
        self.assertIn(name1, l)
        del(l[0])
        self.assertNotIn(name1, l)
        self.assertEqual(len(l), 0)

        self.failUnlessRaises(IndexError, l.__delitem__, 0)
        self.failUnlessRaises(IndexError, l.__delitem__, 'something')
Example #21
0
    def test_iterable_list(self, case):
        name, prefix = case
        ilist = IterableList(name, prefix)

        name1 = "one"
        name2 = "two"
        m1 = TestIterableMember(prefix + name1)
        m2 = TestIterableMember(prefix + name2)

        ilist.extend((m1, m2))

        self.assertEqual(len(ilist), 2)

        # contains works with name and identity
        self.assertIn(name1, ilist)
        self.assertIn(name2, ilist)
        self.assertIn(m2, ilist)
        self.assertIn(m2, ilist)
        self.assertNotIn('invalid', ilist)

        # with string index
        self.assertIs(ilist[name1], m1)
        self.assertIs(ilist[name2], m2)

        # with int index
        self.assertIs(ilist[0], m1)
        self.assertIs(ilist[1], m2)

        # with getattr
        self.assertIs(ilist.one, m1)
        self.assertIs(ilist.two, m2)

        # test exceptions
        self.failUnlessRaises(AttributeError, getattr, ilist, 'something')
        self.failUnlessRaises(IndexError, ilist.__getitem__, 'something')

        # delete by name and index
        self.failUnlessRaises(IndexError, ilist.__delitem__, 'something')
        del (ilist[name2])
        self.assertEqual(len(ilist), 1)
        self.assertNotIn(name2, ilist)
        self.assertIn(name1, ilist)
        del (ilist[0])
        self.assertNotIn(name1, ilist)
        self.assertEqual(len(ilist), 0)

        self.failUnlessRaises(IndexError, ilist.__delitem__, 0)
        self.failUnlessRaises(IndexError, ilist.__delitem__, 'something')
Example #22
0
    def _get_push_info(self, proc, progress):
        progress = to_progress_instance(progress)

        # read progress information from stderr
        # we hope stdout can hold all the data, it should ...
        # read the lines manually as it will use carriage returns between the messages
        # to override the previous one. This is why we read the bytes manually
        progress_handler = progress.new_message_handler()
        output = IterableList('name')

        def stdout_handler(line):
            try:
                output.append(PushInfo._from_line(self, line))
            except ValueError:
                # If an error happens, additional info is given which we parse below.
                pass

        handle_process_output(proc,
                              stdout_handler,
                              progress_handler,
                              finalizer=None,
                              decode_streams=False)
        stderr_text = progress.error_lines and '\n'.join(
            progress.error_lines) or ''
        try:
            proc.wait(stderr=stderr_text)
        except Exception:
            if not output:
                raise
            elif stderr_text:
                log.warning("Error lines received while fetching: %s",
                            stderr_text)

        return output
Example #23
0
    def stale_refs(self) -> IterableList[Reference]:
        """
        :return:
            IterableList RemoteReference objects that do not have a corresponding
            head in the remote reference anymore as they have been deleted on the
            remote side, but are still available locally.

            The IterableList is prefixed, hence the 'origin' must be omitted. See
            'refs' property for an example.

            To make things more complicated, it can be possible for the list to include
            other kinds of references, for example, tag references, if these are stale
            as well. This is a fix for the issue described here:
            https://github.com/gitpython-developers/GitPython/issues/260
            """
        out_refs: IterableList[Reference] = IterableList(RemoteReference._id_attribute_, "%s/" % self.name)
        for line in self.repo.git.remote("prune", "--dry-run", self).splitlines()[2:]:
            # expecting
            # * [would prune] origin/new_branch
            token = " * [would prune] "
            if not line.startswith(token):
                continue
            ref_name = line.replace(token, "")
            # sometimes, paths start with a full ref name, like refs/tags/foo, see #260
            if ref_name.startswith(Reference._common_path_default + '/'):
                out_refs.append(Reference.from_path(self.repo, ref_name))
            else:
                fqhn = "%s/%s" % (RemoteReference._common_path_default, ref_name)
                out_refs.append(RemoteReference(self.repo, fqhn))
            # end special case handling
        # END for each line
        return out_refs
    def _get_push_info(self, proc, progress):
        # read progress information from stderr
        # we hope stdout can hold all the data, it should ...
        # read the lines manually as it will use carriage returns between the messages
        # to override the previous one. This is why we read the bytes manually
        # TODO: poll() on file descriptors to know what to read next, process streams concurrently
        progress_handler = progress.new_message_handler()
        output = IterableList('name')

        def stdout_handler(line):
            try:
                output.append(PushInfo._from_line(self, line))
            except ValueError:
                # if an error happens, additional info is given which we cannot parse
                pass
            # END exception handling

        # END for each line

        try:
            handle_process_output(proc, stdout_handler, progress_handler,
                                  finalize_process)
        except Exception:
            if len(output) == 0:
                raise
        return output
Example #25
0
    def test_iterable_list(self):
        for args in (('name',), ('name', 'prefix_')):
            l = IterableList('name')

            m1 = TestIterableMember('one')
            m2 = TestIterableMember('two')

            l.extend((m1, m2))

            assert len(l) == 2

            # contains works with name and identity
            assert m1.name in l
            assert m2.name in l
            assert m2 in l
            assert m2 in l
            assert 'invalid' not in l

            # with string index
            assert l[m1.name] is m1
            assert l[m2.name] is m2

            # with int index
            assert l[0] is m1
            assert l[1] is m2

            # with getattr
            assert l.one is m1
            assert l.two is m2

            # test exceptions
            self.failUnlessRaises(AttributeError, getattr, l, 'something')
            self.failUnlessRaises(IndexError, l.__getitem__, 'something')

            # delete by name and index
            self.failUnlessRaises(IndexError, l.__delitem__, 'something')
            del(l[m2.name])
            assert len(l) == 1
            assert m2.name not in l and m1.name in l
            del(l[0])
            assert m1.name not in l
            assert len(l) == 0

            self.failUnlessRaises(IndexError, l.__delitem__, 0)
            self.failUnlessRaises(IndexError, l.__delitem__, 'something')
Example #26
0
    def test_iterable_list(self):
        for args in (('name', ), ('name', 'prefix_')):
            l = IterableList('name')

            m1 = TestIterableMember('one')
            m2 = TestIterableMember('two')

            l.extend((m1, m2))

            assert len(l) == 2

            # contains works with name and identity
            assert m1.name in l
            assert m2.name in l
            assert m2 in l
            assert m2 in l
            assert 'invalid' not in l

            # with string index
            assert l[m1.name] is m1
            assert l[m2.name] is m2

            # with int index
            assert l[0] is m1
            assert l[1] is m2

            # with getattr
            assert l.one is m1
            assert l.two is m2

            # test exceptions
            self.failUnlessRaises(AttributeError, getattr, l, 'something')
            self.failUnlessRaises(IndexError, l.__getitem__, 'something')

            # delete by name and index
            self.failUnlessRaises(IndexError, l.__delitem__, 'something')
            del (l[m2.name])
            assert len(l) == 1
            assert m2.name not in l and m1.name in l
            del (l[0])
            assert m1.name not in l
            assert len(l) == 0

            self.failUnlessRaises(IndexError, l.__delitem__, 0)
            self.failUnlessRaises(IndexError, l.__delitem__, 'something')
Example #27
0
    def _get_push_info(self, proc, progress):
        # read progress information from stderr
        # we hope stdout can hold all the data, it should ...
        # read the lines manually as it will use carriage returns between the messages
        # to override the previous one. This is why we read the bytes manually
        digest_process_messages(proc.stderr, progress)

        output = IterableList('name')
        for line in proc.stdout.readlines():
            try:
                output.append(PushInfo._from_line(self, line))
            except ValueError:
                # if an error happens, additional info is given which we cannot parse
                pass
            # END exception handling
        # END for each line

        finalize_process(proc)
        return output
Example #28
0
def get_push_info(repo, remotename_or_url, proc, progress):
    # read progress information from stderr
    # we hope stdout can hold all the data, it should ...
    # read the lines manually as it will use carriage returns between the messages
    # to override the previous one. This is why we read the bytes manually
    stdout, stderr = proc.communicate()
    digest_process_messages(StringIO(stderr), progress)

    output = IterableList('name')
    for line in stdout.splitlines():
        try:
            output.append(CmdPushInfo._from_line(repo, remotename_or_url, line))
        except ValueError:
            # if an error happens, additional info is given which we cannot parse
            pass
        # END exception handling
    # END for each line

    return output
	def _get_push_info(self, proc, progress):
		# read progress information from stderr
		# we hope stdout can hold all the data, it should ...
		# read the lines manually as it will use carriage returns between the messages
		# to override the previous one. This is why we read the bytes manually
		self._digest_process_messages(proc.stderr, progress)
		
		output = IterableList('name')
		for line in proc.stdout.readlines():
			try:
				output.append(PushInfo._from_line(self, line))
			except ValueError:
				# if an error happens, additional info is given which we cannot parse
				pass
			# END exception handling 
		# END for each line
		
		self._finalize_proc(proc)
		return output
Example #30
0
def get_push_info(repo, remotename_or_url, proc, progress):
    # read progress information from stderr
    # we hope stdout can hold all the data, it should ...
    # read the lines manually as it will use carriage returns between the messages
    # to override the previous one. This is why we read the bytes manually
    stdout, stderr = proc.communicate()
    digest_process_messages(StringIO(stderr), progress)

    output = IterableList('name')
    for line in stdout.splitlines():
        try:
            output.append(CmdPushInfo._from_line(repo, remotename_or_url,
                                                 line))
        except ValueError:
            # if an error happens, additional info is given which we cannot parse
            pass
        # END exception handling
    # END for each line

    return output
Example #31
0
    def stale_refs(self):
        """
        :return:
            IterableList RemoteReference objects that do not have a corresponding
            head in the remote reference anymore as they have been deleted on the
            remote side, but are still available locally.

            The IterableList is prefixed, hence the 'origin' must be omitted. See
            'refs' property for an example."""
        out_refs = IterableList(RemoteReference._id_attribute_, "%s/" % self.name)
        for line in self.repo.git.remote("prune", "--dry-run", self).splitlines()[2:]:
            # expecting
            # * [would prune] origin/new_branch
            token = " * [would prune] "
            if not line.startswith(token):
                raise ValueError("Could not parse git-remote prune result: %r" % line)
            fqhn = "%s/%s" % (RemoteReference._common_path_default, line.replace(token, ""))
            out_refs.append(RemoteReference(self.repo, fqhn))
        # END for each line
        return out_refs
	def stale_refs(self):
		"""
		:return:
			IterableList RemoteReference objects that do not have a corresponding 
			head in the remote reference anymore as they have been deleted on the 
			remote side, but are still available locally.
			
			The IterableList is prefixed, hence the 'origin' must be omitted. See
			'refs' property for an example."""
		out_refs = IterableList(RemoteReference._id_attribute_, "%s/" % self.name)
		for line in self.repo.git.remote("prune", "--dry-run", self).splitlines()[2:]:
			# expecting 
			# * [would prune] origin/new_branch
			token = " * [would prune] " 
			if not line.startswith(token):
				raise ValueError("Could not parse git-remote prune result: %r" % line)
			fqhn = "%s/%s" % (RemoteReference._common_path_default,line.replace(token, ""))
			out_refs.append(RemoteReference(self.repo, fqhn))
		# END for each line 
		return out_refs
Example #33
0
    def _get_fetch_info_from_stderr(self, proc, progress):
        # skip first line as it is some remote info we are not interested in
        output = IterableList('name')

        # lines which are no progress are fetch info lines
        # this also waits for the command to finish
        # Skip some progress lines that don't provide relevant information
        fetch_info_lines = list()
        for line in digest_process_messages(proc.stderr, progress):
            if line.startswith('From') or line.startswith('remote: Total') or line.startswith('POST') \
                    or line.startswith(' ='):
                continue
            elif line.startswith('warning:'):
                print >> sys.stderr, line
                continue
            elif line.startswith('fatal:'):
                raise GitCommandError(("Error when fetching: %s" % line, ), 2)
            # END handle special messages
            fetch_info_lines.append(line)
        # END for each line

        # read head information
        fp = open(join(self.repo.git_dir, 'FETCH_HEAD'), 'r')
        fetch_head_info = fp.readlines()
        fp.close()

        # NOTE: HACK Just disabling this line will make github repositories work much better.
        # I simply couldn't stand it anymore, so here is the quick and dirty fix ... .
        # This project needs a lot of work !
        # assert len(fetch_info_lines) == len(fetch_head_info), "len(%s) != len(%s)" % (fetch_head_info, fetch_info_lines)

        output.extend(
            FetchInfo._from_line(self.repo, err_line, fetch_line)
            for err_line, fetch_line in zip(fetch_info_lines, fetch_head_info))

        finalize_process(proc)
        return output
Example #34
0
    def _get_push_info(
        self,
        proc: 'Git.AutoInterrupt',
        progress: Union[Callable[..., Any], RemoteProgress, None],
        kill_after_timeout: Union[None,
                                  float] = None) -> IterableList[PushInfo]:
        progress = to_progress_instance(progress)

        # read progress information from stderr
        # we hope stdout can hold all the data, it should ...
        # read the lines manually as it will use carriage returns between the messages
        # to override the previous one. This is why we read the bytes manually
        progress_handler = progress.new_message_handler()
        output: IterableList[PushInfo] = IterableList('push_infos')

        def stdout_handler(line: str) -> None:
            try:
                output.append(PushInfo._from_line(self, line))
            except ValueError:
                # If an error happens, additional info is given which we parse below.
                pass

        handle_process_output(proc,
                              stdout_handler,
                              progress_handler,
                              finalizer=None,
                              decode_streams=False,
                              kill_after_timeout=kill_after_timeout)
        stderr_text = progress.error_lines and '\n'.join(
            progress.error_lines) or ''
        try:
            proc.wait(stderr=stderr_text)
        except Exception:
            # This is different than fetch (which fails if there is any std_err
            # even if there is an output)
            if not output:
                raise
            elif stderr_text:
                log.warning("Error lines received while fetching: %s",
                            stderr_text)

        return output
Example #35
0
 def __new__(cls) -> 'PushInfoList':
     return cast(PushInfoList, IterableList.__new__(cls, 'push_infos'))
Example #36
0
    def _get_fetch_info_from_stderr(self, proc: 'Git.AutoInterrupt',
                                    progress: Union[Callable[..., Any], RemoteProgress, None],
                                    kill_after_timeout: Union[None, float] = None,
                                    ) -> IterableList['FetchInfo']:

        progress = to_progress_instance(progress)

        # skip first line as it is some remote info we are not interested in
        output: IterableList['FetchInfo'] = IterableList('name')

        # lines which are no progress are fetch info lines
        # this also waits for the command to finish
        # Skip some progress lines that don't provide relevant information
        fetch_info_lines = []
        # Basically we want all fetch info lines which appear to be in regular form, and thus have a
        # command character. Everything else we ignore,
        cmds = set(FetchInfo._flag_map.keys())

        progress_handler = progress.new_message_handler()
        handle_process_output(proc, None, progress_handler, finalizer=None, decode_streams=False,
                              kill_after_timeout=kill_after_timeout)

        stderr_text = progress.error_lines and '\n'.join(progress.error_lines) or ''
        proc.wait(stderr=stderr_text)
        if stderr_text:
            log.warning("Error lines received while fetching: %s", stderr_text)

        for line in progress.other_lines:
            line = force_text(line)
            for cmd in cmds:
                if len(line) > 1 and line[0] == ' ' and line[1] == cmd:
                    fetch_info_lines.append(line)
                    continue

        # read head information
        fetch_head = SymbolicReference(self.repo, "FETCH_HEAD")
        with open(fetch_head.abspath, 'rb') as fp:
            fetch_head_info = [line.decode(defenc) for line in fp.readlines()]

        l_fil = len(fetch_info_lines)
        l_fhi = len(fetch_head_info)
        if l_fil != l_fhi:
            msg = "Fetch head lines do not match lines provided via progress information\n"
            msg += "length of progress lines %i should be equal to lines in FETCH_HEAD file %i\n"
            msg += "Will ignore extra progress lines or fetch head lines."
            msg %= (l_fil, l_fhi)
            log.debug(msg)
            log.debug(b"info lines: " + str(fetch_info_lines).encode("UTF-8"))
            log.debug(b"head info: " + str(fetch_head_info).encode("UTF-8"))
            if l_fil < l_fhi:
                fetch_head_info = fetch_head_info[:l_fil]
            else:
                fetch_info_lines = fetch_info_lines[:l_fhi]
            # end truncate correct list
        # end sanity check + sanitization

        for err_line, fetch_line in zip(fetch_info_lines, fetch_head_info):
            try:
                output.append(FetchInfo._from_line(self.repo, err_line, fetch_line))
            except ValueError as exc:
                log.debug("Caught error while parsing line: %s", exc)
                log.warning("Git informed while fetching: %s", err_line.strip())
        return output