Пример #1
0
    def push_submodule(self, project, submodule_url, destination_dir,
                       branch="master", fast_forward=True,
                       message=None):
        """
        Push a submodule to the given project.
        It is assumed that the project has been created.
        """
        src = project.replace(".git", "")
        repo_src = self.src.join(src)
        git = qisrc.git.Git(repo_src.strpath)
        if git.get_current_branch() != branch:
            git.checkout("--force", "-B", branch)
        if not fast_forward:
            git.reset("--hard", "HEAD~1")

        to_write = repo_src.join(destination_dir)
        if to_write.exists():
            raise RuntimeError("path %s already exists" % destination_dir)

        if not message:
            message = "Add submodule %s" % destination_dir

        git.call("submodule", "add", submodule_url, destination_dir)
        git.add(destination_dir)
        git.commit("--message", message)
        if fast_forward:
            git.push("origin", "%s:%s" % (branch, branch))
        else:
            git.push("origin", "--force", "%s:%s" % (branch, branch))
Пример #2
0
def diff_worktree(git_worktree, git_projects, branch, cmd=None):
    """ Run  `git <cmd> local_branch..remote_branch` for every project

    """
    if not cmd:
        cmd = ["log"]
    remote_projects = git_worktree.get_projects_on_branch(branch)
    for git_project in git_projects:
        remote_project = remote_projects.get(git_project.src)
        if not remote_project:
            continue
        git = qisrc.git.Git(git_project.path)
        local_branch = git.get_current_branch()
        remote_branch = remote_project.default_branch.name
        remote_ref = "%s/%s" % (remote_project.default_remote.name, remote_branch)
        rc, out = git.call("merge-base", local_branch, remote_ref, raises=False)
        if rc != 0:
            continue
        merge_base = out.strip()
        full_cmd = cmd + ["%s..%s" % (merge_base, local_branch)]

        color = ui.config_color(sys.stdout)
        if color:
            full_cmd.append("--color=always")
        rc, out = git.call(*full_cmd, raises=False)
        if rc != 0:
            continue
        if not out:
            continue
        ui.info(ui.bold, git_project.src)
        ui.info(ui.bold, "-" * len(git_project.src))
        ui.info(out)
        ui.info()
def test_switching_from_fixed_ref_to_branch_local_changes(
        qisrc_action, git_server, record_messages):
    """ Test Swithcing From Fixed Ref To Branch Local Changes """
    git_server.create_repo("foo.git")
    git_server.push_file("foo.git", "a.txt", "a")
    git_server.push_tag("foo.git", "v0.1")
    git_server.push_file("foo.git", "b.txt", "b")
    git_server.push_tag("foo.git", "v0.2")
    git_server.push_file("foo.git", "c.txt", "c")
    git_server.set_fixed_ref("foo.git", "v0.1")
    qisrc_action("init", git_server.manifest_url)
    git_worktree = TestGitWorkTree()
    foo_proj = git_worktree.get_git_project("foo")
    git = TestGit(foo_proj.path)
    git.write_file("a.txt", "unstaged changes")
    git_server.set_branch("foo.git", "master")
    record_messages.reset()
    rc = qisrc_action("sync", retcode=True)
    # ERROR message must be displayed to warn user
    assert rc != 0
    assert record_messages.find("unstaged changes")
    _, sha1 = git.call("rev-parse", "HEAD", raises=False)
    expected = git.get_ref_sha1("refs/tags/v0.1")
    # git repo unchanged
    assert sha1 == expected
    git.call("reset", "--hard")
    qisrc_action("sync", retcode=True)
    # if modification is revert sync must be successful
    assert git.get_current_branch() == "master"
Пример #4
0
def test_switching_from_fixed_ref_to_branch_local_changes(qisrc_action, git_server, record_messages):
    """ Test Swithcing From Fixed Ref To Branch Local Changes """
    git_server.create_repo("foo.git")
    git_server.push_file("foo.git", "a.txt", "a")
    git_server.push_tag("foo.git", "v0.1")
    git_server.push_file("foo.git", "b.txt", "b")
    git_server.push_tag("foo.git", "v0.2")
    git_server.push_file("foo.git", "c.txt", "c")
    git_server.set_fixed_ref("foo.git", "v0.1")
    qisrc_action("init", git_server.manifest_url)
    git_worktree = TestGitWorkTree()
    foo_proj = git_worktree.get_git_project("foo")
    git = TestGit(foo_proj.path)
    git.write_file("a.txt", "unstaged changes")
    git_server.set_branch("foo.git", "master")
    record_messages.reset()
    rc = qisrc_action("sync", retcode=True)
    # ERROR message must be displayed to warn user
    assert rc != 0
    assert record_messages.find("unstaged changes")
    _, sha1 = git.call("rev-parse", "HEAD", raises=False)
    expected = git.get_ref_sha1("refs/tags/v0.1")
    # git repo unchanged
    assert sha1 == expected
    git.call("reset", "--hard")
    qisrc_action("sync", retcode=True)
    # if modification is revert sync must be successful
    assert git.get_current_branch() == "master"
Пример #5
0
def clever_reset_ref(git_project, ref, raises=True):
    """ Resets only if needed, fetches only if needed """
    try:
        remote_name = git_project.default_remote.name
    except AttributeError:
        error_msg = "Project {} has no default remote, defaulting to origin"
        ui.error(error_msg.format(git_project.name))
        remote_name = "origin"
    git = qisrc.git.Git(git_project.path)
    # Deals with "refs/" prefixed ref first
    if ref.startswith("refs/"):
        return _reset_hard_to_refs_prefixed_ref(git,
                                                remote_name,
                                                ref,
                                                raises=raises)
    # Else, ref format is a local name (branch or tag)
    # Check if this ref exists and if we are already in the expected state
    rc, ref_sha1 = git.call("rev-parse", ref, "--", raises=False)
    if rc != 0:
        # Maybe this is a newly pushed tag, try to fetch:
        git.fetch(remote_name, "--prune")
        rc, ref_sha1 = git.call("rev-parse", ref, "--", raises=False)
        if rc != 0:
            return False, "Could not parse %s as a valid ref" % ref
    _, actual_sha1 = git.call("rev-parse", "HEAD", raises=False)
    if actual_sha1 == ref_sha1:  # Nothing to do
        return None if raises else True, ""
    # Reset to the ref local name
    return _reset_hard_to_local_refs_name(git, remote_name, ref, raises=raises)
