Exemple #1
0
 def _clone_missing(self, git_project, repo):
     """ Clone Missing """
     branch = repo.default_branch
     fixed_ref = repo.fixed_ref
     clone_url = repo.clone_url
     qisys.sh.mkdir(git_project.path, recursive=True)
     git = qisrc.git.Git(git_project.path)
     remote_name = repo.default_remote.name
     try:
         git.init()
         git.remote("add", remote_name, clone_url)
         git.fetch(remote_name, "--quiet")
         if branch:
             git.checkout("-b", branch, "%s/%s" % (remote_name, branch))
         if fixed_ref:
             git.checkout("-q", fixed_ref)
     except Exception:
         ui.error("Cloning repo failed")
         if git.is_empty():
             qisys.sh.rm(git_project.path)
         self.worktree.remove_project(repo.src)
         return False
     self.save_project_config(git_project)
     self.load_git_projects()
     return True
Exemple #2
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
Exemple #3
0
    def push_file(self, project, filename, contents,
                  branch="master", fast_forward=True,
                  message=None):
        """ Push a new file with the given contents 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(filename)
        if not message:
            if to_write.check(file=True):
                message = "Update %s" % filename
            else:
                message = "Add %s" % filename
        repo_src.ensure(filename, file=True)
        repo_src.join(filename).write(contents)
        git.add(filename)
        git.commit("--message", message)
        if fast_forward:
            git.push("origin", "%s:%s" % (branch, branch))
        else:
            git.push("origin", "--force", "%s:%s" % (branch, branch))
Exemple #4
0
    def push_file(self, project, filename, contents,
                  branch="master", fast_forward=True,
                  message=None):
        """ Push a new file with the given contents to the given project
        It is assumed that the project has beed 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(filename)
        if not message:
            if to_write.check(file=True):
                message = "Update %s" % filename
            else:
                message = "Add %s" % filename
        repo_src.ensure(filename, file=True)
        repo_src.join(filename).write(contents)
        git.add(filename)
        git.commit("--message", message)
        if fast_forward:
            git.push("origin", "%s:%s" % (branch, branch))
        else:
            git.push("origin", "--force", "%s:%s" % (branch, branch))
def create_git_repo(tmp, path, with_release_branch=False):
    """ Create a empty git repository, which just
    what is enough so that it is possible to clone it

    Return a valid git url.
    """
    tmp_srv = os.path.join(tmp, "srv", path + ".git")
    qibuild.sh.mkdir(tmp_srv, recursive=True)
    srv_git = qisrc.git.Git(tmp_srv)
    srv_git.call("init", "--bare")

    tmp_src = os.path.join(tmp, "src", path)
    qibuild.sh.mkdir(tmp_src, recursive=True)
    write_readme(tmp_src, path + "\n")
    git = qisrc.git.Git(tmp_src)
    git.call("init")
    git.call("add", ".")
    git.call("commit", "-m", "intial commit")
    git.call("push", tmp_srv, "master:master")

    if not with_release_branch:
        return tmp_srv

    git.checkout("-b", "release-1.12")
    write_readme(tmp_src, "%s on release-1.12\n" % path)
    git.call("add", "README")
    git.call("commit", "-m", "update README for 1.12")
    git.call("push", tmp_srv, "release-1.12:release-1.12")
    return tmp_srv
    def test_wrong_branch_unstaged(self):
        bar_url = create_git_repo(self.tmp, "bar")
        work = os.path.join(self.tmp, "work")
        qibuild.sh.mkdir(work)
        bar_src = os.path.join(work, "bar")
        git = qisrc.git.Git(bar_src)
        git.clone(bar_url)

        # Checkout a 'next' branch with unstaged changes
        git.checkout("-b", "next")
        write_readme(bar_src, "bar on next\n")
        push_readme_v2(self.tmp, "bar", "master")

        err = git.update_branch("master", "origin")
        self.assertFalse(err)

        # Check we are still on next with our
        # unstaged changes back
        self.assertEqual(git.get_current_branch(), "next")
        readme = read_readme(bar_src)
        self.assertEqual(readme, "bar on next\n")

        # Check that master is up to date
        git.checkout("-f", "master")
        readme = read_readme(bar_src)
        self.assertEqual(readme, "bar v2 on master\n")
