예제 #1
0
    def test_repoStart_onDetached(self):
        self.runRepo(["start", "topic"])

        for sProjectFolder in self.dProjectFolders:
            with changeWorkingDir(sProjectFolder):
                assert git.getCurrentBranch() == "topic"
                assert git.getGitMessages() == [INITIAL_COMMIT_MSG]
예제 #2
0
    def runInRepos(self, dRepos, xFunction, bPrint=True, bCheckTopic=True):
        if bCheckTopic:
            lBranches = set()
            try:
                for sDirPath in dRepos.values():
                    if os.path.isdir(sDirPath):
                        with changeWorkingDir(sDirPath):
                            lBranches.add(
                                strOrDefault(git.getCurrentBranch(), "(none)"))
            except (subprocess.CalledProcessError, OSError) as e:
                raise FatalError(e)

            if len(lBranches) > 1:
                warning("Topic is not consistent across your repositories. "
                        "Found following topics: %s" % ", ".join(lBranches))
                sInput = input("Do you wish to proceed anyway? (y/n): ")
                if sInput != "y":
                    raise FatalError("Operation cancelled")

        lErrorRepos = []
        for sRepoUrl, sDirPath in dRepos.items():
            sRepoName = os.path.basename(sDirPath)
            try:
                os.makedirs(sDirPath, exist_ok=True)
                with changeWorkingDir(sDirPath):
                    if bPrint:
                        highlight("\n### %s ###" %
                                  os.path.basename(os.getcwd()))
                    xFunction(sRepoUrl)
                    if bPrint:
                        success("Done")
            except (subprocess.CalledProcessError, FatalError, OSError) as e:
                error("[%s] %s" % (sRepoName, e))
                lErrorRepos.append(sDirPath)
        return lErrorRepos
예제 #3
0
 def test_repoSync_checkout(self):
     for sProjectFolder in self.dProjectFolders:
         with changeWorkingDir(sProjectFolder):
             lBranches = git.getAllBranches()
             assert len(lBranches) == 1
             assert re.match(r"\(HEAD detached at .*\)", lBranches[0], re.IGNORECASE) is not None
             assert git.getCurrentBranch() == ""
             assert git.getGitMessages() == [INITIAL_COMMIT_MSG]
예제 #4
0
    def test_repoDownload_detach(self):
        iChangeNumber, _ = self.repoDownloadTestSetup()

        self.runRepo(["download", "-d", next(iter(self.dProjectFolders.values())), "%d/1" % iChangeNumber])

        for iIdx, sProjectFolder in enumerate(self.dProjectFolders):
            with changeWorkingDir(sProjectFolder):
                if iIdx == 0:
                    assert git.getCurrentBranch() == ""
                    assert os.path.isfile("test_1.txt")
                    assert not os.path.isfile("test_2.txt")
                    assert git.getGitMessages() == ["Test commit (1)", INITIAL_COMMIT_MSG]
                else:
                    assert git.getCurrentBranch() == "topic_2"
                    assert not os.path.isfile("test_1.txt")
                    assert os.path.isfile("test_2.txt")
                    assert git.getGitMessages() == ["Test commit (2)", INITIAL_COMMIT_MSG]
예제 #5
0
 def END(self):
     if git.getCurrentBranch() == self.oArgs.topic:
         print("Detaching HEAD")
         subprocess.run(
             ["git", "fetch", git.getFirstRemote(), "HEAD"], check=True)
         subprocess.run(["git", "checkout", "FETCH_HEAD", "--detach"],
                        check=True)
     print("Deleting topic %s" % self.oArgs.topic)
     subprocess.run(["git", "branch", "-D", self.oArgs.topic], check=True)
예제 #6
0
    def test_repoRename(self):
        self.runRepo(["start", "topic"])

        self.runRepo(["rename", "renamed_topic"])

        for sProjectFolder in self.dProjectFolders:
            with changeWorkingDir(sProjectFolder):
                assert git.getCurrentBranch() == "renamed_topic"
                assert git.getAllBranches() == ["renamed_topic"]
예제 #7
0
 def RENAME(self):
     sCurrentBranch = git.getCurrentBranch()
     if sCurrentBranch:
         print("Renaming topic: %s -> %s" %
               (sCurrentBranch, self.oArgs.topic))
         subprocess.run(["git", "branch", "-m", self.oArgs.topic],
                        check=True)
     else:
         raise FatalError("There is no topic")
예제 #8
0
    def test_repoStart_onOtherTopic(self):
        self.runRepo(["start", "topic_1"])
        self.createCommit()
        self.runRepo(["start", "topic_2"])

        for sProjectFolder in self.dProjectFolders:
            with changeWorkingDir(sProjectFolder):
                assert git.getCurrentBranch() == "topic_2"
                assert git.getGitMessages() == ["Test commit (1)", INITIAL_COMMIT_MSG]
                assert os.path.isfile("test_1.txt")