Пример #6
0
def stat_tracking_remote(git, branch, tracking):
    """Check if branch is ahead and / or behind tracking."""
    if branch is None or tracking is None:
        return 0, 0
    _, local_ref = git.call("rev-parse", branch, raises=False)
    _, remote_ref = git.call("rev-parse", tracking, raises=False)
    return stat_ahead_behind(git, local_ref, remote_ref)
Пример #7
0
def diff_worktree(git_worktree, git_projects, branch, cmd=None):
    """ Run  `git <cmd> local_branch..remote_branch` for every project

    """
    if not cmd:
        cmd = ["log"]
    remote_projects = git_worktree.get_projects_on_branch(branch)
    for git_project in git_projects:
        remote_project = remote_projects.get(git_project.src)
        if not remote_project:
            continue
        git = qisrc.git.Git(git_project.path)
        local_branch = git.get_current_branch()
        remote_branch = remote_project.default_branch.name
        remote_ref = "%s/%s" % (remote_project.default_remote.name, remote_branch)
        rc, out = git.call("merge-base", local_branch, remote_ref, raises=False)
        if rc != 0:
            continue
        merge_base = out.strip()
        full_cmd = cmd + ["%s..%s" % (merge_base, local_branch)]

        color = ui.config_color(sys.stdout)
        if color:
            full_cmd.append("--color=always")
        rc, out = git.call(*full_cmd, raises=False)
        if rc != 0:
            continue
        if not out:
            continue
        ui.info(ui.bold, git_project.src)
        ui.info(ui.bold, "-" * len(git_project.src))
        ui.info(out)
        ui.info()
Пример #8
0
def _test_switching_to_fixed_ref_happy(qisrc_action, git_server,
                                       record_messages, tag_ref_to_test,
                                       branch_ref_to_test):
    git_server.create_repo("foo.git")
    git_server.push_file("foo.git", "a.txt", "a")
    git_server.push_tag("foo.git", "v0.1")
    git_server.push_file("foo.git", "b.txt", "b")
    git_server.push_branch("foo.git", "feature/b")
    git_server.push_file("foo.git", "c.txt", "c")
    qisrc_action("init", git_server.manifest_url)

    # Check for fixed_ref tag
    git_server.set_fixed_ref("foo.git", tag_ref_to_test)
    qisrc_action("sync")
    git_worktree = TestGitWorkTree()
    foo_proj = git_worktree.get_git_project("foo")
    git = qisrc.git.Git(foo_proj.path)
    _, sha1 = git.call("rev-parse", "HEAD", raises=False)
    expected = git.get_ref_sha1("refs/tags/v0.1")
    assert sha1 == expected
    # qisrc.reset.clever_reset_ref should tell where is the HEAD after reset
    record_messages.reset()
    qisrc_action("sync")
    assert record_messages.find("HEAD is now at")
    assert record_messages.find("Add a.txt")
    _, status_output = git.status(raises=False)
    assert "HEAD" in status_output
    assert "detached" in status_output

    # If branch ref name is local, makesure it exists on local copy, then go back to master
    if branch_ref_to_test == "feature/b":
        git.checkout("feature/b", raises=False)
        git.checkout("master", raises=False)

    # Check for fixed_ref branch
    git_server.set_fixed_ref("foo.git", branch_ref_to_test)
    qisrc_action("sync")
    git_worktree = TestGitWorkTree()
    foo_proj = git_worktree.get_git_project("foo")
    git = qisrc.git.Git(foo_proj.path)
    _, sha1 = git.call("rev-parse", "HEAD", raises=False)
    expected = git.get_ref_sha1("refs/remotes/origin/feature/b")
    assert sha1 == expected
    # qisrc.reset.clever_reset_ref should tell where is the HEAD after reset
    record_messages.reset()
    qisrc_action("sync")
    assert record_messages.find("HEAD is now at")
    assert record_messages.find("Add b.txt")
    _, status_output = git.status(raises=False)

    # FIXME: when using ref long name branch (refs/xxx), if we come from a tag, we stay in a detached head,
    # and we should be in an attached head state to be consistent with the ref short name branc behaviour
    # That's not an issue for now as users reference short name in manifest, but it will be cleaner to be consistent...
    if not branch_ref_to_test.startswith("refs/"):
        assert "HEAD" not in status_output
        assert "detached" not in status_output
    else:
        # Remove these assert when dealing with behaviour consistency mentionned above
        assert "HEAD" in status_output
        assert "detached" in status_output
Пример #9
0
def clever_reset_ref(git_project, ref, raises=True):
    """ Resets only if needed, fetches only if needed """
    try:
        remote_name = git_project.default_remote.name
    except AttributeError:
        error_msg = "Project {} has no default remote, defaulting to origin"
        ui.error(error_msg.format(git_project.name))
        remote_name = "origin"
    git = qisrc.git.Git(git_project.path)
    # Deals with "refs/" prefixed ref first
    if ref.startswith("refs/"):
        return _reset_hard_to_refs_prefixed_ref(git, remote_name, ref, raises=raises)
    # Else, ref format is a local name (branch or tag)
    # Check if this ref exists and if we are already in the expected state
    rc, ref_sha1 = git.call("rev-parse", ref, "--", raises=False)
    if rc != 0:
        # Maybe this is a newly pushed tag, try to fetch:
        git.fetch(remote_name)
        rc, ref_sha1 = git.call("rev-parse", ref, "--", raises=False)
        if rc != 0:
            return False, "Could not parse %s as a valid ref" % ref
    _, actual_sha1 = git.call("rev-parse", "HEAD", raises=False)
    if actual_sha1 == ref_sha1:  # Nothing to do
        return None if raises else True, ""
    # Reset to the ref local name
    return _reset_hard_to_local_refs_name(git, remote_name, ref, raises=raises)
Пример #10
0
def stat_tracking_remote(git, branch, tracking):
    """ Check if branch is ahead and / or behind tracking. """
    if branch is None or tracking is None:
        return 0, 0
    _, local_ref = git.call("rev-parse", branch, raises=False)
    _, remote_ref = git.call("rev-parse", tracking, raises=False)
    return stat_ahead_behind(git, local_ref, remote_ref)