Exemple #7
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))
    def test_wrong_branch(self):
        bar_url = create_git_repo(self.tmp, "bar")
        work = os.path.join(self.tmp, "work")
        qibuild.sh.mkdir(work)
        bar_src = os.path.join(work, "bar")
        git = qisrc.git.Git(bar_src)
        git.clone(bar_url)
        git.update_branch("master", "origin")
        readme = read_readme(bar_src)
        self.assertEqual(readme, "bar\n")

        # Checkout a 'next' branch
        git.checkout("-b", "next")
        with open(os.path.join(bar_src, "README"), "w") as fp:
            fp.write("bar on next\n")
        git.commit("-a", "-m", "README next")

        # Push a new commit
        push_readme_v2(self.tmp, "bar", "master")

        # Update, check that master is up to date
        err = git.update_branch("master", "origin")
        self.assertFalse(err)
        git.checkout("master")
        readme = read_readme(bar_src)
        self.assertEqual(readme, "bar v2 on master\n")
Exemple #9
0
def fetch_manifest(worktree, manifest_git_url, branch="master",
    profile="default",
    src="manifest/default"):
    """ Fetch the manifest for a worktree

    :param manifest_git_url: A git repository containing a
        'manifest.xml' file, ala repo
    :param branch: The branch to use
    :param src: The path where to store the clone of the manifest

    Note: every changes made by the user directly in the manifest repo
    will be lost!

    """
    manifest = worktree.get_project(src)
    if not manifest:
        clone_project(worktree, manifest_git_url, src=src)
        manifest = worktree.get_project(src)
    # Make sure manifest project is on the correct, up to date branch:
    git = qisrc.git.Git(manifest.path)
    git.set_remote("origin", manifest_git_url)
    git.set_tracking_branch(branch, "origin")
    git.checkout("-f", branch, quiet=True)
    git.fetch(quiet=True)
    git.reset("--hard", "origin/%s" % branch, quiet=True)
    filename = profile + ".xml"
    manifest_file = os.path.join(manifest.path, filename)
    if not os.path.exists(manifest_file):
        mess  = "Could not find a file named '%s' " % filename
        mess += "in the repository: %s\n" % manifest_git_url
        raise Exception(mess)
    return manifest_file
Exemple #10
0
def test_fake_git_wrong_setup():
    git = FakeGit("repo")
    git.add_result("checkout", 0, "")
    git.checkout("-f", "master")
    # pylint: disable-msg=E1101
    with pytest.raises(Exception) as e:
        git.fetch()
    assert "Unexpected call to fetch" in e.value.args[0]
Exemple #11
0
def test_wrong_setup():
    git = FakeGit("repo")
    git.add_result("checkout", 0, "")
    git.checkout("-f", "master")
    # pylint: disable-msg=E1101
    with pytest.raises(Exception) as e:
        git.fetch()
    assert "Unexpected call to fetch" in e.value.message
Exemple #12
0
def test_retcode_when_skipping(qisrc_action, git_server):
    git_server.create_repo("bar")
    qisrc_action("init", git_server.manifest_url)
    git_worktree = TestGitWorkTree()
    bar_proj = git_worktree.get_git_project("bar")
    git = TestGit(bar_proj.path)
    git.checkout("-b", "devel")
    rc = qisrc_action("sync", retcode=True)
    assert rc != 0
Exemple #13
0
def test_fake_git_configured_but_not_called():
    git = FakeGit("repo")
    git.add_result("checkout", 1, "")
    git.add_result("reset", 0, "")
    # pylint: disable-msg=E1101
    git.checkout(raises=False)
    with pytest.raises(Exception) as e:
        git.check()
    assert "reset was added as result but never called" in e.value.args[0]
Exemple #14
0
def test_configured_but_not_called():
    git = FakeGit("repo")
    git.add_result("checkout", 1, "")
    git.add_result("reset", 0, "")
    # pylint: disable-msg=E1101
    git.checkout(raises=False)
    with pytest.raises(Exception) as e:
        git.check()
    assert "reset was added as result but never called" in e.value.message
Exemple #15
0
def test_retcode_when_skipping(qisrc_action, git_server):
    git_server.create_repo("bar")
    qisrc_action("init", git_server.manifest_url)
    git_worktree = TestGitWorkTree()
    bar_proj = git_worktree.get_git_project("bar")
    git = TestGit(bar_proj.path)
    git.checkout("-b", "devel")
    rc = qisrc_action("sync", retcode=True)
    assert rc != 0
