Beispiel #1
0
def main():
    " This method launches gitbuster."
    app = QApplication(sys.argv)

    if len(sys.argv) == 2 and is_top_git_directory(sys.argv[1]):
        filepath = os.path.abspath(sys.argv[1])
    else:
        filepath = select_git_directory()

    if not filepath:
        sys.exit(1)

    test_repo = Repo(filepath)
    if os.path.exists(os.path.join(filepath, ".git/rebase-merge")):
        # Special conflict mode
        os.chdir(filepath)
        orig_hexsha = open(".git/rebase-merge/head").read().strip()
        conflict_hexsha = open(".git/rebase-merge/stopped-sha").read().strip()
        unmerged_files = get_unmerged_files(conflict_hexsha, orig_hexsha,
                                            filepath)
        conflicts_dialog = ConflictsDialog(unmerged_files)
        ret = conflicts_dialog.exec_()
        if ret:
            solutions = conflicts_dialog.get_solutions()
            apply_solutions(solutions)
            print "Applied your solutions, you can now continue:"
            print "git rebase --continue"
        sys.exit()

    if test_repo.is_dirty():
        warning_title = "Unclean repository"
        warning_text = "The chosen repository has unstaged changes. " \
                       "You should commit or stash them. "\
                       "Do you want to continue anyway ?"
        warning_choice = QMessageBox.warning(None, warning_title,
                                             warning_text,
                                             "Yes",
                                             button1Text="No",
                                             button2Text ="Stash")

        if warning_choice == 1:
            sys.exit(2)
        elif warning_choice == 2:
            test_repo.git.stash()

    window = MainWindow(directory=filepath, debug=True)
    window.show()

    #reroute SIGINT to Qt.
    def quit(signum, frame):
        # Clean the repo : stages, tmp_rebase, remotes
        window._ui.actionQuit.trigger()
    signal.signal(signal.SIGINT, quit)

    #run app and exit with same code
    sys.exit(app.exec_())
    def ref_update(self, commit):
        """
            Update the commit, probably since one of it's parents has changed.
        """
        model = self._model

        parents = model.c_data(commit, "parents")

        if model.is_deleted(commit):
            # If the commit has been deleted, skip it
            if self._last_updated_sha:
                # We don't need to set the last updated sha
                return True

            # The last updated sha hasn't be set, meaning that this may be
            # the top commit.
            if parents[0] in self._updated_refs:
                self._last_updated_sha = self._updated_refs[parents[0]]
            else:
                hexsha = model.c_data(parents[0], "hexsha")
                self._last_updated_sha = hexsha

            return True

        if len(parents) != 1:
            # This is a merge
            for parent in parents:
                if parent in self._should_be_updated and \
                   parent not in self._updated_refs:
                    # Meaning one of the parent branches of the merge hasn't
                    # been rewritten yet => skip for now
                    return True

        # The following will be useful to query the model
        commit_row = model.row_of(commit)

        # Here the parent should be the one defined in the mode (we should call
        # data()). Otherwise, we won't be able to insert or delete commits.
        _parent = parents[0]
        if _parent in self._updated_refs:
            _parent_sha = self._updated_refs[_parent]
        else:
            _parent_sha = self._model.c_data(_parent, "hexsha")

        self.run_command("git checkout -f %s" % _parent_sha)

        to_pick_hexsha = model.c_data(commit, "hexsha")
        if len(parents) == 1:
            # This is not a merge
            pick_command = "git cherry-pick -n %s" % to_pick_hexsha
        else:
            # This is a merge
            pick_command = "git cherry-pick -n -m 1 %s" % to_pick_hexsha

        output, errors = self.run_command(pick_command)
        if [line for line in errors if "error: could not apply" in line]:
            # We have a merge conflict.
            model.set_conflicting_commit(commit_row)
            commit = model.get_conflicting_commit()
            if commit in self._solutions:
                apply_solutions(self._solutions[commit])
            else:
                # Find out what were the hexsha of the conflicting commit
                # and of it's parent, in order to find the diff.
                self.process_unmerged_state(_parent_sha)
                self.cleanup_repo()
                return False

        output, errors = self.run_command("git write-tree")
        new_tree = output[0].strip()

        parent_string = ""
        for parent in parents:
            if parent in self._updated_refs:
                _parent = self._updated_refs[parent]
            else:
                _parent = self._model.c_data(parent, "hexsha")

            parent_string += "-p %s " % _parent

        FIELDS, MESSAGE = self.prepare_arguments(commit_row)
        with open("tmp_message", "w") as handle:
            handle.write(MESSAGE)

        output, errors = self.run_command(FIELDS +
                                        "git commit-tree %s %s < tmp_message" %
                                        (new_tree, parent_string))
        new_sha = output[0].strip()
        self._last_updated_sha = new_sha
        self._updated_refs[commit] = new_sha

        self._progress += 1. / self._to_rewrite_count
        for _commit in self._model.c_data(commit, "children"):
            if not self.ref_update(_commit):
                return False

        return True