Ejemplo n.º 1
0
def ok_clean_git(path,
                 annex=None,
                 head_modified=[],
                 index_modified=[],
                 untracked=[],
                 ignore_submodules=False):
    """Verify that under given path there is a clean git repository

    it exists, .git exists, nothing is uncommitted/dirty/staged

    Note
    ----
    Parameters head_modified and index_modified currently work
    in pure git or indirect mode annex only and are ignored otherwise!
    Implementation is yet to do!

    Parameters
    ----------
    path: str or Repo
      in case of a str: path to the repository's base dir;
      Note, that passing a Repo instance prevents detecting annex. This might be
      useful in case of a non-initialized annex, a GitRepo is pointing to.
    annex: bool or None
      explicitly set to True or False to indicate, that an annex is (not)
      expected; set to None to autodetect, whether there is an annex.
      Default: None.
    ignore_submodules: bool
      if True, submodules are not inspected
    """
    # TODO: See 'Note' in docstring

    if isinstance(path, AnnexRepo):
        if annex is None:
            annex = True
        # if `annex` was set to False, but we find an annex => fail
        assert_is(annex, True)
        r = path
    elif isinstance(path, GitRepo):
        if annex is None:
            annex = False
        # explicitly given GitRepo instance doesn't make sense with 'annex' True
        assert_is(annex, False)
        r = path
    else:
        # 'path' is an actual path
        try:
            r = AnnexRepo(path, init=False, create=False)
            if annex is None:
                annex = True
            # if `annex` was set to False, but we find an annex => fail
            assert_is(annex, True)
        except Exception:
            # Instantiation failed => no annex
            try:
                r = GitRepo(path, init=False, create=False)
            except Exception:
                raise AssertionError("Couldn't find an annex or a git "
                                     "repository at {}.".format(path))
            if annex is None:
                annex = False
            # explicitly given GitRepo instance doesn't make sense with
            # 'annex' True
            assert_is(annex, False)

    eq_(sorted(r.untracked_files), sorted(untracked))

    if annex and r.is_direct_mode():
        if head_modified or index_modified:
            lgr.warning("head_modified and index_modified are not quite valid "
                        "concepts in direct mode! Looking for any change "
                        "(staged or not) instead.")
            status = r.get_status(untracked=False,
                                  submodules=not ignore_submodules)
            modified = []
            for s in status:
                modified.extend(status[s])
            eq_(sorted(head_modified + index_modified),
                sorted(f for f in modified))
        else:
            ok_(not r.is_dirty(untracked_files=not untracked,
                               submodules=not ignore_submodules))
    else:
        repo = r.repo

        if repo.index.entries.keys():
            ok_(repo.head.is_valid())

            if not head_modified and not index_modified:
                # get string representations of diffs with index to ease
                # troubleshooting
                head_diffs = [
                    str(d) for d in repo.index.diff(repo.head.commit)
                ]
                index_diffs = [str(d) for d in repo.index.diff(None)]
                eq_(head_diffs, [])
                eq_(index_diffs, [])
            else:
                if head_modified:
                    # we did ask for interrogating changes
                    head_modified_ = [
                        d.a_path for d in repo.index.diff(repo.head.commit)
                    ]
                    eq_(head_modified_, head_modified)
                if index_modified:
                    index_modified_ = [d.a_path for d in repo.index.diff(None)]
                    eq_(index_modified_, index_modified)