Exemple #16
0
def test_fake_git_configured_but_not_called_enough():
    git = FakeGit("repo")
    git.add_result("checkout", 0, "")
    git.add_result("checkout", 1, "Unstaged changes")
    git.checkout("next")
    # pylint: disable-msg=E1101
    with pytest.raises(Exception) as e:
        git.check()
    assert "checkout was configured to be called 2 times" in e.value.args[0]
    assert "was only called 1 times" in e.value.args[0]
Exemple #17
0
 def push_manifest(self, message, allow_empty=False):
     """ Push new manifest.xml version """
     manifest_repo = self.root.join("src", "manifest")
     git = qisrc.git.Git(manifest_repo.strpath)
     commit_args = ["--all", "--message", message]
     if allow_empty:
         commit_args.append("--allow-empty")
     git.commit(*commit_args)
     git.checkout("--force", "-B", self.manifest_branch)
     git.push("origin", "%s:%s" % (self.manifest_branch, self.manifest_branch))
Exemple #18
0
def test_configured_but_not_called_enough():
    git = FakeGit("repo")
    git.add_result("checkout", 0, "")
    git.add_result("checkout", 1, "Unstaged changes")
    git.checkout("next")
    # pylint: disable-msg=E1101
    with pytest.raises(Exception) as e:
        git.check()
    assert "checkout was configured to be called 2 times" in e.value.message
    assert "was only called 1 times" in e.value.message
Exemple #19
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
Exemple #20
0
def do(args):
    """Main entry points."""

    git_worktree = qisrc.parsers.get_git_worktree(args)
    snapshot = None
    if args.snapshot:
        snapshot = qisrc.snapshot.Snapshot()
        snapshot.load(args.snapshot)

    if snapshot and snapshot.format_version and snapshot.format_version >= 1:
        reset_manifest(git_worktree, snapshot, groups=args.groups)

    git_projects = qisrc.parsers.get_git_projects(git_worktree,
                                                  args,
                                                  default_all=True,
                                                  use_build_deps=True)
    errors = list()
    for i, git_project in enumerate(git_projects):
        ui.info_count(i, len(git_projects), "Reset", git_project.src)
        src = git_project.src
        git = qisrc.git.Git(git_project.path)
        ok, message = git.require_clean_worktree()
        if not ok and not args.force:
            ui.warning(message)
            errors.append(src)
            continue
        git.checkout(".")
        if not git_project.default_branch:
            ui.warning(git_project.src, "not in any manifest, skipping")
            continue
        branch = git_project.default_branch.name
        remote = git_project.default_remote.name
        git.safe_checkout(branch, remote, force=True)

        to_reset = None
        if args.snapshot:
            to_reset = snapshot.refs.get(src)
            if not to_reset:
                ui.warning(src, "not found in the snapshot")
                continue
        elif args.tag:
            to_reset = args.tag
        else:
            to_reset = "%s/%s" % (remote, branch)
        try:
            qisrc.reset.clever_reset_ref(git_project, to_reset)
        except:
            errors.append(src)

    if not errors:
        return
    ui.error("Failed to reset some projects")
    for error in errors:
        ui.info(ui.red, " * ", error)
    sys.exit(1)
Exemple #21
0
 def change_branch(self, project, new_branch):
     repo = self.get_repo(project)
     repo_src = self.src.join(repo.src)
     git = qisrc.git.Git(repo_src.strpath)
     git.checkout("--force", "-B", new_branch)
     for remote in repo.remotes:
         git.push(remote.url, "%s:%s" % (new_branch, new_branch))
     repo.default_branch = new_branch
     self.manifest.dump()
     self.push_manifest("%s on %s" % (repo.project, new_branch))
     self.manifest.load()
Exemple #22
0
 def change_branch(self, project, new_branch):
     repo = self.get_repo(project)
     repo_src = self.src.join(repo.src)
     git = qisrc.git.Git(repo_src.strpath)
     git.checkout("--force", "-B", new_branch)
     for remote in repo.remotes:
         git.push(remote.url, "%s:%s" % (new_branch, new_branch))
     repo.default_branch = new_branch
     self.manifest.dump()
     self.push_manifest("%s on %s" % (repo.project, new_branch))
     self.manifest.load()