Пример #11
0
 def push_branch(self, project, branch):
     """ push branch on project """
     src = project.replace(".git", "")
     repo_src = self.src.join(src)
     git = qisrc.git.Git(repo_src.strpath)
     # create the branch
     git.call("branch", branch)
     git.push("origin", branch)
Пример #12
0
 def delete_file(self, project, filename):
     """ Delete a file from the repository """
     src = project.replace(".git", "")
     repo_src = self.src.join(src)
     git = qisrc.git.Git(repo_src.strpath)
     git.call("rm", filename)
     git.commit("--message", "remove %s" % filename)
     git.push("origin", "master:master")
Пример #13
0
 def push_branch(self, project, branch):
     """ push branch on project """
     src = project.replace(".git", "")
     repo_src = self.src.join(src)
     git = qisrc.git.Git(repo_src.strpath)
     # create the branch
     git.call("branch", branch)
     git.push("origin", branch)
Пример #14
0
 def delete_file(self, project, filename):
     """ Delete a file from the repository """
     src = project.replace(".git", "")
     repo_src = self.src.join(src)
     git = qisrc.git.Git(repo_src.strpath)
     git.call("rm", filename)
     git.commit("--message", "remove %s" % filename)
     git.push("origin", "master:master")
Пример #15
0
def _test_switching_to_fixed_ref_happy(qisrc_action, git_server, record_messages, tag_ref_to_test, branch_ref_to_test):
    """ Test Switching To Fixed Ref Happy """
    git_server.create_repo("foo.git")
    git_server.push_file("foo.git", "a.txt", "a")
    git_server.push_tag("foo.git", "v0.1")
    git_server.push_file("foo.git", "b.txt", "b")
    git_server.push_branch("foo.git", "feature/b")
    git_server.push_file("foo.git", "c.txt", "c")
    qisrc_action("init", git_server.manifest_url)
    # Check for fixed_ref tag
    git_server.set_fixed_ref("foo.git", tag_ref_to_test)
    qisrc_action("sync")
    git_worktree = TestGitWorkTree()
    foo_proj = git_worktree.get_git_project("foo")
    git = qisrc.git.Git(foo_proj.path)
    _, sha1 = git.call("rev-parse", "HEAD", raises=False)
    expected = git.get_ref_sha1("refs/tags/v0.1")
    assert sha1 == expected
    # qisrc.reset.clever_reset_ref should tell where is the HEAD after reset
    record_messages.reset()
    qisrc_action("sync")
    assert record_messages.find("HEAD is now at")
    assert record_messages.find("Add a.txt")
    _, status_output = git.status(raises=False)
    assert "HEAD" in status_output
    assert "detached" in status_output
    # If branch ref name is local, makesure it exists on local copy, then go back to master
    if branch_ref_to_test == "feature/b":
        git.checkout("feature/b", raises=False)
        git.checkout("master", raises=False)
    # Check for fixed_ref branch
    git_server.set_fixed_ref("foo.git", branch_ref_to_test)
    qisrc_action("sync")
    git_worktree = TestGitWorkTree()
    foo_proj = git_worktree.get_git_project("foo")
    git = qisrc.git.Git(foo_proj.path)
    _, sha1 = git.call("rev-parse", "HEAD", raises=False)
    expected = git.get_ref_sha1("refs/remotes/origin/feature/b")
    assert sha1 == expected
    # qisrc.reset.clever_reset_ref should tell where is the HEAD after reset
    record_messages.reset()
    qisrc_action("sync")
    assert record_messages.find("HEAD is now at")
    assert record_messages.find("Add b.txt")
    _, status_output = git.status(raises=False)
    # FIXME: when using ref long name branch (refs/xxx), if we come from a tag, we stay in a detached head,
    # and we should be in an attached head state to be consistent with the ref short name branc behaviour
    # That's not an issue for now as users reference short name in manifest, but it will be cleaner to be consistent...
    if not branch_ref_to_test.startswith("refs/"):
        assert "HEAD" not in status_output
        assert "detached" not in status_output
    else:
        # Remove these assert when dealing with behaviour consistency mentionned above
        assert "HEAD" in status_output
        assert "detached" in status_output
Пример #16
0
def test_fixed_ref_behind(qisrc_action, git_server, record_messages):
    git_server.create_repo("foo.git")
    git_server.push_file("foo.git", "a.txt", "a")
    git_server.push_tag("foo.git", "v0.1")
    git_server.set_fixed_ref("foo.git", "v0.1")
    qisrc_action("init", git_server.manifest_url)
    git_worktree = TestGitWorkTree()
    foo_proj = git_worktree.get_git_project("foo")
    git = qisrc.git.Git(foo_proj.path)
    git.call("reset", "--hard", "HEAD~1")
    qisrc_action("status")
    assert record_messages.find("fixed ref v0.1 -1")
Пример #17
0
def test_fixed_ref_behind(qisrc_action, git_server, record_messages):
    """ Test Fixed Ref Behind """
    git_server.create_repo("foo.git")
    git_server.push_file("foo.git", "a.txt", "a")
    git_server.push_tag("foo.git", "v0.1")
    git_server.set_fixed_ref("foo.git", "v0.1")
    qisrc_action("init", git_server.manifest_url)
    git_worktree = TestGitWorkTree()
    foo_proj = git_worktree.get_git_project("foo")
    git = qisrc.git.Git(foo_proj.path)
    git.call("reset", "--hard", "HEAD~1")
    qisrc_action("status")
    assert record_messages.find("fixed ref v0.1 -1")
Пример #18
0
def test_git_get_local_branches(tmpdir):
    tmpdir = tmpdir.strpath
    git = qisrc.git.Git(tmpdir)
    # pylint: disable-msg=E1101
    with pytest.raises(Exception):
        git.get_local_branches()
    write_readme(tmpdir, "readme\n")
    git.call("init")
    git.call("add", ".")
    git.commit("-m", "initial commit")
    assert git.get_local_branches() == ["master"]
    git.checkout("-b", "devel")
    assert git.get_local_branches() == ["devel", "master"]
Пример #19
0
def stat_tracking_remote(git, branch, tracking):
    """Check if branch is ahead and / or behind tracking."""
    behind = 0
    ahead = 0
    (ret, out) = git.call("rev-list", "--left-right",
                          "%s..%s" % (tracking, branch), raises=False)
    if ret == 0:
        ahead = len(out.split())
    (ret, out) = git.call("rev-list", "--left-right",
                          "%s..%s" % (branch, tracking), raises=False)
    if ret == 0:
        behind = len(out.split())
    return (ahead, behind)
