Newer
Older
if (!ensureFileSaved(patchFile))
return;
applyPatch(state.topLevel(), patchFile);
}
void GitPlugin::promptApplyPatch()
{
QTC_ASSERT(state.hasTopLevel(), return);
applyPatch(state.topLevel(), QString());
}
void GitPlugin::applyPatch(const QString &workingDirectory, QString file)
{
// Ensure user has been notified about pending changes
switch (m_gitClient->ensureStash(workingDirectory)) {
case GitClient::StashUnchanged:
case GitClient::Stashed:
case GitClient::NotStashed:
break;
default:
return;
}
// Prompt for file
if (file.isEmpty()) {
const QString filter = tr("Patches (*.patch *.diff)");
file = QFileDialog::getOpenFileName(Core::ICore::mainWindow(),
QString(), filter);
if (file.isEmpty())
return;
}
// Run!
VcsBase::VcsBaseOutputWindow *outwin = VcsBase::VcsBaseOutputWindow::instance();
QString errorMessage;
if (m_gitClient->synchronousApplyPatch(workingDirectory, file, &errorMessage)) {
if (errorMessage.isEmpty()) {
outwin->append(tr("Patch %1 successfully applied to %2").arg(file, workingDirectory));
} else {
outwin->append(errorMessage);
}
} else {
outwin->appendError(errorMessage);
}
}
void GitPlugin::stash()
{
// Simple stash without prompt, reset repo.
QTC_ASSERT(state.hasTopLevel(), return);
const QString id = m_gitClient->synchronousStash(state.topLevel(), QString(), 0);
if (!id.isEmpty() && m_stashDialog)
m_stashDialog->refresh(state.topLevel(), true);
}
void GitPlugin::stashSnapshot()
{
// Prompt for description, restore immediately and keep on working.
QTC_ASSERT(state.hasTopLevel(), return);
const QString id = m_gitClient->synchronousStash(state.topLevel(), QString(), GitClient::StashImmediateRestore|GitClient::StashPromptDescription);
if (!id.isEmpty() && m_stashDialog)
m_stashDialog->refresh(state.topLevel(), true);
}
// Create a non-modal dialog with refresh method or raise if it exists
template <class NonModalDialog>
inline void showNonModalDialog(const QString &topLevel,
QPointer<NonModalDialog> &dialog)
{
if (dialog) {
dialog->show();
dialog->raise();
} else {
dialog = new NonModalDialog(Core::ICore::mainWindow());
dialog->refresh(topLevel, true);
dialog->show();
}
}
void GitPlugin::branchList()
{
showNonModalDialog(currentState().topLevel(), m_branchDialog);
}
void GitPlugin::remoteList()
{
showNonModalDialog(currentState().topLevel(), m_remoteDialog);
}
void GitPlugin::stashList()
{
showNonModalDialog(currentState().topLevel(), m_stashDialog);
void GitPlugin::updateActions(VcsBase::VcsBasePlugin::ActionState as)
const bool repositoryEnabled = currentState().hasTopLevel();
if (m_stashDialog)
m_stashDialog->refresh(currentState().topLevel(), false);
if (m_branchDialog)
m_branchDialog->refresh(currentState().topLevel(), false);
if (m_remoteDialog)
m_remoteDialog->refresh(currentState().topLevel(), false);
m_commandLocator->setEnabled(repositoryEnabled);
if (!enableMenuAction(as, m_menuAction))
// Note: This menu is visible if there is no repository. Only
// 'Create Repository'/'Show' actions should be available.
const QString fileName = currentState().currentFileName();
foreach (Utils::ParameterAction *fileAction, m_fileActions)
fileAction->setParameter(fileName);
// If the current file looks like a patch, offer to apply
m_applyCurrentFilePatchAction->setParameter(currentState().currentPatchFileDisplayName());
const QString projectName = currentState().currentProjectName();
foreach (Utils::ParameterAction *projectAction, m_projectActions)
projectAction->setParameter(projectName);
foreach (QAction *repositoryAction, m_repositoryActions)
repositoryAction->setEnabled(repositoryEnabled);
updateRepositoryBrowserAction();
// Prompts for repo.
m_showAction->setEnabled(true);
void GitPlugin::updateRepositoryBrowserAction()
{
const bool repositoryEnabled = currentState().hasTopLevel();
const bool hasRepositoryBrowserCmd = !settings().stringValue(GitSettings::repositoryBrowserCmd).isEmpty();
m_repositoryBrowserAction->setEnabled(repositoryEnabled && hasRepositoryBrowserCmd);
}
if (!m_changeSelectionDialog)
m_changeSelectionDialog = new ChangeSelectionDialog();
if (state.hasFile())
m_changeSelectionDialog->setWorkingDirectory(state.currentFileDirectory());
else if (state.hasTopLevel())
m_changeSelectionDialog->setWorkingDirectory(state.topLevel());
if (m_changeSelectionDialog->exec() != QDialog::Accepted)
return;
const QString change = m_changeSelectionDialog->change();
if (change.isEmpty())
m_gitClient->show(m_changeSelectionDialog->workingDirectory(), change);
const GitSettings &GitPlugin::settings() const
}
void GitPlugin::setSettings(const GitSettings &s)
{
if (s == m_settings)
return;
m_settings = s;
static_cast<GitVersionControl *>(versionControl())->emitConfigurationChanged();
updateRepositoryBrowserAction();
}
GitClient *GitPlugin::gitClient() const
{
return m_gitClient;
}
#ifdef WITH_TESTS
#include <QTest>
void GitPlugin::testStatusParsing_data()
{
QTest::addColumn<FileStates>("first");
QTest::addColumn<FileStates>("second");
QTest::newRow(" M") << FileStates(ModifiedFile) << FileStates(UnknownFileState);
QTest::newRow(" D") << FileStates(DeletedFile) << FileStates(UnknownFileState);
QTest::newRow("M ") << (ModifiedFile | StagedFile) << FileStates(UnknownFileState);
QTest::newRow("MM") << (ModifiedFile | StagedFile) << FileStates(ModifiedFile);
QTest::newRow("MD") << (ModifiedFile | StagedFile) << FileStates(DeletedFile);
QTest::newRow("A ") << (AddedFile | StagedFile) << FileStates(UnknownFileState);
QTest::newRow("AM") << (AddedFile | StagedFile) << FileStates(ModifiedFile);
QTest::newRow("AD") << (AddedFile | StagedFile) << FileStates(DeletedFile);
QTest::newRow("D ") << (DeletedFile | StagedFile) << FileStates(UnknownFileState);
QTest::newRow("DM") << (DeletedFile | StagedFile) << FileStates(ModifiedFile);
QTest::newRow("R ") << (RenamedFile | StagedFile) << FileStates(UnknownFileState);
QTest::newRow("RM") << (RenamedFile | StagedFile) << FileStates(ModifiedFile);
QTest::newRow("RD") << (RenamedFile | StagedFile) << FileStates(DeletedFile);
QTest::newRow("C ") << (CopiedFile | StagedFile) << FileStates(UnknownFileState);
QTest::newRow("CM") << (CopiedFile | StagedFile) << FileStates(ModifiedFile);
QTest::newRow("CD") << (CopiedFile | StagedFile) << FileStates(DeletedFile);
// Merges
QTest::newRow("DD") << (DeletedFile | UnmergedFile | UnmergedUs | UnmergedThem) << FileStates(UnknownFileState);
QTest::newRow("AA") << (AddedFile | UnmergedFile | UnmergedUs | UnmergedThem) << FileStates(UnknownFileState);
QTest::newRow("UU") << (ModifiedFile | UnmergedFile | UnmergedUs | UnmergedThem) << FileStates(UnknownFileState);
QTest::newRow("AU") << (AddedFile | UnmergedFile | UnmergedUs) << FileStates(UnknownFileState);
QTest::newRow("UD") << (DeletedFile | UnmergedFile | UnmergedThem) << FileStates(UnknownFileState);
QTest::newRow("UA") << (AddedFile | UnmergedFile | UnmergedThem) << FileStates(UnknownFileState);
QTest::newRow("DU") << (DeletedFile | UnmergedFile | UnmergedUs) << FileStates(UnknownFileState);
}
void GitPlugin::testStatusParsing()
{
CommitData data;
QFETCH(FileStates, first);
QFETCH(FileStates, second);
QString output = QLatin1String("## master...origin/master [ahead 1]\n");
output += QString::fromLatin1(QTest::currentDataTag()) + QLatin1String(" main.cpp\n");
data.parseFilesFromStatus(output);
QCOMPARE(data.files.at(0).first, first);
if (second == UnknownFileState)
QCOMPARE(data.files.size(), 1);
else
QCOMPARE(data.files.at(1).first, second);
}
#endif