Exemple #23
0
def do(args):
    """Main entry points."""

    git_worktree = qisrc.parsers.get_git_worktree(args)
    snapshot = None
    if args.snapshot:
        snapshot = qisrc.snapshot.Snapshot()
        snapshot.load(args.snapshot)

    if snapshot and snapshot.format_version and snapshot.format_version >= 1:
        reset_manifest(git_worktree, snapshot, groups=args.groups)

    git_projects = qisrc.parsers.get_git_projects(git_worktree, args,
                                                  default_all=True,
                                                  use_build_deps=True)
    errors = list()
    for i, git_project in enumerate(git_projects):
        ui.info_count(i, len(git_projects), "Reset", git_project.src)
        src = git_project.src
        git = qisrc.git.Git(git_project.path)
        ok, message = git.require_clean_worktree()
        if not ok and not args.force:
            ui.warning(message)
            errors.append(src)
            continue
        git.checkout(".")
        if not git_project.default_branch:
            ui.warning(git_project.src, "not in any manifest, skipping")
            continue
        branch = git_project.default_branch.name
        remote = git_project.default_remote.name
        git.safe_checkout(branch, remote, force=True)

        to_reset = None
        if args.snapshot:
            to_reset = snapshot.refs.get(src)
            if not to_reset:
                ui.warning(src, "not found in the snapshot")
                continue
        elif args.tag:
            to_reset = args.tag
        else:
            to_reset = "%s/%s" % (remote, branch)
        try:
            qisrc.reset.clever_reset_ref(git_project, to_reset)
        except:
            errors.append(src)

    if not errors:
        return
    ui.error("Failed to reset some projects")
    for error in errors:
        ui.info(ui.red, " * ", error)
    sys.exit(1)
Exemple #24
0
 def push_manifest(self, message, allow_empty=False):
     """ Push new manifest.xml version """
     manifest_repo = self.root.join("src", "manifest")
     git = qisrc.git.Git(manifest_repo.strpath)
     commit_args = ["--all", "--message", message]
     if allow_empty:
         commit_args.append("--allow-empty")
     git.commit(*commit_args)
     if git.get_current_branch() != self.manifest_branch:
         git.checkout("--force", "-B", self.manifest_branch)
     git.push("origin", "%s:%s" % (self.manifest_branch, self.manifest_branch))
Exemple #25
0
def test_using_force_when_not_an_a_branch(qisrc_action, git_server):
    git_server.create_repo("foo.git")
    git_server.push_file("foo.git", "foo.txt", "this is foo")
    manifest_url = git_server.manifest_url
    qisrc_action("init", manifest_url)
    git_worktree = TestGitWorkTree()
    foo_proj = git_worktree.get_git_project("foo")
    git = qisrc.git.Git(foo_proj.path)
    git.checkout("HEAD~1")
    assert not git.get_current_branch()
    qisrc_action("checkout", "master", "--force")
    assert git.get_current_branch() == "master"
Exemple #26
0
 def _sync_manifest(self, local_manifest):
     """ Update the local manifest clone with the remote """
     manifest_repo = os.path.join(self.manifests_root, local_manifest.name)
     git = qisrc.git.Git(manifest_repo)
     with git.transaction() as transaction:
         git.fetch("origin")
         git.checkout("-B", local_manifest.branch)
         git.reset("--hard", "origin/%s" % local_manifest.branch)
     if not transaction.ok:
         ui.warning("Update failed")
         ui.info(transaction.output)
         return
Exemple #27
0
def test_using_force_when_not_an_a_branch(qisrc_action, git_server):
    git_server.create_repo("foo.git")
    git_server.push_file("foo.git", "foo.txt", "this is foo")
    manifest_url = git_server.manifest_url
    qisrc_action("init", manifest_url)
    git_worktree = TestGitWorkTree()
    foo_proj = git_worktree.get_git_project("foo")
    git = qisrc.git.Git(foo_proj.path)
    git.checkout("HEAD~1")
    assert not git.get_current_branch()
    qisrc_action("checkout", "master", "--force")
    assert git.get_current_branch() == "master"
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"]
 def test_get_current_branch(self):
     bar_url = create_git_repo(self.tmp, "bar")
     work = os.path.join(self.tmp, "work")
     qibuild.sh.mkdir(work)
     bar_src = os.path.join(work, "bar")
     git = qisrc.git.Git(bar_src)
     git.clone(bar_url)
     self.assertEqual(git.get_current_branch(), "master")
     push_readme_v2(self.tmp, "bar", "master")
     git.pull()
     self.assertEqual(git.get_current_branch(), "master")
     git.checkout("-f", "HEAD~1")
     self.assertEqual(git.get_current_branch(), None)