Пример #20
0
def stat_tracking_remote(git, branch, tracking):
    """Check if branch is ahead and / or behind tracking."""
    behind = 0
    ahead = 0
    (ret, out) = git.call("rev-list", "--left-right",
                          "%s..%s" % (tracking, branch), raises=False)
    if ret == 0:
        ahead = len(out.split())
    (ret, out) = git.call("rev-list", "--left-right",
                          "%s..%s" % (branch, tracking), raises=False)
    if ret == 0:
        behind = len(out.split())
    return (ahead, behind)
Пример #21
0
def test_new_project_under_review(tmpdir, git_server):
    foo_repo = git_server.create_repo("foo.git", review=False)
    assert foo_repo.review is False
    git_server.use_review("foo.git")
    foo_repo = git_server.get_repo("foo.git")
    assert foo_repo.review is True
    assert foo_repo.review_remote.name == "gerrit"
    git = qisrc.git.Git(tmpdir.strpath)
    rc, out = git.call("ls-remote", foo_repo.clone_url, raises=False)
    assert rc == 0
    git = qisrc.git.Git(tmpdir.strpath)
    rc, out = git.call("ls-remote", foo_repo.review_remote.url, raises=False)
    assert rc == 0
Пример #22
0
def test_new_project_under_review(tmpdir, git_server):
    foo_repo = git_server.create_repo("foo.git", review=False)
    assert foo_repo.review is False
    git_server.use_review("foo.git")
    foo_repo = git_server.get_repo("foo.git")
    assert foo_repo.review is True
    assert foo_repo.review_remote.name == "gerrit"
    git = qisrc.git.Git(tmpdir.strpath)
    rc, out = git.call("ls-remote", foo_repo.clone_url, raises=False)
    assert rc == 0
    git = qisrc.git.Git(tmpdir.strpath)
    rc, out = git.call("ls-remote", foo_repo.review_remote.url, raises=False)
    assert rc == 0
Пример #23
0
def clever_reset_ref(git_project, ref, raises=True):
    """ Resets only if needed, fetches only if needed """
    try:
        remote_name = git_project.default_remote.name
    except AttributeError:
        error_msg = "Project {} has no default remote, defaulting to origin"
        ui.error(error_msg.format(git_project.name))
        remote_name = "origin"

    git = qisrc.git.Git(git_project.path)
    if ref.startswith("refs/"):
        if raises:
            git.fetch(remote_name, ref)
            git.reset("--hard", "FETCH_HEAD")
            return
        else:
            with git.tansaction() as transaction:
                git.fetch(remote_name, ref)
                git.reset("--hard", "FETCH_HEAD")
                return transaction.ok, transaction.output

    rc, ref_sha1 = git.call("rev-parse", ref, raises=False)
    if rc != 0:
        # Maybe this is a newly pushed tag, try to fetch:
        git.fetch(remote_name)
        rc, ref_sha1 = git.call("rev-parse", ref, raises=False)
        if rc != 0:
            return False, "Could not parse %s as a valid ref" % ref
    _, actual_sha1 = git.call("rev-parse", "HEAD", raises=False)
    if actual_sha1 == ref_sha1:  # Nothing to do
        if raises:
            return
        else:
            return True, ""
    ret, _ = git.call("show", "--oneline", ref, raises=False)
    if ret == 0:  # SHA-1 exists locally
        if raises:
            git.reset("--hard", ref)
        else:
            rc, out = git.reset("--hard", ref, raises=False)
            return (rc == 0), out
    else:  # Full fetch in this case
        if raises:
            git.fetch(remote_name)
            git.reset("--hard", ref)
        else:
            with git.transaction() as transaction:
                git.fetch(remote_name)
                git.reset("--hard", ref)
            return transaction.ok, transaction.output
Пример #24
0
 def push_tag(self, project, tag, branch="master", fast_forward=True):
     """ push tag on project """
     src = project.replace(".git", "")
     repo_src = self.src.join(src)
     git = qisrc.git.Git(repo_src.strpath)
     if git.get_current_branch() != branch:
         git.checkout("--force", "-B", branch)
     if not fast_forward:
         git.reset("--hard", "HEAD~1")
     # tag the branch
     git.call("tag", tag)
     if fast_forward:
         git.push("origin", tag)
     else:
         git.push("origin", "--force", tag)
Пример #25
0
 def push_tag(self, project, tag, branch="master", fast_forward=True):
     """ push tag on project """
     src = project.replace(".git", "")
     repo_src = self.src.join(src)
     git = qisrc.git.Git(repo_src.strpath)
     if git.get_current_branch() != branch:
         git.checkout("--force", "-B", branch)
     if not fast_forward:
         git.reset("--hard", "HEAD~1")
     # tag the branch
     git.call("tag", tag)
     if fast_forward:
         git.push("origin", tag)
     else:
         git.push("origin", "--force", tag)
Пример #26
0
 def __str__(self):
     """ String Representation of the Toochain """
     git_path = qisys.sh.get_share_path("qi", "toolchains", self.name + ".git")
     sha1 = None
     if os.path.exists(git_path):
         git = qisrc.git.Git(git_path)
         _, sha1 = git.call("rev-parse", "HEAD", raises=False)
     res = "Toolchain %s\n" % self.name
     if self.feed_url:
         res += "Using feed from %s" % self.feed_url
         if self.feed_name:
             res += " (feeds/%s.xml)" % self.feed_name
         if self.feed_branch:
             res += " on %s" % self.feed_branch
         if sha1:
             res += " - %s" % sha1[:8]
         res += "\n"
     else:
         res += "No feed\n"
     if self.packages:
         res += "  Packages:\n"
     else:
         res += "No packages\n"
     sorted_packages = sorted(self.packages)
     for package in sorted_packages:
         res += ui.indent(package.name, 2)
         if package.version:
             res += " " + package.version
         res += "\n"
         if package.path:
             res += ui.indent("in " + package.path, 3) + "\n"
     return res
