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")
    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")
    def test_untracked_would_be_overwritten(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 untracked, conflicting changes
        a_file = os.path.join(bar_src, "a_file")
        with open(a_file, "w") as fp:
            fp.write("a_file\n")

        upstream_src = os.path.join(self.tmp, "src", "bar")
        upstream_file = os.path.join(upstream_src, "a_file")
        with open(upstream_file, "w") as fp:
            fp.write("upstream file\n")
        upstream_git = qisrc.git.Git(upstream_src)
        upstream_git.call("add", "a_file")
        upstream_git.call("commit", "-m", "Add a file")
        upstream_git.call("push", bar_url, "master:master")

        err = git.update_branch("master", "origin")
        self.assertTrue(err)
        self.assertTrue("untracked working tree files" in err)
        self.assertEqual(git.get_current_branch(), "master")
    def test_conflict(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")

        # Updating branch should fail
        err = git.update_branch("master", "origin")
        self.assertTrue(err)
        self.assertTrue("Merge conflict in README" in err, err)

        # But we should be back at our previous commit
        readme = read_readme(bar_src)
        self.assertEqual(readme, "bar\nconflicting changes\n")

        self.assertEqual(git.get_current_branch(), "master")
        rebase_apply = os.path.join(git.repo, ".git", "rebase_apply")
        self.assertFalse(os.path.exists(rebase_apply))
    def test_simple(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)
        # Should be a noop
        git.update_branch("master", "origin")
        readme = read_readme(bar_src)
        self.assertEqual(readme, "bar\n")

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

        # Update, check that branch is up to date
        git.update_branch("master", "origin")
        readme = read_readme(bar_src)
        self.assertEqual(readme, "bar v2 on master\n")
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()
    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_unstaged_changes_conflict(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 unstaged, conflicting changes
        readme = os.path.join(bar_src, "README")
        with open(readme, "a") as fp:
            fp.write("Unstaged changes\n")
        push_readme_v2(self.tmp, "bar", "master")

        err = git.update_branch("master", "origin")
        self.assertTrue(err)
        self.assertTrue("Merge conflict in README" in err)
        self.assertTrue("Stashing back changes failed" in err)
        self.assertTrue(git.get_current_branch(), "master")
        rebase_apply = os.path.join(git.repo, ".git", "rebase_apply")
        self.assertFalse(os.path.exists(rebase_apply))
        readme = read_readme(bar_src)
        self.assertTrue(readme, "Unstaged changes\n")
    def test_unstaged_changes_no_conflict(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 unstaged, non-conflicting changes
        readme = os.path.join(bar_src, "README")
        with open(readme, "w") as fp:
            fp.write("Unstaged changes\n")

        upstream_src = os.path.join(self.tmp, "src", "bar")
        upstream_file = os.path.join(upstream_src, "a_file")
        with open(upstream_file, "w") as fp:
            fp.write("upstream file\n")
        upstream_git = qisrc.git.Git(upstream_src)
        upstream_git.call("add", "a_file")
        upstream_git.call("commit", "-m", "Add a file")
        upstream_git.call("push", bar_url, "master:master")

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

        # Check that upstream file is here
        a_file = os.path.join(bar_src, "a_file")
        self.assertTrue(os.path.exists(a_file))

        # Check that unstaged changes are here:
        readme = read_readme(bar_src)
        self.assertEqual(readme, "Unstaged changes\n")

        self.assertTrue(git.get_current_branch(), "master")
        rebase_apply = os.path.join(git.repo, ".git", "rebase_apply")
        self.assertFalse(os.path.exists(rebase_apply))
    def test_untracked_files(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 untracked, non-conflicting changes
        a_file = os.path.join(bar_src, "a_file")
        with open(a_file, "w") as fp:
            fp.write("a_file\n")
        push_readme_v2(self.tmp, "bar", "master")

        # Update branch, untracked files should still be here
        err = git.update_branch("master", "origin")
        self.assertFalse(err)

        self.assertTrue(os.path.exists(a_file))
        with open(a_file, "r") as fp:
            contents = fp.read()
        self.assertEqual(contents, "a_file\n")
        readme = read_readme(bar_src)
        self.assertEqual(readme, "bar v2 on master\n")