def test_changing_branch_of_repo_under_code_review(qisrc_action, git_server,
                                                   record_messages):
    git_server.create_repo("foo.git", review=True)
    qisrc_action("init", git_server.manifest_url)
    git_server.change_branch("foo.git", "devel")
    git_worktree = TestGitWorkTree()
    foo_proj = git_worktree.get_git_project("foo")
    git = TestGit(foo_proj.path)
    git.checkout("-b", "devel")
    record_messages.reset()
    qisrc_action("sync")
    assert record_messages.find("default branch changed")
    assert not record_messages.find("now using code review")
Exemple #31
0
def test_changing_branch_of_repo_under_code_review(qisrc_action, git_server,
                                                   record_messages):
    git_server.create_repo("foo.git", review=True)
    qisrc_action("init", git_server.manifest_url)
    git_server.change_branch("foo.git", "devel")
    git_worktree = TestGitWorkTree()
    foo_proj = git_worktree.get_git_project("foo")
    git = TestGit(foo_proj.path)
    git.checkout("-b", "devel")
    record_messages.reset()
    qisrc_action("sync")
    assert record_messages.find("default branch changed")
    assert not record_messages.find("now using code review")
Exemple #32
0
 def _sync_git(repo, url, branch, ref):
     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.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)
Exemple #33
0
 def _sync_manifest(self):
     """ Update the local manifest clone with the remote """
     git = qisrc.git.Git(self.manifest_repo)
     git.set_remote("origin", self.manifest.url)
     if git.get_current_branch() != self.manifest.branch:
         git.checkout("-B", self.manifest.branch)
     with git.transaction() as transaction:
         git.fetch("origin")
         if self.manifest.ref:
             to_reset = self.manifest.ref
             git.reset("--hard", to_reset)
         else:
             git.reset("--hard", "origin/%s" % self.manifest.branch)
     if not transaction.ok:
         raise Exception("Update failed\n" + transaction.output)
def test_when_not_on_a_branch(git_server, qisrc_action, record_messages):
    git_server.create_repo("foo.git")
    git_server.switch_manifest_branch("devel")
    git_server.change_branch("foo.git", "devel")
    git_server.push_file("foo.git", "devel",
                         "this is devel\n", branch="devel",
                         message="start developing")
    qisrc_action("init", git_server.manifest_url, "--branch", "devel")
    git_worktree = TestGitWorkTree()
    foo = git_worktree.get_git_project("foo")
    git = qisrc.git.Git(foo.path)
    git.checkout("HEAD~1")
    record_messages.reset()
    qisrc_action("log", "--all", "master")
    assert record_messages.find("Not on a branch")
Exemple #35
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)
Exemple #36
0
 def _sync_manifest(self):
     """ Update the local manifest clone with the remote """
     git = qisrc.git.Git(self.manifest_repo)
     git.set_remote("origin", self.manifest.url)
     if git.get_current_branch() != self.manifest.branch:
         git.checkout("-B", self.manifest.branch)
     with git.transaction() as transaction:
         git.fetch("origin")
         if self.manifest.ref:
             to_reset = self.manifest.ref
             git.reset("--hard", to_reset)
         else:
             git.reset("--hard", "origin/%s" % self.manifest.branch)
     if not transaction.ok:
         raise Exception("Update failed\n" + transaction.output)
Exemple #37
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)
Exemple #38
0
def test_when_not_on_a_branch(git_server, qisrc_action, record_messages):
    """ Test When Not On a Branch """
    git_server.create_repo("foo.git")
    git_server.switch_manifest_branch("devel")
    git_server.change_branch("foo.git", "devel")
    git_server.push_file("foo.git", "devel",
                         "this is devel\n", branch="devel",
                         message="start developing")
    qisrc_action("init", git_server.manifest_url, "--branch", "devel")
    git_worktree = TestGitWorkTree()
    foo1 = git_worktree.get_git_project("foo")
    git = qisrc.git.Git(foo1.path)
    git.checkout("HEAD~1")
    record_messages.reset()
    qisrc_action("log", "--all", "master")
    assert record_messages.find("Not on a branch")