Пример #27
0
 def __str__(self):
     """ String Representation of the Toochain """
     git_path = qisys.sh.get_share_path("qi", "toolchains", self.name + ".git")
     sha1 = None
     if os.path.exists(git_path):
         git = qisrc.git.Git(git_path)
         _, sha1 = git.call("rev-parse", "HEAD", raises=False)
     res = "Toolchain %s\n" % self.name
     if self.feed_url:
         res += "Using feed from %s" % self.feed_url
         if self.feed_name:
             res += " (feeds/%s.xml)" % self.feed_name
         if self.feed_branch:
             res += " on %s" % self.feed_branch
         if sha1:
             res += " - %s" % sha1[:8]
         res += "\n"
     else:
         res += "No feed\n"
     if self.packages:
         res += "  Packages:\n"
     else:
         res += "No packages\n"
     sorted_packages = sorted(self.packages)
     for package in sorted_packages:
         res += ui.indent(package.name, 2)
         if package.version:
             res += " " + package.version
         res += "\n"
         if package.path:
             res += ui.indent("in " + package.path, 3) + "\n"
     return res
Пример #28
0
 def _sync_git(repo, url, branch, ref):
     """ Sync Git """
     git = qisrc.git.Git(repo)
     git.set_remote("origin", url)
     if git.get_current_branch() != branch:
         git.checkout("-B", branch)
     with git.transaction() as transaction:
         git.call("remote", "update", "--prune", "origin")
         git.fetch("origin")
         if ref:
             to_reset = ref
             git.reset("--hard", to_reset)
         else:
             git.reset("--hard", "origin/%s" % branch)
     if not transaction.ok:
         raise Exception("Update failed\n" + transaction.output)
Пример #29
0
def test_create_empty_repo(tmpdir, git_server):
    """ Test Create Empty Repo """
    foo_repo = git_server.create_repo("foo", empty=True)
    git = qisrc.git.Git(tmpdir.strpath)
    rc, out = git.call("ls-remote", foo_repo.clone_url, raises=False)
    assert rc == 0
    assert not out
Пример #30
0
def test_displays_git_info(tmpdir, git_server, feed, qitoolchain_action):
    boost_package = qitoolchain.qipackage.QiPackage("boost", version="1.44")
    feed.add_package(boost_package)
    git_server.create_repo("toolchains.git")
    git_server.change_branch("toolchains.git", "devel")
    git_server.push_file("toolchains.git",
                         "feeds/bar.xml",
                         feed.feed_xml.read(),
                         branch="devel")

    feed_url = git_server.get_repo("toolchains.git").clone_url

    git = qisrc.git.Git(tmpdir.strpath)
    _, out = git.call("ls-remote", feed_url, "devel", raises=False)
    devel_sha1 = out.split()[0][:8]

    qitoolchain_action("create", "--feed-name", "bar", "--branch", "devel",
                       "foo", feed_url)
    foo_tc = qitoolchain.get_toolchain("foo")
    as_str = str(foo_tc)
    print as_str
    assert "on devel" in as_str
    assert "(feeds/bar.xml)" in as_str
    assert "from %s" % feed_url in as_str
    assert devel_sha1 in as_str
Пример #31
0
def test_qisrc_checkout_with_branch_to_ref(qisrc_action, git_server):
    """ Test QiSrc Checkout With Branch to Ref """
    manifest_url = git_server.manifest_url
    git_server.create_repo("foo.git")
    git_server.create_repo("bar.git")
    git_server.push_file("foo.git", "a.txt", "a")
    git_server.push_tag("foo.git", "v0.1")
    git_server.push_file("foo.git", "b.txt", "b")
    git_server.push_tag("bar.git", "v0.2")
    git_server.push_file("bar.git", "c.txt", "b")
    qisrc_action("init", manifest_url)
    git_server.switch_manifest_branch("devel")
    git_server.set_fixed_ref("foo.git", "v0.1")
    git_server.set_fixed_ref("bar.git", "v0.2")
    git_worktree = TestGitWorkTree()
    foo_proj = git_worktree.get_git_project("foo")
    git = TestGit(foo_proj.path)
    assert git.get_current_branch() == "master"
    qisrc_action("checkout", "devel")
    _, sha1 = git.call("rev-parse", "HEAD", raises=False)
    expected = git.get_ref_sha1("refs/tags/v0.1")
    assert sha1 == expected
    bar_proj = git_worktree.get_git_project("bar")
    bar_git = qisrc.git.Git(bar_proj.path)
    _, sha1 = bar_git.call("rev-parse", "HEAD", raises=False)
    expected = bar_git.get_ref_sha1("refs/tags/v0.2")
    assert sha1 == expected
Пример #32
0
def test_create_review_repos(tmpdir, git_server):
    foo_repo = git_server.create_repo("foo", review=True)
    assert foo_repo.review_remote.name == "gerrit"
    assert foo_repo.default_remote.name == "origin"
    git = qisrc.git.Git(tmpdir.strpath)
    rc, out = git.call("ls-remote", foo_repo.clone_url, raises=False)
    assert rc == 0
Пример #33
0
def test_qisrc_checkout_with_branch_to_ref(qisrc_action, git_server):
    """ Test QiSrc Checkout With Branch to Ref """
    manifest_url = git_server.manifest_url
    git_server.create_repo("foo.git")
    git_server.create_repo("bar.git")
    git_server.push_file("foo.git", "a.txt", "a")
    git_server.push_tag("foo.git", "v0.1")
    git_server.push_file("foo.git", "b.txt", "b")
    git_server.push_tag("bar.git", "v0.2")
    git_server.push_file("bar.git", "c.txt", "b")
    qisrc_action("init", manifest_url)
    git_server.switch_manifest_branch("devel")
    git_server.set_fixed_ref("foo.git", "v0.1")
    git_server.set_fixed_ref("bar.git", "v0.2")
    git_worktree = TestGitWorkTree()
    foo_proj = git_worktree.get_git_project("foo")
    git = TestGit(foo_proj.path)
    assert git.get_current_branch() == "master"
    qisrc_action("checkout", "devel")
    _, sha1 = git.call("rev-parse", "HEAD", raises=False)
    expected = git.get_ref_sha1("refs/tags/v0.1")
    assert sha1 == expected
    bar_proj = git_worktree.get_git_project("bar")
    bar_git = qisrc.git.Git(bar_proj.path)
    _, sha1 = bar_git.call("rev-parse", "HEAD", raises=False)
    expected = bar_git.get_ref_sha1("refs/tags/v0.2")
    assert sha1 == expected