예제 #9
0
    def test_repoEnd_whenNotActive(self):
        self.runRepo(["start", "topic_1"])
        self.runRepo(["start", "topic_2"])

        self.runRepo(["end", "topic_1"])

        for sProjectFolder in self.dProjectFolders:
            with changeWorkingDir(sProjectFolder):
                assert git.getAllBranches() == ["topic_2"]
                assert git.getCurrentBranch() == "topic_2"
예제 #10
0
    def test_repoSync_detach(self):
        self.runRepo(["start", "topic"])
        self.createCommit()

        self.runRepo(["sync", "-d"])

        for sProjectFolder in self.dProjectFolders:
            with changeWorkingDir(sProjectFolder):
                assert git.getCurrentBranch() == ""
                assert git.getGitMessages() == [INITIAL_COMMIT_MSG]
                assert not os.path.isfile("test_1.txt")
예제 #11
0
    def test_repoDownload_rebase_wrongProject(self):
        iChangeNumber, _ = self.repoDownloadTestSetup()

        oProcess = self.runRepo(["download", "foobar", "%d/1" % iChangeNumber], check=False)
        assert oProcess.returncode != 0

        for iIdx, sProjectFolder in enumerate(self.dProjectFolders):
            with changeWorkingDir(sProjectFolder):
                assert git.getCurrentBranch() == "topic_2"
                assert os.path.isfile("test_2.txt")
                assert not os.path.isfile("test_1.txt")
                assert git.getGitMessages() == ["Test commit (2)", INITIAL_COMMIT_MSG]
예제 #12
0
    def test_repoEnd_whenActive(self):
        self.runRepo(["start", "topic"])
        self.createCommit()

        self.runRepo(["end", "topic"])

        for sProjectFolder in self.dProjectFolders:
            with changeWorkingDir(sProjectFolder):
                lBranches = git.getAllBranches()
                assert len(lBranches) == 1
                assert re.match(r"\(HEAD detached at .*\)", lBranches[0], re.IGNORECASE) is not None
                assert git.getCurrentBranch() == ""
                assert git.getGitMessages() == [INITIAL_COMMIT_MSG]
                assert not os.path.isfile("test_1.txt")
예제 #13
0
    def test_repoRebase_simple(self):
        self.runRepo(["start", "topic_2"])
        self.runRepo(["start", "topic_1"])
        self.createCommit(sId="1")
        self.runRepo(["switch", "topic_2"])
        self.createCommit(sId="2")

        self.runRepo(["rebase", "topic_1"])

        for iIdx, sProjectFolder in enumerate(self.dProjectFolders):
            with changeWorkingDir(sProjectFolder):
                assert git.getCurrentBranch() == "topic_2"
                assert os.path.isfile("test_1.txt")
                assert os.path.isfile("test_2.txt")
                assert git.getGitMessages() == ["Test commit (2)", "Test commit (1)", INITIAL_COMMIT_MSG]
예제 #14
0
 def SYNC(self, sRepoUrl):
     if not os.path.isdir(".git"):
         print("Cloning from %s" % sRepoUrl)
         subprocess.run(["git", "clone", sRepoUrl, "."], check=True)
         sCurrentBranch = git.getCurrentBranch()
         subprocess.run(["git", "checkout", "HEAD", "--detach"], check=True)
         subprocess.run(["git", "branch", "-d", sCurrentBranch], check=True)
     else:
         print("Syncing from %s" % sRepoUrl)
         subprocess.run(
             ["git", "fetch", git.getFirstRemote(), "HEAD"], check=True)
         if self.oArgs.detach:
             subprocess.run(["git", "checkout", "FETCH_HEAD", "--detach"],
                            check=True)
         else:
             gerrit.rebase("FETCH_HEAD", bIgnoreChangeIds=True)
예제 #15
0
 def repoDownloadTestAssertResult(self, iPatch):
     for iIdx, sProjectFolder in enumerate(self.dProjectFolders):
         with changeWorkingDir(sProjectFolder):
             assert git.getCurrentBranch() == "topic_2"
             assert os.path.isfile("test_2.txt")
             if iIdx == 0:
                 assert os.path.isfile("test_1.txt")
                 if iPatch == 1:
                     assert git.getGitMessages() == ["Test commit (2)", "Test commit (1)", INITIAL_COMMIT_MSG]
                 elif iPatch == 2:
                     assert git.getGitMessages() == ["Test commit (2)", "Amended test commit (1)",
                                                     INITIAL_COMMIT_MSG]
                 else:
                     pytest.fail("iPatch parameter must be 1 or 2, received %d" % iPatch)
             else:
                 assert not os.path.isfile("test_1.txt")
                 assert git.getGitMessages() == ["Test commit (2)", INITIAL_COMMIT_MSG]
