예제 #1
0
    def __get_notes_filename(cls, notes_rev):
        """Return the filename used to store the git notes.

        PARAMETERS
            notes_rev: The revision of the notes change.
        """
        # A git note for any given commit (called the "annotated commit"
        # in this function) is maintained through a file in the special
        # refs/notes/commits namespace.  The name of that file seems
        # to vary a little bit from case to case (sometimes it is just
        # equal to "%s" % rev, while some other times it is equal to
        # "%s/%s" % (rev[:2], rev[2:]) where rev is the revision of
        # the annotated commit. The one constant is that it is easy
        # to deduce the annotated commit ID, by just stripping the '/'
        # characters.

        # Look at the files modified by the git notes commit via
        # diff-tree. There should be only one, pointing us towards
        # the annotated commit.
        all_changes = git.diff_tree('-r', notes_rev, _split_lines=True)
        if not all_changes:
            # notes_rev is probably the root commit.  Just use the empty
            # tree's sha1 as the reference.
            empty_tree_rev = git.mktree(_input='')
            all_changes = git.diff_tree('-r', empty_tree_rev, notes_rev,
                                        _split_lines=True)

        # The output should be 2 lines...
        #   - The first line contains the hash of what is being compared,
        #     which should be notes_rev;
        #   - The second line contains the file change that interests us.
        # ... except in the case where the notes_rev does not have
        # a parent (first note).  In that case, we diff-tree'ed against
        # the empty tree rev, and the first line is omitted.
        #
        # There is also another situation where the output is more than
        # two lines: Newer version of git sometimes rename some of the
        # files created by older versions of "git notes" during notes
        # updates, and bunches those renamings together with a note
        # update, thus creating commits that actually touch multiple
        # files (N707-041). In that situation, it appears as though
        # the first entry is always the one corresponding to the commit
        # being annotated, so discard anything past the second line.
        all_changes = all_changes[:2]
        assert all_changes

        (_, _, _, _, _, filename) = all_changes[-1].split(None, 5)
        return filename
def check_commit(old_rev, new_rev, project_name):
    """Call check_file for every file changed between old_rev and new_rev.

    Raise InvalidUpdate if one or more style violation are detected.

    PARAMETERS
        old_rev: The commit to be used as a reference to determine
            the list of files that have been modified/added by
            the new commit.  Must be a valid revision.
        new_rev: The commit to be checked.
        project_name: The name of the project (same as the attribute
            in updates.emails.EmailInfo).
    """
    debug('check_commit(old_rev=%s, new_rev=%s)' % (old_rev, new_rev))

    all_changes = git.diff_tree('-r', old_rev, new_rev, _split_lines=True)
    for item in all_changes:
        (old_mode, new_mode, old_sha1, new_sha1, status, filename) \
            = item.split(None, 5)
        debug('diff-tree entry: %s %s %s %s %s %s'
              % (old_mode, new_mode, old_sha1, new_sha1, status, filename),
              level=5)

        if status in ('D'):
            debug('deleted file ignored: %s' % filename, level=2)
        elif new_mode == '160000':
            debug('subproject entry ignored: %s' % filename, level=2)
        else:
            # Note: We treat a file rename as the equivalent of the old
            # file being deleted and the new file being added. This means
            # that we should run the pre-commit checks if applicable.
            # This is why we did not tell the `git diff-tree' command
            # above to detect renames, and why we do not have a special
            # branch for status values starting with `R'.
            check_file(filename, new_sha1, new_rev, project_name)
예제 #3
0
    def files_changed(self):
        """Return the list of files changed by this commit.

        Cache the result in self.__files_changed so that subsequent
        calls to this method do not require calling git again.
        """
        if self.__files_changed is None:
            self.__files_changed = []
            all_changes = git.diff_tree('-r', self.base_rev_for_git(),
                                        self.rev, _split_lines=True)
            for item in all_changes:
                (old_mode, new_mode, old_sha1, new_sha1, status, filename) \
                    = item.split(None, 5)
                debug('diff-tree entry: %s %s %s %s %s %s'
                      % (old_mode, new_mode, old_sha1, new_sha1, status,
                         filename),
                      level=5)
                self.__files_changed.append(filename)
        return self.__files_changed
예제 #4
0
파일: gitcmds.py 프로젝트: dannyfeng/gitGUI
def diff_filenames(*args):
    """Return a list of filenames that have been modified"""
    diff_zstr = git.diff_tree(name_only=True,
                              no_commit_id=True, r=True, z=True, *args)
    return _parse_diff_filenames(diff_zstr)