Newer
Older
QTC_ASSERT(state.hasTopLevel(), return);
cleanRepository(state.topLevel());
}
void GitPlugin::cleanRepository(const QString &directory)
{
// Find files to be deleted
QString errorMessage;
QStringList files;
QApplication::setOverrideCursor(Qt::WaitCursor);
const bool gotFiles = m_gitClient->synchronousCleanList(directory, &files, &ignoredFiles, &errorMessage);
QApplication::restoreOverrideCursor();
QMessageBox::warning(parent, tr("Unable to retrieve file list"), errorMessage);
if (files.isEmpty() && ignoredFiles.isEmpty()) {
QMessageBox::information(parent, tr("Repository Clean"),
tr("The repository is clean."));
return;
}
// Show in dialog
dialog.setFileList(directory, files, ignoredFiles);
dialog.exec();
}
// If the file is modified in an editor, make sure it is saved.
static bool ensureFileSaved(const QString &fileName)
{
const QList<Core::IEditor*> editors = Core::EditorManager::instance()->editorsForFileName(fileName);
if (editors.isEmpty())
return true;
Core::IDocument *document = editors.front()->document();
if (!document || !document->isModified())
return true;
bool canceled;
QList<Core::IDocument *> documents;
documents << document;
Core::DocumentManager::saveModifiedDocuments(documents, &canceled);
return !canceled;
}
void GitPlugin::applyCurrentFilePatch()
{
QTC_ASSERT(state.hasPatchFile() && state.hasTopLevel(), return);
const QString patchFile = state.currentPatchFile();
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
GitClient::StashGuard stashGuard(workingDirectory, QLatin1String("Apply-Patch"));
if (stashGuard.stashingFailed(false))
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));
outwin->append(errorMessage);
} else {
outwin->appendError(errorMessage);
}
}
void GitPlugin::stash()
{
// Simple stash without prompt, reset repo.
QTC_ASSERT(state.hasTopLevel(), return);
QString id;
gitClient()->ensureStash(state.topLevel(), QString(), false, &id);
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();
m_changeSelectionDialog->setWorkingDirectory(state.currentDirectoryOrTopLevel());
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;
}
#include <QTextBlock>
#include <QTextDocument>
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);
QTest::newRow("??") << FileStates(UntrackedFile) << FileStates(UnknownFileState);
// 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);
}
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
void GitPlugin::testDiffFileResolving_data()
{
QTest::addColumn<QByteArray>("header");
QTest::addColumn<QByteArray>("fileName");
QTest::newRow("New") << QByteArray(
"diff --git a/src/plugins/git/giteditor.cpp b/src/plugins/git/giteditor.cpp\n"
"new file mode 100644\n"
"index 0000000..40997ff\n"
"--- /dev/null\n"
"+++ b/src/plugins/git/giteditor.cpp\n"
"@@ -0,0 +1,281 @@\n\n")
<< QByteArray("src/plugins/git/giteditor.cpp");
QTest::newRow("Deleted") << QByteArray(
"diff --git a/src/plugins/git/giteditor.cpp b/src/plugins/git/giteditor.cpp\n"
"deleted file mode 100644\n"
"index 40997ff..0000000\n"
"--- a/src/plugins/git/giteditor.cpp\n"
"+++ /dev/null\n"
"@@ -1,281 +0,0 @@\n\n")
<< QByteArray("src/plugins/git/giteditor.cpp");
QTest::newRow("Normal") << QByteArray(
"diff --git a/src/plugins/git/giteditor.cpp b/src/plugins/git/giteditor.cpp\n"
"index 69e0b52..8fc974d 100644\n"
"--- a/src/plugins/git/giteditor.cpp\n"
"+++ b/src/plugins/git/giteditor.cpp\n"
"@@ -49,6 +49,8 @@\n\n")
<< QByteArray("src/plugins/git/giteditor.cpp");
}
void GitPlugin::testDiffFileResolving()
{
GitEditor editor(editorParameters + 3, 0);
void GitPlugin::testLogResolving()
{
QByteArray data(
"commit 50a6b54c03219ad74b9f3f839e0321be18daeaf6 (HEAD, origin/master)\n"
"Merge: 3587b51 bc93ceb\n"
"Author: Junio C Hamano <gitster@pobox.com>\n"
"Date: Fri Jan 25 12:53:31 2013 -0800\n"
"\n"
" Merge branch 'for-junio' of git://bogomips.org/git-svn\n"
" \n"
" * 'for-junio' of git://bogomips.org/git-svn:\n"
" git-svn: Simplify calculation of GIT_DIR\n"
" git-svn: cleanup sprintf usage for uppercasing hex\n"
"\n"
"commit 3587b513bafd7a83d8c816ac1deed72b5e3a27e9\n"
"Author: Junio C Hamano <gitster@pobox.com>\n"
"Date: Fri Jan 25 12:52:55 2013 -0800\n"
"\n"
" Update draft release notes to 1.8.2\n"
" \n"
" Signed-off-by: Junio C Hamano <gitster@pobox.com>\n"
);
GitEditor editor(editorParameters + 1, 0);
editor.testLogResolving(data,
"50a6b54c - Merge branch 'for-junio' of git://bogomips.org/git-svn",
"3587b513 - Update draft release notes to 1.8.2");