Пример #34
0
def test_create_review_repos(tmpdir, git_server):
    foo_repo = git_server.create_repo("foo", review=True)
    assert foo_repo.review_remote.name == "gerrit"
    assert foo_repo.default_remote.name == "origin"
    git = qisrc.git.Git(tmpdir.strpath)
    rc, out = git.call("ls-remote", foo_repo.clone_url, raises=False)
    assert rc == 0
Пример #35
0
 def snapshot(self):
     """ Return a :py:class`.Snapshot` of the current worktree state """
     snapshot = qisrc.snapshot.Snapshot()
     snapshot.manifest = self.manifest
     git = qisrc.git.Git(self.syncer.manifest_repo)
     rc, out = git.call("rev-parse", "HEAD", raises=False)
     snapshot.manifest.ref = out
     for git_project in self.git_projects:
         src = git_project.src
         git = qisrc.git.Git(git_project.path)
         rc, out = git.call("rev-parse", "HEAD", raises=False)
         if rc != 0:
             ui.error("git rev-parse HEAD failed for", src)
             continue
         snapshot.refs[src] = out.strip()
     return snapshot
Пример #36
0
def test_create_empty_repo(tmpdir, git_server):
    """ Test Create Empty Repo """
    foo_repo = git_server.create_repo("foo", empty=True)
    git = qisrc.git.Git(tmpdir.strpath)
    rc, out = git.call("ls-remote", foo_repo.clone_url, raises=False)
    assert rc == 0
    assert not out
Пример #37
0
def stat_ahead_behind(git, local_ref, remote_ref):
    """
    Returns a tuple (ahead, behind) describing how far
    from the remote ref the local ref is.
    """
    behind = 0
    ahead = 0
    (ret, out) = git.call("rev-list", "--left-right",
                          "%s..%s" % (remote_ref, local_ref), raises=False)
    if ret == 0:
        ahead = len(out.split())
    (ret, out) = git.call("rev-list", "--left-right",
                          "%s..%s" % (local_ref, remote_ref), raises=False)
    if ret == 0:
        behind = len(out.split())
    return ahead, behind
Пример #38
0
def stat_ahead_behind(git, local_ref, remote_ref):
    """ Returns a tuple (ahead, behind) describing how far
    from the remote ref the local ref is

    """
    behind = 0
    ahead = 0
    (ret, out) = git.call("rev-list", "--left-right",
                          "%s..%s" % (remote_ref, local_ref), raises=False)
    if ret == 0:
        ahead = len(out.split())
    (ret, out) = git.call("rev-list", "--left-right",
                          "%s..%s" % (local_ref, remote_ref), raises=False)
    if ret == 0:
        behind = len(out.split())
    return (ahead, behind)
Пример #39
0
def test_with_git(qisrc_action):
    qisrc_action("create", "foo", "--git")
    worktree = TestWorkTree()
    foo_proj = worktree.get_project("foo")
    git = qisrc.git.Git(foo_proj.path)
    ret, out = git.call("show", "HEAD", raises=False)
    assert ret == 0
    assert ".gitignore" in out
Пример #40
0
def test_with_git(qisrc_action):
    qisrc_action("create", "foo", "--git")
    worktree = TestWorkTree()
    foo_proj = worktree.get_project("foo")
    git = qisrc.git.Git(foo_proj.path)
    ret, out = git.call("show", "HEAD", raises=False)
    assert ret == 0
    assert ".gitignore" in out
Пример #41
0
    def snapshot(self):
        """ Return a :py:class`.Snapshot` of the current worktree state

        """
        snapshot = qisrc.snapshot.Snapshot()
        snapshot.manifest = self.manifest
        git = qisrc.git.Git(self._syncer.manifest_repo)
        rc, out = git.call("rev-parse", "HEAD", raises=False)
        snapshot.manifest.ref = out
        for git_project in self.git_projects:
            src = git_project.src
            git = qisrc.git.Git(git_project.path)
            rc, out = git.call("rev-parse", "HEAD", raises=False)
            if rc != 0:
                ui.error("git rev-parse HEAD failed for", src)
                continue
            snapshot.refs[src] = out.strip()
        return snapshot
Пример #42
0
def diff_worktree(git_worktree, git_projects, branch, cmd=None):  # pylint: disable=too-many-locals
    """ Run  `git <cmd> local_branch..remote_branch` for every project

    """
    if not cmd:
        cmd = ["log"]
    remote_projects = git_worktree.get_projects_on_branch(branch)
    for git_project in git_projects:
        remote_project = remote_projects.get(git_project.src)
        if not remote_project:
            continue
        git = qisrc.git.Git(git_project.path)
        local_branch = git.get_current_branch()
        if not local_branch:
            message = (ui.brown, "Not on a branch")
        else:
            remote_branch = remote_project.default_branch.name
            remote_ref = "%s/%s" % (remote_project.default_remote.name,
                                    remote_branch)
            rc, out = git.call("merge-base",
                               local_branch,
                               remote_ref,
                               raises=False)
            if rc != 0:
                message = (ui.red, "Calling git merge-base failed")
            else:
                merge_base = out.strip()
                full_cmd = cmd + ["%s..%s" % (merge_base, local_branch)]

                color = ui.config_color(sys.stdout)
                if color:
                    full_cmd.append("--color=always")
                rc, out = git.call(*full_cmd, raises=False)
                if rc != 0:
                    message = (ui.red, "Calling git log failed")
                else:
                    if out:
                        message = (out, )
                    else:
                        continue
        ui.info(ui.bold, git_project.src)
        ui.info(ui.bold, "-" * len(git_project.src))
        ui.info(*message)
        ui.info()
Пример #43
0
def _reset_hard_to_local_refs_name(git, remote_name, ref, raises=True):
    """ deals with the git reset --hard command for short name ref (NOT on the format 'refs/xxx') """
    need_to_fetch, _ = git.call("show", "--oneline", ref, "--", raises=False)
    if need_to_fetch:
        git.fetch(remote_name, "--tags")
    # else: SHA-1 already exists locally, no need to fetch
    _, tag_list = git.tag("-l", ref, raises=False)
    is_tag = ref == tag_list
    # Perform effective switch
    rc, out = _switch_to_git_ref(git, ref, is_tag)
    return None if raises else (rc == 0), out
