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); } }
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); }
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); }
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; }
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; }
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; }
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()); }
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; }
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); }
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); }
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(); }
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; }