Example #1
0
 def show_log(self, num):
     cur_commit = Commit(self.workspace, sha1=self.head_tree)
     print_str = cur_commit.raw_content
     while num > 1 and cur_commit.parent_sha1:
         num -= 1
         parent_commit = Commit(self.workspace, sha1=cur_commit.parent_sha1)
         print_str += '\n%s' % (parent_commit.raw_content)
         cur_commit = parent_commit
     less_str(print_str)
Example #2
0
 def test_commit_once(self):
     Command.cmd_commit('first ci')
     commit = Commit(sha1=Branch().head_commit)
     self.assertIsNone(commit.parent_sha1)
     tree = Tree(sha1=commit.tree)
     objects = tree.parse_objects()
     self.assertEqual(objects[self.path]['sha1'], Blob(self.content).sha1)
Example #3
0
    def commit(self, msg):
        new_tree = self.index.do_commit(self.workspace)

        committer_name = self.config.config_dict['user']['name']
        committer_email = '<%s>' % (self.config.config_dict['user']['email'])
        commit_time = int(time.time())
        commit_timezone = time.strftime("%z", time.gmtime())

        commit = Commit(self.workspace, sha1=None, tree_sha1=new_tree.sha1, parent_sha1=self.head_tree, name=committer_name, email=committer_email, \
                        timestamp=commit_time, timezone=commit_timezone, msg=msg)
        write_object_to_file(commit.path, commit.content)
        write_to_file(self.head_path, commit.sha1)
Example #4
0
    def _from_line(cls, remote, line):
        """
        Create a new PushInfo instance as parsed from line which is expected to be like
        c   refs/heads/master:refs/heads/master 05d2687..1d0568e
        """
        control_character, from_to, summary = line.split('\t', 3)
        flags = 0

        # control character handling
        try:
            flags |= cls._flag_map[control_character]
        except KeyError:
            raise ValueError(
                "Control Character %r unknown as parsed from line %r" %
                (control_character, line))
        # END handle control character

        # from_to handling
        from_ref_string, to_ref_string = from_to.split(':')
        if flags & cls.DELETED:
            from_ref = None
        else:
            from_ref = Reference.from_path(remote.repo, from_ref_string)

        # commit handling, could be message or commit info
        old_commit = None
        if summary.startswith('['):
            if "[rejected]" in summary:
                flags |= cls.REJECTED
            elif "[remote rejected]" in summary:
                flags |= cls.REMOTE_REJECTED
            elif "[remote failure]" in summary:
                flags |= cls.REMOTE_FAILURE
            elif "[no match]" in summary:
                flags |= cls.ERROR
            elif "[new tag]" in summary:
                flags |= cls.NEW_TAG
            elif "[new branch]" in summary:
                flags |= cls.NEW_HEAD
            # uptodate encoded in control character
        else:
            # fast-forward or forced update - was encoded in control character,
            # but we parse the old and new commit
            split_token = "..."
            if control_character == " ":
                split_token = ".."
            old_sha, new_sha = summary.split(' ')[0].split(split_token)
            old_commit = Commit(remote.repo, old_sha)
        # END message handling

        return PushInfo(flags, from_ref, to_ref_string, remote, old_commit,
                        summary)
	def _get_commit(self):
		"""
		:return:
			Commit object we point to, works for detached and non-detached 
			SymbolicReferences"""
		# we partially reimplement it to prevent unnecessary file access
		hexsha, target_ref_path = self._get_ref_info()
		
		# it is a detached reference
		if hexsha:
			return Commit(self.repo, hex_to_bin(hexsha))
		
		return self.from_path(self.repo, target_ref_path).commit
Example #6
0
def read_commits(repo_path):
    """ Возвращает (yield) объекты Commit для всех коммитов """
    commit = None
    cmds = git_cmd_start(repo_path) + ['log', '-m', '--parents', '--numstat', '--date=iso'] 
    process = Popen(cmds, stdout=PIPE, stderr=PIPE)
    
    for line in iter(process.stdout):
        line = line.replace('\n', '')
        if line.startswith("Author: "):
            commit.author = author_alias(line[len("Author: "):])
        elif line.startswith("Date: "):
            commit.date = line[len("Date: "):]
            commit.date = commit.date[:-6].strip() # убираем +0300
        elif line.startswith("commit "):
            if commit: 
                yield commit
            if ' (from' in line:
                line = line[:line.index(' (from')]
            hashes = line.split(' ')[1:]
            commit = Commit(hashes[0], hashes[1:])
        elif line.startswith("    "):
            commit.message = line[4:]
        else:
            m = r_numstat.match(line) 
            if m:
                f_add, f_rem, f_name = m.groups()
                if f_add != '-': # не бинарный
                    f_add, f_rem = int(f_add), int(f_rem)
                    commit.changes.append((f_name, f_add, f_rem))
                
    if commit: 
        yield commit
        
    errors = process.stderr.read()
    if errors:
        raise GitError("log: " + errors)
Example #7
0
    def test_commit_twice(self):
        Command.cmd_commit('first ci')
        parent_sha1 = Branch().head_commit

        second_content = '11\n'
        write_to_file(self.path, second_content)

        new_path = '2.txt'
        new_content = '2\n'
        write_to_file(new_path, new_content)

        Command.cmd_add('.')
        Command.cmd_commit('second ci')

        commit = Commit(sha1=Branch().head_commit)
        self.assertEqual(parent_sha1, commit.parent_sha1)
        tree = Tree(sha1=commit.tree)
        objects = tree.parse_objects()
        self.assertEqual(objects[self.path]['sha1'], Blob(second_content).sha1)
        self.assertEqual(objects[new_path]['sha1'], Blob(new_content).sha1)
Example #8
0
    def _from_line(cls, repo, line, fetch_line):
        """
        Parse information from the given line as returned by git-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,
                os.path.join(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 = Commit(repo, operation.split(split_token)[0])
            # END handle refspec
        # END reference flag handling

        return cls(remote_local_ref, flags, note, old_commit)