Exemple #39
0
 def _clone_missing(self, git_project, repo):
     branch = repo.default_branch
     clone_url = repo.clone_url
     qisys.sh.mkdir(git_project.path, recursive=True)
     git = qisrc.git.Git(git_project.path)
     remote_name = repo.default_remote.name
     try:
         git.init()
         git.remote("add", remote_name, clone_url)
         git.fetch(remote_name, "--quiet")
         git.checkout("-b", branch, "%s/%s" % (remote_name, branch))
     except:
         ui.error("Cloning repo failed")
         if git.is_empty():
             qisys.sh.rm(git_project.path)
         self.worktree.remove_project(repo.src)
         return False
     self.save_project_config(git_project)
     self.load_git_projects()
     return True
def push_file(tmp, git_path, filename, contents, branch="master"):
    """ Push a file to the given url. Assumes the repository
    has been created with :py:func:`create_git_repo` with the same
    path

    """
    tmp_src = os.path.join(tmp, "src", git_path)
    tmp_srv = os.path.join(tmp, "srv", git_path + ".git")
    git = qisrc.git.Git(tmp_src)
    if branch in git.get_local_branches():
        git.checkout("-f", branch)
    else:
        git.checkout("-b", branch)
    dirname = os.path.dirname(filename)
    qibuild.sh.mkdir(os.path.join(tmp_src, dirname), recursive=True)
    with open(os.path.join(tmp_src, filename), "w") as fp:
        fp.write(contents)
    git.add(filename)
    git.commit("-m", "added %s" % filename)
    git.push(tmp_srv, "%s:%s" % (branch, branch))
    def test_wrong_branch_with_conflicts(self):
        bar_url = create_git_repo(self.tmp, "bar")
        work = os.path.join(self.tmp, "work")
        qibuild.sh.mkdir(work)
        bar_src = os.path.join(work, "bar")
        git = qisrc.git.Git(bar_src)
        git.clone(bar_url)

        # Create conflicting changes
        write_readme(bar_src, "conflicting changes\n", append=True)
        git.commit("-a", "-m", "conflicting changes")
        push_readme_v2(self.tmp, "bar", "master")

        # Checkout an other branch
        git.checkout("-b", "next")

        # Try to update master while being on an other branch:
        err = git.update_branch("master", "origin")
        self.assertTrue(err)
        self.assertTrue("Merge is not fast-forward" in err)
def test_set_tracking_branch(tmpdir):
    tmpdir = tmpdir.strpath
    bar_url = create_git_repo(tmpdir, "bar")
    work = os.path.join(tmpdir, "work")
    bar_src = os.path.join(work, "bar")
    git = qisrc.git.Git(bar_src)
    git.clone(bar_url)

    push_file(tmpdir, "bar", "README", "README on release",  branch="release")
    push_file(tmpdir, "bar", "README", "README on master", branch="master")
    git.update_branch("master", "origin")

    git.set_tracking_branch("release", "origin")
    err = git.update_branch("release", "origin")
    assert not err

    # This should work out of the box
    git.pull()
    git.checkout("release")
    git.pull()
Exemple #43
0
def _switch_to_git_ref(git, ref_to_reset_to, is_tag):
    """ Switch To Git Ref """
    if is_tag:
        # checkout puts the git current repo in a detached HEAD status
        # As setting a tag in the manifest means oubvioulsy a read-only git copy,
        # The detached HEAD prevents an user to accidentally pull up to the original branch HEAD and commits things
        rc, out = git.checkout(ref_to_reset_to, "--", raises=False)
    else:
        # reset --hard keeps the attached HEAD, and that's probably what the user needs to be able to track changes
        # and commits some things. If the user wants its git copy in read-only, he can use a tag instead of a branch
        rc, out = git.reset("--hard", ref_to_reset_to, "--", raises=False)
    return rc, out