Пример #44
0
def _reset_hard_to_local_refs_name(git, remote_name, ref, raises=True):
    """ deals with the git reset --hard command for short name ref (NOT on the format 'refs/xxx') """
    need_to_fetch, _ = git.call("show", "--oneline", ref, "--", raises=False)
    if need_to_fetch:
        git.fetch(remote_name, "--tags", "--prune")
    # else: SHA-1 already exists locally, no need to fetch
    _, tag_list = git.tag("-l", ref, raises=False)
    is_tag = ref == tag_list
    # Perform effective switch
    rc, out = _switch_to_git_ref(git, ref, is_tag)
    return None if raises else (rc == 0), out
Пример #45
0
def test_git_version(qibuild_action):
    proj = qibuild_action.add_test_project("gitversion")
    git = qisrc.git.Git(proj.path)
    git.call("init")
    git.call("add", ".")
    git.call("commit", "--message", "initial commit")
    git.call("tag", "v0.1")
    qibuild_action("configure", "gitversion")
    qibuild_action("make", "gitversion")
    testversion = qibuild.find.find_bin([proj.sdk_directory], "testversion")
    process = subprocess.Popen(testversion, stdout=subprocess.PIPE)
    out, _ = process.communicate()
    assert out.strip() == "v0.1"
Пример #46
0
def test_git_version(qibuild_action):
    proj = qibuild_action.add_test_project("gitversion")
    git = qisrc.git.Git(proj.path)
    git.call("init")
    git.call("add", ".")
    git.call("commit", "--message", "initial commit")
    git.call("tag", "v0.1")
    qibuild_action("configure", "gitversion")
    qibuild_action("make", "gitversion")
    testversion = qibuild.find.find_bin([proj.sdk_directory], "testversion")
    process = subprocess.Popen(testversion, stdout=subprocess.PIPE)
    out, _ = process.communicate()
    assert out.strip() == "v0.1"
Пример #47
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("version")
    args = parser.parse_args()
    version = args.version
    this_dir = os.path.dirname(__file__)
    qibuild_root = os.path.join(this_dir, "..")
    git = qisrc.git.Git(qibuild_root)
    ok, message = git.require_clean_worktree()
    if not ok:
        raise Exception(message)
    for filename in FILES_TO_PATCH:
        full_path = os.path.join(qibuild_root, filename)
        fix_version_for_file(full_path, "next", version)
    git.commit("--all", "-m", "qibuild %s" % version)
    git.call("tag", "v" + version)
    for filename in FILES_TO_PATCH:
        full_path = os.path.join(qibuild_root, filename)
        fix_version_for_file(filename, version, "next")
    git.commit("--all", "-m", "start next development")
    print "All OK feel free to push"
Пример #48
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("version")
    args = parser.parse_args()
    version = args.version
    this_dir = os.path.dirname(__file__)
    qibuild_root = os.path.join(this_dir, "..")
    git = qisrc.git.Git(qibuild_root)
    ok, message = git.require_clean_worktree()
    if not ok:
        raise Exception(message)
    for filename in FILES_TO_PATCH:
        full_path = os.path.join(qibuild_root, filename)
        fix_version_for_file(full_path, "next", version)
    git.commit("--all", "-m", "qibuild %s" % version)
    git.call("tag", "v" + version)
    for filename in FILES_TO_PATCH:
        full_path = os.path.join(qibuild_root, filename)
        fix_version_for_file(filename, version, "next")
    git.commit("--all", "-m", "start next development")
    print "All OK feel free to push"
Пример #49
0
def test_is_ff(tmpdir):
    a_git = tmpdir.mkdir("a_git_project")
    a_src = a_git.strpath

    git = qisrc.git.Git(a_src)
    git.init()
    write_readme(a_src, "readme\n")
    git.add(".")
    git.commit("-m", "initial commit")
    git.call("branch", "A")

    write_readme(a_src, "readme2\n")
    git.add(".")
    git.commit("-m", "second commit")
    git.call("branch", "B")

    (ret, out) = git.call("show-ref", "--verify", "refs/heads/A", raises=False)
    A_sha1 = out.split()[0]
    (ret, out) = git.call("show-ref", "--verify", "refs/heads/B", raises=False)
    B_sha1 = out.split()[0]

    class Status:
        pass
    status = Status()
    status.mess = ""
    assert qisrc.git.is_ff(git, status, A_sha1, B_sha1) == True
    assert qisrc.git.is_ff(git, status, B_sha1, A_sha1) == False
    assert qisrc.git.is_ff(git, status, A_sha1, A_sha1) == True
Пример #50
0
def do(args):
    """Main entry point."""
    git_worktree = qisrc.parsers.get_git_worktree(args)
    git_projects = qisrc.parsers.get_git_projects(git_worktree,
                                                  args,
                                                  default_all=True,
                                                  use_build_deps=args.use_deps)
    git_grep_opts = args.git_grep_opts
    if args.path == 'none':
        git_grep_opts.append("-h")
    else:
        git_grep_opts.append("-H")
        if args.path == 'absolute' or args.path == 'worktree':
            git_grep_opts.append("-I")
            git_grep_opts.append("--null")
    if ui.config_color(sys.stdout):
        git_grep_opts.append("--color=always")
    git_grep_opts.append(args.pattern)

    if not git_projects:
        qisrc.worktree.on_no_matching_projects(git_worktree,
                                               groups=args.groups)
        sys.exit(0)

    max_src = max(len(x.src) for x in git_projects)
    retcode = 1
    for i, project in enumerate(git_projects):
        ui.info_count(i,
                      len(git_projects),
                      ui.green,
                      "Looking in",
                      ui.blue,
                      project.src.ljust(max_src),
                      end="\r")
        git = qisrc.git.Git(project.path)
        (status, out) = git.call("grep", *git_grep_opts, raises=False)
        if out != "":
            if args.path == 'absolute' or args.path == 'worktree':
                lines = out.splitlines()
                out_lines = list()
                for line in lines:
                    line_split = line.split('\0')
                    prepend = project.src if args.path == 'worktree' else project.path
                    line_split[0] = os.path.join(prepend, line_split[0])
                    out_lines.append(":".join(line_split))
                out = '\n'.join(out_lines)
            ui.info("\n", ui.reset, out)
        if status == 0:
            retcode = 0
    if not out:
        ui.info(ui.reset)
    sys.exit(retcode)