예제 #16
0
    def test_repoRebase_complex(self):
        self.runRepo(["start", "topic_1"])
        self.createCommit(sId="1")
        self.runRepo(["start", "topic_2"])
        self.createCommit(sId="2")
        self.runRepo(["switch", "topic_1"])
        self.createCommit(sId="1", bAmend=True)
        self.runRepo(["switch", "topic_2"])

        self.runRepo(["rebase", "topic_1"])

        for iIdx, sProjectFolder in enumerate(self.dProjectFolders):
            with changeWorkingDir(sProjectFolder):
                assert git.getCurrentBranch() == "topic_2"
                sFileName = "test_1.txt"
                assert os.path.isfile(sFileName)
                with open(sFileName, "r") as oFile:
                    assert oFile.read() == "This is an amended test (1)."
                assert os.path.isfile("test_2.txt")
                assert git.getGitMessages() == ["Test commit (2)", "Amended test commit (1)", INITIAL_COMMIT_MSG]
예제 #17
0
 def PULL(self, sRepoUrl):
     sChangeId = gerrit.getChangeId()
     if not sChangeId:
         raise FatalError("Unable to extract Change-Id")
     sProject = gerrit.getProjectName()
     try:
         dChangeData = self.getApiClient().getChangeData(
             sChangeId, sProject, lAdditionalData=["ALL_REVISIONS"])
     except requests.HTTPError as e:
         if e.response.status_code == 404:
             warning("No remote patch")
             return
         raise e
     sRemoteCommit = dChangeData["current_revision"]
     sLocalCommit = git.getLastCommit()
     sLastPushedCommit = self.getRepoData().getLastPushedCommit(
         sProject, sChangeId)
     if sRemoteCommit == sLocalCommit:
         print("Already up-to-date.")
         return
     elif sRemoteCommit == sLastPushedCommit:
         print("You are ahead of Gerrit.")
         return
     elif sLocalCommit in dChangeData["revisions"]:
         print("Pulling changes from %s" % sRepoUrl)
         sBranch = git.getCurrentBranch()
         dFetchData = dChangeData["revisions"][sRemoteCommit]["fetch"][
             "ssh"]
         subprocess.run(
             ["git", "fetch", dFetchData["url"], dFetchData["ref"]],
             check=True)
         subprocess.run(["git", "checkout", "FETCH_HEAD"], check=True)
         if sBranch:
             subprocess.run(["git", "branch", "-D", sBranch], check=True)
             subprocess.run(["git", "checkout", "-b", sBranch], check=True)
     else:
         raise FatalError("You have local commits unknown to Gerrit")
예제 #18
0
def rebase(sTargetBranch, bIgnoreChangeIds=False):
    sCurrentBranch = git.getCurrentBranch()
    if not sCurrentBranch:
        sCurrentBranch = "tmp.%06d" % random.randrange(1e6)
        subprocess.run(["git", "checkout", "-b", sCurrentBranch], check=True)
        bDeleteBranch = True
    else:
        bDeleteBranch = False

    subprocess.run(["git", "checkout", "--detach", sTargetBranch], check=True)
    lChangeIds = cherry(
        sCurrentBranch).values() if not bIgnoreChangeIds else []
    for sCommitIdToPick, sChangeId in cherry("HEAD",
                                             sHead=sCurrentBranch).items():
        if sChangeId in lChangeIds:
            continue
        git.cherryPick(sCommitIdToPick,
                       xOnAbort=lambda: subprocess.run(
                           ["git", "checkout", sCurrentBranch], check=True))

    if bDeleteBranch:
        subprocess.run(["git", "branch", "-D", sCurrentBranch])
    else:
        subprocess.run(["git", "checkout", "-B", sCurrentBranch], check=True)
예제 #19
0
 def topic():
     sRepoName = os.path.basename(os.getcwd())
     dTopics[sRepoName] = strOrDefault(git.getCurrentBranch(), "(none)")
예제 #20
0
 def SWITCH(self):
     print(
         "Switching topic: %s -> %s" %
         (strOrDefault(git.getCurrentBranch(), "(none)"), self.oArgs.topic))
     subprocess.run(["git", "checkout", self.oArgs.topic], check=True)
예제 #21
0
 def START(self):
     print(
         "Creating new topic: %s -> %s" %
         (strOrDefault(git.getCurrentBranch(), "(none)"), self.oArgs.topic))
     subprocess.run(["git", "checkout", "-b", self.oArgs.topic], check=True)