Exemple #44
0
    def _sync_manifest(self):
        """ Update the local manifest clone with the remote """
        if not self.manifest.url:
            mess = """ \
No manifest set for worktree in {root}
Please run `qisrc init MANIFEST_URL`
"""
            raise Exception(mess.format(root=self.git_worktree.root))
        git = qisrc.git.Git(self.manifest_repo)
        git.set_remote("origin", self.manifest.url)
        if git.get_current_branch() != self.manifest.branch:
            git.checkout("-B", self.manifest.branch)
        with git.transaction() as transaction:
            git.fetch("origin")
            if self.manifest.ref:
                to_reset = self.manifest.ref
                git.reset("--hard", to_reset)
            else:
                git.reset("--hard", "origin/%s" % self.manifest.branch)
        if not transaction.ok:
            raise Exception("Update failed\n" + transaction.output)
Exemple #45
0
def _switch_to_git_ref(git, ref_to_reset_to, is_tag):
    """ Switch To Git Ref """
    if is_tag:
        # checkout puts the git current repo in a detached HEAD status
        # As setting a tag in the manifest means oubvioulsy a read-only git copy,
        # The detached HEAD prevents an user to accidentally pull up to the original branch HEAD and commits things
        rc, out = git.checkout(ref_to_reset_to, "--", raises=False)
    else:
        # reset --hard keeps the attached HEAD, and that's probably what the user needs to be able to track changes
        # and commits some things. If the user wants its git copy in read-only, he can use a tag instead of a branch
        rc, out = git.reset("--hard", ref_to_reset_to, "--", raises=False)
    return rc, out
Exemple #46
0
 def _clone_missing(self, git_project, repo):
     branch = repo.default_branch
     clone_url = repo.clone_url
     qisys.sh.mkdir(git_project.path, recursive=True)
     git = qisrc.git.Git(git_project.path)
     remote_name = repo.default_remote.name
     try:
         git.init()
         git.remote("add", remote_name, clone_url)
         git.fetch(remote_name, "--quiet")
         remote_branch = "%s/%s" % (remote_name, branch)
         rc, _ = git.call("rev-parse", "--verify", "--quiet", remote_branch, raises=False)
         # When `remote_branch` is invalid, try to checkout `branch` instead
         git.checkout("-b", branch, branch if rc else remote_branch)
     except:
         ui.error("Cloning repo failed")
         if git.is_empty():
             qisys.sh.rm(git_project.path)
         self.worktree.remove_project(repo.src)
         return False
     self.save_project_config(git_project)
     self.load_git_projects()
     return True
Exemple #47
0
 def _clone_missing(self, git_project, repo):
     branch = repo.default_branch
     clone_url = repo.clone_url
     qisys.sh.mkdir(git_project.path, recursive=True)
     git = qisrc.git.Git(git_project.path)
     remote_name = repo.default_remote.name
     try:
         git.init()
         git.remote("add", remote_name, clone_url)
         git.fetch(remote_name, "--quiet")
         remote_branch = "%s/%s" % (remote_name, branch)
         rc, _ = git.call("rev-parse", "--verify", "--quiet", remote_branch, raises=False)
         # When `remote_branch` is invalid, try to checkout `branch` instead
         git.checkout("-b", branch, branch if rc else remote_branch)
     except:
         ui.error("Cloning repo failed")
         if git.is_empty():
             qisys.sh.rm(git_project.path)
         self.worktree.remove_project(repo.src)
         return False
     self.save_project_config(git_project)
     self.load_git_projects()
     return True
 def test_set_remote(self):
     bar_url = create_git_repo(self.tmp, "bar", with_release_branch=True)
     work = os.path.join(self.tmp, "work")
     qibuild.sh.mkdir(work)
     bar_src = os.path.join(work, "bar")
     git = qisrc.git.Git(bar_src)
     git.clone(bar_url,  "-o", "foo")
     # Must work:
     git.pull()
     git.set_remote("origin", bar_url)
     # Must NOT work:
     out, err_ = git.pull("origin", raises=False)
     self.assertFalse(out == 0)
     # Must work
     git.set_tracking_branch("master", "origin")
     git.pull()
     readme = read_readme(bar_src)
     self.assertEqual(readme, "bar\n")
     git.set_tracking_branch("stable", "origin", remote_branch="release-1.12")
     git.checkout("stable")
     git.pull()
     readme = read_readme(bar_src)
     self.assertEqual(readme, "bar on release-1.12\n")