Example #1
0
void GitEditorWidget::applyDiffChunk(const DiffChunk& chunk, bool revert)
{
    QTemporaryFile patchFile;
    if (!patchFile.open())
        return;

    const QString baseDir = workingDirectory();
    patchFile.write(chunk.header);
    patchFile.write(chunk.chunk);
    patchFile.close();

    GitClient *client = GitPlugin::instance()->client();
    QStringList args = QStringList() << QLatin1String("--cached");
    if (revert)
        args << QLatin1String("--reverse");
    QString errorMessage;
    if (client->synchronousApplyPatch(baseDir, patchFile.fileName(), &errorMessage, args)) {
        if (errorMessage.isEmpty())
            VcsOutputWindow::append(tr("Chunk successfully staged"));
        else
            VcsOutputWindow::append(errorMessage);
        if (revert)
            emit diffChunkReverted(chunk);
        else
            emit diffChunkApplied(chunk);
    } else {
        VcsOutputWindow::appendError(errorMessage);
    }
}
Example #2
0
void BranchUtils::rebase()
{
    if (!Core::DocumentManager::saveAllModifiedDocuments())
        return;
    const QModelIndex selected = selectedIndex();
    QTC_CHECK(selected != m_model->currentBranch());

    const QString baseBranch = m_model->fullName(selected, true);
    GitClient *client = GitPlugin::client();
    if (client->beginStashScope(m_repository, "rebase"))
        client->rebase(m_repository, baseBranch);
}
Example #3
0
void BranchDialog::rebase()
{
    if (!Core::DocumentManager::saveAllModifiedDocuments())
        return;
    QModelIndex idx = selectedIndex();
    QTC_CHECK(idx != m_model->currentBranch()); // otherwise the button would not be enabled!

    const QString baseBranch = m_model->fullName(idx, true);
    GitClient *client = GitPlugin::instance()->gitClient();
    if (client->beginStashScope(m_repository, QLatin1String("rebase")))
        client->rebase(m_repository, baseBranch);
}
Example #4
0
bool BranchUtils::merge(bool allowFastForward)
{
    if (!Core::DocumentManager::saveAllModifiedDocuments())
        return false;
    const QModelIndex selected = selectedIndex();
    QTC_CHECK(selected != m_model->currentBranch());

    const QString branch = m_model->fullName(selected, true);
    GitClient *client = GitPlugin::client();
    if (client->beginStashScope(m_repository, "merge", AllowUnstashed))
        return client->synchronousMerge(m_repository, branch, allowFastForward);

    return false;
}
Example #5
0
QStringList GitEditorWidget::annotationPreviousVersions(const QString &revision) const
{
    QStringList revisions;
    QString errorMessage;
    GitClient *client = GitPlugin::instance()->client();
    const QFileInfo fi(source());
    const QString workingDirectory = fi.absolutePath();
    // Get the SHA1's of the file.
    if (!client->synchronousParentRevisions(workingDirectory, QStringList(fi.fileName()),
                                            revision, &revisions, &errorMessage)) {
        VcsOutputWindow::appendSilently(errorMessage);
        return QStringList();
    }
    return revisions;
}
Example #6
0
bool LogChangeDialog::runDialog(const QString &repository,
                                const QString &commit,
                                LogChangeWidget::LogFlags flags)
{
    if (!m_widget->init(repository, commit, flags))
        return false;

    if (QDialog::exec() == QDialog::Accepted) {
        if (m_resetTypeComboBox) {
            GitClient *client = GitPlugin::instance()->client();
            client->settings().setValue(GitSettings::lastResetIndexKey,
                                        m_resetTypeComboBox->currentIndex());
        }
        return true;
    }
    return false;
}
Example #7
0
void GitEditorWidget::resetChange(const QByteArray &resetType)
{
    const QString workingDir = sourceWorkingDirectory();

    GitClient *client = GitPlugin::instance()->client();
    if (resetType == "hard"
            && client->gitStatus(workingDir, StatusMode(NoUntracked | NoSubmodules))
            != GitClient::StatusUnchanged) {
        if (QMessageBox::question(
                    Core::ICore::mainWindow(), tr("Reset"),
                    tr("All changes in working directory will be discarded. Are you sure?"),
                    QMessageBox::Yes | QMessageBox::No,
                    QMessageBox::No) == QMessageBox::No) {
            return;
        }
    }
    client->reset(workingDir, QLatin1String("--" + resetType), m_currentChange);
}
void ChangeSelectionDialog::recalculateCompletion()
{
    const QString workingDir = workingDirectory();
    if (workingDir == m_oldWorkingDir)
        return;
    m_oldWorkingDir = workingDir;

    if (!workingDir.isEmpty()) {
        GitClient *client = GitPlugin::instance()->client();
        QStringList args;
        args << QLatin1String("--format=%(refname:short)");
        QString output;
        if (client->synchronousForEachRefCmd(workingDir, args, &output)) {
            m_changeModel->setStringList(output.split(QLatin1Char('\n')));
            return;
        }
    }
    m_changeModel->setStringList(QStringList());
}
Example #9
0
bool LogChangeWidget::populateLog(const QString &repository, const QString &commit, LogFlags flags)
{
    const QString currentCommit = this->commit();
    int selected = currentCommit.isEmpty() ? 0 : -1;
    if (const int rowCount = m_model->rowCount())
        m_model->removeRows(0, rowCount);

    // Retrieve log using a custom format "Sha1:Subject [(refs)]"
    GitClient *client = GitPlugin::instance()->client();
    QStringList arguments;
    arguments << QLatin1String("--max-count=1000") << QLatin1String("--format=%h:%s %d");
    arguments << (commit.isEmpty() ? QLatin1String("HEAD") : commit);
    if (!(flags & IncludeRemotes))
        arguments << QLatin1String("--not") << QLatin1String("--remotes");
    QString output;
    if (!client->synchronousLog(repository, arguments, &output, 0, VcsCommand::NoOutput))
        return false;
    foreach (const QString &line, output.split(QLatin1Char('\n'))) {
        const int colonPos = line.indexOf(QLatin1Char(':'));
        if (colonPos != -1) {
            QList<QStandardItem *> row;
            for (int c = 0; c < ColumnCount; ++c) {
                auto item = new QStandardItem;
                item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
                if (line.endsWith(QLatin1Char(')'))) {
                    QFont font = item->font();
                    font.setBold(true);
                    item->setFont(font);
                }
                row.push_back(item);
            }
            const QString sha1 = line.left(colonPos);
            row[Sha1Column]->setText(sha1);
            row[SubjectColumn]->setText(line.right(line.size() - colonPos - 1));
            m_model->appendRow(row);
            if (selected == -1 && currentCommit == sha1)
                selected = m_model->rowCount() - 1;
        }
    }
    setCurrentIndex(m_model->index(selected, 0));
    return true;
}
QStringList GitEditor::annotationPreviousVersions(const QString &revision) const
{
    QStringList revisions;
    QString errorMessage;
    GitClient *client = GitPlugin::instance()->gitClient();
    const QFileInfo fi(source());
    const QString workingDirectory = fi.absolutePath();
    // Get the SHA1's of the file.
    if (!client->synchronousParentRevisions(workingDirectory, QStringList(fi.fileName()),
                                            revision, &revisions, &errorMessage)) {
        VCSBase::VCSBaseOutputWindow::instance()->appendSilently(errorMessage);
        return QStringList();
    }
    // Format verbose, SHA1 being first token
    QStringList descriptions;
    if (!client->synchronousShortDescriptions(workingDirectory, revisions, &descriptions, &errorMessage)) {
        VCSBase::VCSBaseOutputWindow::instance()->appendSilently(errorMessage);
        return QStringList();
    }
    return descriptions;
}
Example #11
0
void BranchDialog::merge()
{
    if (!Core::DocumentManager::saveAllModifiedDocuments())
        return;
    QModelIndex idx = selectedIndex();
    QTC_CHECK(idx != m_model->currentBranch()); // otherwise the button would not be enabled!

    const QString branch = m_model->fullName(idx, true);
    GitClient *client = GitPlugin::instance()->gitClient();
    bool allowFastForward = true;
    if (client->isFastForwardMerge(m_repository, branch)) {
        QMenu popup;
        QAction *fastForward = popup.addAction(tr("Fast-Forward"));
        popup.addAction(tr("No Fast-Forward"));
        QAction *chosen = Utils::execMenuAtWidget(&popup, m_ui->mergeButton);
        if (!chosen)
            return;
        allowFastForward = (chosen == fastForward);
    }
    if (client->beginStashScope(m_repository, QLatin1String("merge"), AllowUnstashed))
        client->synchronousMerge(m_repository, branch, allowFastForward);
}
Example #12
0
LogChangeDialog::LogChangeDialog(bool isReset, QWidget *parent) :
    QDialog(parent)
    , m_widget(new LogChangeWidget)
    , m_dialogButtonBox(new QDialogButtonBox(this))
    , m_resetTypeComboBox(0)
{
    auto layout = new QVBoxLayout(this);
    layout->addWidget(new QLabel(isReset ? tr("Reset to:") : tr("Select change:"), this));
    layout->addWidget(m_widget);
    auto popUpLayout = new QHBoxLayout;
    if (isReset) {
        popUpLayout->addWidget(new QLabel(tr("Reset type:"), this));
        m_resetTypeComboBox = new QComboBox(this);
        m_resetTypeComboBox->addItem(tr("Hard"), QLatin1String("--hard"));
        m_resetTypeComboBox->addItem(tr("Mixed"), QLatin1String("--mixed"));
        m_resetTypeComboBox->addItem(tr("Soft"), QLatin1String("--soft"));
        GitClient *client = GitPlugin::instance()->client();
        m_resetTypeComboBox->setCurrentIndex(client->settings().intValue(
                                                 GitSettings::lastResetIndexKey));
        popUpLayout->addWidget(m_resetTypeComboBox);
        popUpLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Ignored));
    }

    popUpLayout->addWidget(m_dialogButtonBox);
    m_dialogButtonBox->addButton(QDialogButtonBox::Cancel);
    QPushButton *okButton = m_dialogButtonBox->addButton(QDialogButtonBox::Ok);
    layout->addLayout(popUpLayout);

    connect(m_dialogButtonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
    connect(m_dialogButtonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);

    connect(m_widget, &LogChangeWidget::activated, okButton, [okButton] { okButton->animateClick(); });

    setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
    resize(600, 400);
}
Example #13
0
void BranchDialog::checkout()
{
    if (!Core::DocumentManager::saveAllModifiedDocuments())
        return;
    QModelIndex idx = selectedIndex();

    const QString currentBranch = m_model->fullName(m_model->currentBranch());
    const QString nextBranch = m_model->fullName(idx);
    const QString popMessageStart = QCoreApplication::applicationName() +
            QLatin1String(" ") + nextBranch + QLatin1String("-AutoStash ");

    BranchCheckoutDialog branchCheckoutDialog(this, currentBranch, nextBranch);
    GitClient *gitClient = GitPlugin::instance()->gitClient();

    if (gitClient->gitStatus(m_repository, StatusMode(NoUntracked | NoSubmodules)) != GitClient::StatusChanged)
        branchCheckoutDialog.foundNoLocalChanges();

    QList<Stash> stashes;
    gitClient->synchronousStashList(m_repository, &stashes);
    foreach (const Stash &stash, stashes) {
        if (stash.message.startsWith(popMessageStart)) {
            branchCheckoutDialog.foundStashForNextBranch();
            break;
        }
    }

    if (!branchCheckoutDialog.hasLocalChanges() &&
        !branchCheckoutDialog.hasStashForNextBranch()) {
        // No local changes and no Auto Stash - no need to open dialog
        m_model->checkoutBranch(idx);
    } else if (branchCheckoutDialog.exec() == QDialog::Accepted) {

        if (branchCheckoutDialog.makeStashOfCurrentBranch()) {
            if (gitClient->synchronousStash(m_repository,
                           currentBranch + QLatin1String("-AutoStash")).isEmpty()) {
                return;
            }
        } else if (branchCheckoutDialog.moveLocalChangesToNextBranch()) {
            if (!gitClient->beginStashScope(m_repository, QLatin1String("Checkout"), NoPrompt))
                return;
        } else if (branchCheckoutDialog.discardLocalChanges()) {
            if (!gitClient->synchronousReset(m_repository))
                return;
        }

        m_model->checkoutBranch(idx);

        QString stashName;
        gitClient->synchronousStashList(m_repository, &stashes);
        foreach (const Stash &stash, stashes) {
            if (stash.message.startsWith(popMessageStart)) {
                stashName = stash.name;
                break;
            }
        }

        if (branchCheckoutDialog.moveLocalChangesToNextBranch())
            gitClient->endStashScope(m_repository);
        else if (branchCheckoutDialog.popStashOfNextBranch())
            gitClient->synchronousStashRestore(m_repository, stashName, true);
    }
    enableButtons();
}
Example #14
0
bool BranchUtils::checkout()
{
    if (!Core::DocumentManager::saveAllModifiedDocuments())
        return false;

    const QModelIndex selected = selectedIndex();
    const QString currentBranch = m_model->fullName(m_model->currentBranch());
    const QString nextBranch = m_model->fullName(selected);
    const QString popMessageStart = QCoreApplication::applicationName() +
            ' ' + nextBranch + "-AutoStash ";

    BranchCheckoutDialog branchCheckoutDialog(m_widget, currentBranch, nextBranch);
    GitClient *client = GitPlugin::client();

    if (client->gitStatus(m_repository, StatusMode(NoUntracked | NoSubmodules)) != GitClient::StatusChanged)
        branchCheckoutDialog.foundNoLocalChanges();

    QList<Stash> stashes;
    client->synchronousStashList(m_repository, &stashes);
    for (const Stash &stash : qAsConst(stashes)) {
        if (stash.message.startsWith(popMessageStart)) {
            branchCheckoutDialog.foundStashForNextBranch();
            break;
        }
    }

    if (!branchCheckoutDialog.hasLocalChanges() &&
        !branchCheckoutDialog.hasStashForNextBranch()) {
        // No local changes and no Auto Stash - no need to open dialog
        m_model->checkoutBranch(selected);
    } else if (branchCheckoutDialog.exec() == QDialog::Accepted) {

        if (branchCheckoutDialog.makeStashOfCurrentBranch()) {
            if (client->synchronousStash(m_repository, currentBranch + "-AutoStash").isEmpty())
                return false;
        } else if (branchCheckoutDialog.moveLocalChangesToNextBranch()) {
            if (!client->beginStashScope(m_repository, "Checkout", NoPrompt))
                return false;
        } else if (branchCheckoutDialog.discardLocalChanges()) {
            if (!client->synchronousReset(m_repository))
                return false;
        }

        m_model->checkoutBranch(selected);

        QString stashName;
        client->synchronousStashList(m_repository, &stashes);
        for (const Stash &stash : qAsConst(stashes)) {
            if (stash.message.startsWith(popMessageStart)) {
                stashName = stash.name;
                break;
            }
        }

        if (branchCheckoutDialog.moveLocalChangesToNextBranch())
            client->endStashScope(m_repository);
        else if (branchCheckoutDialog.popStashOfNextBranch())
            client->synchronousStashRestore(m_repository, stashName, true);
    }

    if (QTC_GUARD(m_branchView))
        m_branchView->selectionModel()->clear();
    return true;
}