Пример #51
0
def test_gen_scm_info(build_worktree, tmpdir):
    build_worktree.add_test_project("world")
    hello_proj = build_worktree.add_test_project("hello")
    git = qisrc.git.Git(hello_proj.path)
    git.init()
    git.add(".")
    git.commit("--message", "initial commit")
    rc, sha1 = git.call("rev-parse", "HEAD", raises=False)
    package_xml = tmpdir.join("package.xml").strpath
    hello_proj.gen_package_xml(package_xml)
    tree = qisys.qixml.read(package_xml)
    scm_elem = tree.find("scm")
    git_elem = scm_elem.find("git")
    assert git_elem.get("revision") == sha1
Пример #52
0
def test_gen_scm_info(build_worktree, tmpdir):
    build_worktree.add_test_project("world")
    hello_proj = build_worktree.add_test_project("hello")
    git = qisrc.git.Git(hello_proj.path)
    git.init()
    git.add(".")
    git.commit("--message", "initial commit")
    rc, sha1 = git.call("rev-parse", "HEAD", raises=False)
    package_xml = tmpdir.join("package.xml").strpath
    hello_proj.gen_package_xml(package_xml)
    tree = qisys.qixml.read(package_xml)
    scm_elem = tree.find("scm")
    git_elem = scm_elem.find("git")
    assert git_elem.get("revision") == sha1
Пример #53
0
def test_tags(qisrc_action, git_server):
    """ Test Tags """
    git_server.create_repo("foo.git")
    git_server.push_file("foo.git", "a.txt", "a")
    git_server.push_tag("foo.git", "v0.1")
    git_server.push_file("foo.git", "b.txt", "b")
    git_server.set_fixed_ref("foo.git", "v0.1")
    qisrc_action("init", git_server.manifest_url)
    git_worktree = TestGitWorkTree()
    foo_proj = git_worktree.get_git_project("foo")
    git = TestGit(foo_proj.path)
    _, sha1 = git.call("rev-parse", "HEAD", raises=False)
    expected = git.get_ref_sha1("refs/tags/v0.1")
    assert sha1 == expected
Пример #54
0
def open_git_feed(toolchain_name, feed_url, name=None, branch="master", first_pass=True):
    """ Open a Git Feed """
    git_path = qisys.sh.get_share_path("qi", "toolchains", toolchain_name + ".git")
    git = qisrc.git.Git(git_path)
    if first_pass:
        if os.path.exists(git_path):
            git.call("remote", "set-url", "origin", feed_url)
            git.call("remote", "update", "--prune", "origin")
            git.call("fetch", "origin", "--quiet")
            git.call("reset", "--hard", "--quiet", "origin/%s" % branch)
        else:
            git.clone(feed_url, "--quiet", "--branch", branch)
        feed_path = os.path.join(git_path, "feeds", name + ".xml")
    else:
        feed_path = feed_url
    return feed_path
Пример #55
0
def clever_reset_ref(git_project, ref):
    """ Resets only if needed, fetches only if needed """
    try:
        remote_name = git_project.default_remote.name
    except AttributeError:
        error_msg = "Project {} has no default remote, defaulting to origin"
        ui.error(error_msg.format(git_project.name))
        remote_name = "origin"

    git = qisrc.git.Git(git_project.path)
    if ref.startswith("refs/"):
        git.fetch(remote_name, ref)
        git.reset("--hard", "FETCH_HEAD")
        return
    _, actual_sha1 = git.call("rev-parse", "HEAD", raises=False)
    if actual_sha1 == ref:  # Nothing to do
        return
    ret, _ = git.call("show", "--oneline", ref, raises=False)
    if ret == 0:  # SHA-1 exists locally
        git.reset("--hard", ref)
    else:  # Full fetch in this case
        git.fetch(remote_name)
        git.reset("--hard", ref)
Пример #56
0
def test_tags(qisrc_action, git_server):
    """ Test Tags """
    git_server.create_repo("foo.git")
    git_server.push_file("foo.git", "a.txt", "a")
    git_server.push_tag("foo.git", "v0.1")
    git_server.push_file("foo.git", "b.txt", "b")
    git_server.set_fixed_ref("foo.git", "v0.1")
    qisrc_action("init", git_server.manifest_url)
    git_worktree = TestGitWorkTree()
    foo_proj = git_worktree.get_git_project("foo")
    git = TestGit(foo_proj.path)
    _, sha1 = git.call("rev-parse", "HEAD", raises=False)
    expected = git.get_ref_sha1("refs/tags/v0.1")
    assert sha1 == expected
Пример #57
0
def test_push(tmpdir):
    foo_url = create_git_repo(tmpdir.strpath, "foo")
    work = tmpdir.mkdir("work")
    foo_src = work.mkdir("foo")
    foo_src = foo_src.strpath
    git = qisrc.git.Git(foo_src)
    git.clone(foo_url)

    # this should work:
    qisrc.review.push(foo_src, "master")
    (retcode, out) = git.call("ls-remote", "origin", raises=False)
    assert retcode == 0
    assert "refs/for/master" not in out
    assert "refs/heads/master" in out

    gerrit_url = create_git_repo(tmpdir.strpath, "foo-gerrit")
    git.call("remote", "add", "gerrit", gerrit_url)
    git.set_config("review.remote", "gerrit")
    git.checkout("-b", "next")
    qisrc.review.push(foo_src, "next")
    (retcode, out) = git.call("ls-remote", "gerrit", raises=False)
    assert retcode == 0
    assert "refs/for/next" in out
    assert "refs/heads/next" not in out
Пример #58
0
 def _add_scm_info(self, package_xml_root):
     worktree = self.build_worktree.worktree
     git_worktreee = qisrc.worktree.GitWorkTree(worktree)
     git_projects = git_worktreee.git_projects
     parent_git_project = qisys.parsers.find_parent_project(git_projects, self.path)
     if not parent_git_project:
         return
     git = qisrc.git.Git(parent_git_project.path)
     rc, out = git.call("rev-parse", "HEAD", raises=False)
     if rc != 0:
         return
     sha1 = out.strip()
     scm_elem = etree.SubElement(package_xml_root, "scm")
     git_elem = etree.SubElement(scm_elem, "git")
     git_elem.set("revision", sha1)