Update CMakeLists.txt, Settings.cpp, Diff.cpp, and 27 more files

This commit is contained in:
Martin Marmsoler 2022-12-29 11:35:17 +01:00
parent 4f1976c1ff
commit b6b2c3187a
30 changed files with 633 additions and 388 deletions

View File

@ -1,5 +1,6 @@
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
add_subdirectory(util)
add_subdirectory(cli)
add_subdirectory(conf)
add_subdirectory(cred)
@ -13,7 +14,6 @@ add_subdirectory(plugins)
add_subdirectory(tools)
add_subdirectory(ui)
add_subdirectory(update)
add_subdirectory(util)
add_subdirectory(watcher)
# Add executable last.

View File

@ -9,13 +9,12 @@
#include "Settings.h"
#include "ConfFile.h"
#include "Debug.h"
#include <QCoreApplication>
#include <QDir>
#include <QSettings>
#include <QStandardPaths>
#include <QDebug>
#ifdef Q_OS_WIN
#define CS Qt::CaseInsensitive
#else

View File

@ -9,9 +9,9 @@
#include "Diff.h"
#include "Patch.h"
#include "Debug.h"
#include "git2/patch.h"
#include <algorithm>
#include <QDebug>
bool containsPath(QString &str, QString &occurence, Qt::CaseSensitivity cs) {
if (str.contains(occurence, cs)) {
@ -114,7 +114,7 @@ QByteArray Diff::print() {
diff.append(line);
}
}
qDebug() << QString(diff);
Debug(QString(diff));
return diff;
}

View File

@ -316,7 +316,7 @@ signals:
void referenceAdded(const Reference &ref);
void referenceAboutToBeRemoved(const Reference &ref);
void referenceRemoved(const QString &name);
void referenceUpdated(const Reference &ref);
void referenceUpdated(const Reference &ref, bool restoreSelection = false);
void remoteAboutToBeAdded(const QString &name);
void remoteAdded(const Remote &remote);

View File

@ -1,6 +1,6 @@
add_library(tools DiffTool.cpp EditTool.cpp ExternalTool.cpp MergeTool.cpp
ShowTool.cpp)
target_link_libraries(tools conf git Qt5::Gui)
target_link_libraries(tools conf git Qt5::Gui util)
set_target_properties(tools PROPERTIES AUTOMOC ON)

View File

@ -12,12 +12,12 @@
#include "git/Config.h"
#include "git/Index.h"
#include "git/Repository.h"
#include "Debug.h"
#include <QDateTime>
#include <QDir>
#include <QFileInfo>
#include <QProcess>
#include <QTemporaryFile>
#include <QDebug>
MergeTool::MergeTool(const QString &file, const git::Blob &localBlob,
const git::Blob &remoteBlob, const git::Blob &baseBlob,
@ -116,11 +116,11 @@ bool MergeTool::start() {
arguments.append("sh");
arguments.append("-c");
arguments.append(command);
// qDebug() << "Command: " << "flatpak-spawn";
// Debug("Command: " << "flatpak-spawn");
process->start("flatpak-spawn", arguments);
// qDebug() << "QProcess Arguments: " << process->arguments();
// Debug("QProcess Arguments: " << process->arguments());
if (!process->waitForStarted()) {
qDebug() << "MergeTool starting failed";
Debug("MergeTool starting failed");
return false;
}
#else

39
src/trace.h Normal file
View File

@ -0,0 +1,39 @@
#ifndef TRACE_H
#define TRACE_H
#include <chrono>
#include <QString>
#include <iostream>
// copied from labplot project
// Thank you Alex ;)
class PerfTracer {
public:
explicit PerfTracer(QString m) {
msg = m.toStdString();
start = std::chrono::high_resolution_clock::now();
};
~PerfTracer() {
auto end = std::chrono::high_resolution_clock::now();
auto diff =
std::chrono::duration_cast<std::chrono::milliseconds>(end - start)
.count();
std::cout << msg << ": " << diff << " ms" << std::endl;
}
private:
std::chrono::high_resolution_clock::time_point start;
std::string msg;
};
#define PERFTRACE_ENABLED
#ifdef PERFTRACE_ENABLED
#define PERFTRACE(msg) PerfTracer tracer(QString(Q_FUNC_INFO) + msg)
#else
#define PERFTRACE(msg)
#endif
#define PERFTRACE_DETAILVIEW 0
#endif // TRACE_H

View File

@ -13,6 +13,7 @@
#include "MainWindow.h"
#include "ProgressIndicator.h"
#include "RepoView.h"
#include "Debug.h"
#include "app/Application.h"
#include "conf/Settings.h"
#include "dialogs/MergeDialog.h"
@ -72,6 +73,10 @@ private:
bool mCanceled = false;
};
/*!
* \brief The CommitModel class
* Model showing all commits as timeline
*/
class CommitModel : public QAbstractListModel {
Q_OBJECT
@ -92,15 +97,11 @@ public:
emit statusFinished(!mRows.isEmpty() && !mRows.first().commit.isValid());
});
git::RepositoryNotifier *notifier = repo.notifier();
connect(notifier, &git::RepositoryNotifier::referenceUpdated, this,
&CommitModel::resetReference);
connect(notifier, &git::RepositoryNotifier::workdirChanged,
[this] { resetReference(mRef); });
resetSettings();
}
void restoreSelection(bool restore) { mRestoreSelection = restore; }
git::Reference reference() const { return mRef; }
git::Diff status() const {
@ -150,9 +151,15 @@ public:
resetWalker();
}
void suppressResetWalker(bool suppress) { mSuppressResetWalker = suppress; }
bool isSuppressResetWalker() { return mSuppressResetWalker; }
void setReference(const git::Reference &ref) {
mRef = ref;
resetWalker();
if (!mSuppressResetWalker) {
resetWalker();
}
}
void resetReference(const git::Reference &ref) {
@ -165,7 +172,11 @@ public:
if (!ref.isValid() || ref.isHead())
startStatus();
resetWalker();
if (!mSuppressResetWalker) {
resetWalker();
} else {
// reset walker will be done when status finished
}
}
void resetWalker() {
@ -174,6 +185,7 @@ public:
// Reset state.
mParents.clear();
mRows.clear();
DebugRefresh("");
// Update status row.
bool head = (!mRef.isValid() || mRef.isHead());
@ -184,8 +196,8 @@ public:
row.append({Segment(Bottom, kTaintedColor), Segment(Dot, QColor())});
mParents.append(Parent(mRef.target(), nextColor(), true));
}
mRows.append(Row(git::Commit(), row));
DebugRefresh("mRows append invalid commit");
mRows.append(Row(git::Commit(), row)); // Uncommitted changes
}
// Begin walking commits.
@ -284,6 +296,7 @@ public:
row = columns(commit, parents, root);
rows.append(Row(commit, row));
DebugRefresh("Append commit: " << commit.shortId());
// Bail out.
if (i++ >= 64)
@ -546,12 +559,18 @@ private:
QList<Parent> mParents;
// walker settings
bool mSuppressResetWalker{false};
bool mRestoreSelection{true};
bool mRefsAll = true;
bool mSortDate = true;
bool mCleanStatus = true;
bool mGraphVisible = true;
};
/*!
* \brief The ListModel class
* Used to show a list of commits. This is used when a filter is used
*/
class ListModel : public QAbstractListModel {
public:
ListModel(QObject *parent = nullptr) : QAbstractListModel(parent) {}
@ -1103,7 +1122,8 @@ CommitList::CommitList(Index *index, QWidget *parent)
&CommitList::restoreSelection);
CommitModel *model = static_cast<CommitModel *>(mModel);
connect(model, &CommitModel::statusFinished, [this](bool visible) {
connect(model, &CommitModel::statusFinished, [this, model](bool visible) {
mRestoreSelection = true; // Reset to default
// Fake a selection notification if the diff is visible and selected.
if (visible && selectionModel()->isSelected(mModel->index(0, 0)))
resetSelection();
@ -1112,31 +1132,24 @@ CommitList::CommitList(Index *index, QWidget *parent)
if (selectedIndexes().isEmpty())
selectFirstCommit();
model->restoreSelection(true);
// Notify main window.
emit statusChanged(visible);
});
connect(this, &CommitList::entered,
[this](const QModelIndex &index) { update(index); });
git::RepositoryNotifier *notifier = repo.notifier();
connect(notifier, &git::RepositoryNotifier::referenceUpdated,
[this](const git::Reference &ref) {
if (!ref.isValid())
return;
if (ref.isStash())
updateModel();
if (ref.isHead()) {
QModelIndex index = this->model()->index(0, 0);
if (!index.data(CommitRole).isValid()) {
selectFirstCommit();
} else {
selectRange(ref.target().id().toString());
}
}
[this](const git::Reference &ref, bool restoreSelection) {
mRestoreSelection = restoreSelection;
resetReference(ref);
});
connect(notifier, &git::RepositoryNotifier::workdirChanged, [this] {
resetReference(static_cast<const CommitModel *>(mModel)->reference());
});
connect(this, &CommitList::entered,
[this](const QModelIndex &index) { update(index); });
#ifdef Q_OS_MAC
QFont font = this->font();
@ -1164,6 +1177,11 @@ QString CommitList::selectedRange() const {
git::Diff CommitList::selectedDiff() const {
QModelIndexList indexes = sortedIndexes();
DebugRefresh("Selected indices count: " << indexes.count());
for (const auto &index : indexes) {
const auto &id = index.data(CommitRole).value<git::Commit>().shortId();
DebugRefresh("Commit: " << id);
}
if (indexes.isEmpty())
return git::Diff();
@ -1197,8 +1215,13 @@ void CommitList::cancelStatus() {
}
void CommitList::setReference(const git::Reference &ref) {
// storeSelection(); // If it will not be called because resetWalker was
// suppressed
static_cast<CommitModel *>(mModel)->setReference(ref);
updateModel();
// restoreSelection(); // If it will not be called because resetWalker was
// suppressed
if (!isSuppressResetWalker())
updateModel();
setFocus();
}
@ -1241,6 +1264,11 @@ void CommitList::resetSelection(bool spontaneous) {
void CommitList::selectFirstCommit(bool spontaneous) {
QModelIndex index = model()->index(0, 0);
const auto commit = index.data(CommitRole).value<git::Commit>();
if (commit.isValid())
DebugRefresh("Commit id: " << commit.shortId());
else
DebugRefresh("Invalid commit");
if (index.isValid()) {
selectIndexes(QItemSelection(index, index), QString(), spontaneous);
} else {
@ -1295,6 +1323,18 @@ bool CommitList::selectRange(const QString &range, const QString &file,
return true;
}
void CommitList::suppressResetWalker(bool suppress) {
static_cast<CommitModel *>(mModel)->suppressResetWalker(suppress);
}
void CommitList::resetReference(const git::Reference &ref) {
static_cast<CommitModel *>(mModel)->resetReference(ref);
}
bool CommitList::isSuppressResetWalker() {
return static_cast<CommitModel *>(mModel)->isSuppressResetWalker();
}
void CommitList::resetSettings() {
static_cast<CommitModel *>(mModel)->resetSettings(true);
}
@ -1574,12 +1614,20 @@ void CommitList::leaveEvent(QEvent *event) {
QListView::leaveEvent(event);
}
void CommitList::storeSelection() { mSelectedRange = selectedRange(); }
void CommitList::storeSelection() {
mSelectedRange = selectedRange();
DebugRefresh("Selected Range: " << mSelectedRange);
Debug(mSelectedRange);
}
void CommitList::restoreSelection() {
// Restore selection.
if (!mSelectedRange.isEmpty() && !selectRange(mSelectedRange))
DebugRefresh(mSelectedRange);
if (!mRestoreSelection ||
(!mSelectedRange.isEmpty() && !selectRange(mSelectedRange))) {
DebugRefresh("Failed to restore");
emit diffSelected(git::Diff());
}
mSelectedRange = QString();
}

View File

@ -49,8 +49,11 @@ public:
void selectFirstCommit(bool spontaneous = false);
bool selectRange(const QString &range, const QString &file = QString(),
bool spontaneous = false);
void suppressResetWalker(bool suppress);
bool isSuppressResetWalker();
void resetSettings();
void resetReference(const git::Reference &ref);
void setModel(QAbstractItemModel *model) override;
@ -93,6 +96,8 @@ private:
QAbstractListModel *mList;
QAbstractListModel *mModel;
bool mRestoreSelection{true};
QString mSelectedRange;
};

View File

@ -422,7 +422,7 @@ void DiffView::fetchMore(int fetchWidgets) {
git::Patch patch = mDiff.patch(pidx);
if (!patch.isValid()) {
// This diff is stale. Refresh the view.
QTimer::singleShot(0, view, &RepoView::refresh);
QTimer::singleShot(0, [view]() { view->refresh(); });
return;
}

View File

@ -1,5 +1,6 @@
#include "HunkWidget.h"
#include "Line.h"
#include "Debug.h"
#include "git/Diff.h"
#include "DiffView.h"
#include "DisclosureButton.h"
@ -703,14 +704,14 @@ void HunkWidget::load(git::Patch &staged, bool force) {
return;
}
qDebug() << "Diff Header:";
Debug("Diff Header:");
for (int i = 0; i < mPatch.count(); i++) {
qDebug() << mPatch.header(i);
Debug(mPatch.header(i));
}
qDebug() << "Staged Header:";
Debug("Staged Header:");
for (int i = 0; i < mStaged.count(); i++) {
qDebug() << mStaged.header(i);
Debug(mStaged.header(i));
}
// Load hunk.
@ -804,21 +805,21 @@ void HunkWidget::load(git::Patch &staged, bool force) {
void HunkWidget::setEditorLineInfos(QList<Line> &lines,
Account::FileComments &comments,
int width) {
qDebug() << "Patch lines:" << lines.count();
Debug("Patch lines:" << lines.count());
for (int i = 0; i < lines.count(); i++) {
qDebug() << i << ") " << lines[i].print()
<< "Content: " << mPatch.lineContent(mIndex, i);
Debug(i << ") " << lines[i].print()
<< "Content: " << mPatch.lineContent(mIndex, i));
}
qDebug() << "Staged linesStaged:" << mStaged.count();
Debug("Staged linesStaged:" << mStaged.count());
for (int i = 0; i < mStaged.count(); i++) {
qDebug() << "Staged patch No. " << i;
Debug("Staged patch No. " << i);
for (int lidx = 0; lidx < mStaged.lineCount(i); lidx++) {
auto origin = mStaged.lineOrigin(i, lidx);
int oldLineStaged = mStaged.lineNumber(i, lidx, git::Diff::OldFile);
int newLineStaged = mStaged.lineNumber(i, lidx, git::Diff::NewFile);
auto line = Line(origin, oldLineStaged, newLineStaged);
qDebug() << lidx << ") " << line.print() << mStaged.lineContent(i, lidx);
Debug(lidx << ") " << line.print() << mStaged.lineContent(i, lidx));
}
}
@ -871,7 +872,7 @@ void HunkWidget::setEditorLineInfos(QList<Line> &lines,
bool first_staged_patch_match = false;
for (int lidx = 0; lidx < count; ++lidx) {
const Line &line = lines.at(lidx);
qDebug() << "Line Content: " << mPatch.lineContent(mIndex, lidx);
Debug("Line Content: " << mPatch.lineContent(mIndex, lidx));
const auto lineOrigin = line.origin();
marker = -1;
staged = false;

View File

@ -16,6 +16,7 @@
#include "TreeProxy.h"
#include "TreeView.h"
#include "ViewDelegate.h"
#include "Debug.h"
#include "conf/Settings.h"
#include "DiffView/DiffView.h"
#include "git/Index.h"
@ -301,7 +302,7 @@ QModelIndex DoubleTreeWidget::selectedIndex() const {
static void addNodeToMenu(const git::Index &index, QStringList &files,
const Node *node, bool staged, bool statusDiff) {
qDebug() << "DoubleTreeWidgetr addNodeToMenu()" << node->name();
Debug("DoubleTreeWidgetr addNodeToMenu()" << node->name());
if (node->hasChildren()) {
for (auto child : node->children()) {
@ -383,6 +384,12 @@ void DoubleTreeWidget::setDiff(const git::Diff &diff, const QString &file,
Q_UNUSED(file)
Q_UNUSED(pathspec)
mSetDiffCounter++;
DebugRefresh("DoubleTreeWidget::setDiff: time: "
<< QDateTime::currentDateTime()
<< "Counter: " << mSetDiffCounter);
mDiff = diff;
// Remember selection.

View File

@ -47,6 +47,8 @@ public:
void findNext() override;
void findPrevious() override;
uint32_t setDiffCounter() { return mSetDiffCounter; }
private slots:
void collapseCountChanged(int count);
static void showFileContextMenu(const QPoint &pos, RepoView *view,
@ -107,6 +109,8 @@ private:
int fileCountExpansionThreshold{100};
uint32_t mSetDiffCounter{0};
friend class TestTreeView;
};
#endif // DOUBLETREEWIDGET_H

View File

@ -11,6 +11,7 @@
#include "RepoView.h"
#include "IgnoreDialog.h"
#include "conf/Settings.h"
#include "Debug.h"
#include "dialogs/SettingsDialog.h"
#include "git/Diff.h"
#include "git/Index.h"
@ -45,7 +46,7 @@ void handlePath(const git::Repository &repo, const QString &path,
const git::Diff &diff, QStringList &modified,
QStringList &untracked) {
auto fullPath = repo.workdir().absoluteFilePath(path);
qDebug() << "FileContextMenu handlePath()" << path;
Debug("FileContextMenu handlePath()" << path);
if (QFileInfo(fullPath).isDir()) {
auto dir = QDir(path);

View File

@ -1,11 +1,11 @@
#include "ReferenceModel.h"
#include "Debug.h"
#include "git/Signature.h"
#include "git/Tag.h"
#include "git/Branch.h"
#include "git/TagRef.h"
#include <QDateTime>
#include <QDebug>
namespace {
const QString kNowrapFmt = "<span style='white-space: nowrap'>%1</span>";
@ -87,7 +87,7 @@ void ReferenceModel::update() {
if (mKinds & ReferenceView::LocalBranches) {
QList<git::Reference> branches;
foreach (const git::Branch &branch, mRepo.branches(GIT_BRANCH_LOCAL)) {
qDebug() << "ReferenceView: Local branches: " << branch.name();
Debug("ReferenceView: Local branches: " << branch.name());
const bool branchOnCommit =
!mCommit.isValid() || branch.annotatedCommit().commit() == mCommit;
if ((!(mKinds & ReferenceView::ExcludeHead) || !branch.isHead()) &&
@ -121,7 +121,7 @@ void ReferenceModel::update() {
QList<git::Reference> remotes;
foreach (const git::Branch &branch, mRepo.branches(GIT_BRANCH_REMOTE)) {
// Filter remote HEAD branches.
qDebug() << "ReferenceView: Remote branches: " << branch.name();
Debug("ReferenceView: Remote branches: " << branch.name());
const bool remoteOnCommit =
!mCommit.isValid() || branch.annotatedCommit().commit() == mCommit;
if (!branch.name().endsWith("HEAD") && remoteOnCommit)
@ -139,7 +139,7 @@ void ReferenceModel::update() {
if (mKinds & ReferenceView::Tags) {
QList<git::Reference> tags;
foreach (const git::TagRef &tag, mRepo.tags()) {
qDebug() << "ReferenceView: Tags: " << tag.name();
Debug("ReferenceView: Tags: " << tag.name());
const bool tagOnCommit =
!mCommit.isValid() || tag.annotatedCommit().commit() == mCommit;
if (tagOnCommit)

View File

@ -173,25 +173,27 @@ ReferenceWidget::ReferenceWidget(const git::Repository &repo,
if (!currentReference().isValid())
select(mRepo.head());
});
}
// Update the label when the reference changes.
connect(this, &ReferenceWidget::referenceChanged,
[this](const git::Reference &ref) {
if (!ref.isValid()) {
mLabel->setText(QString());
return;
}
/*!
* \brief ReferenceWidget::updateReference
* Update Label
* \param ref
*/
void ReferenceWidget::updateLabel(const git::Reference &ref) {
if (!ref.isValid()) {
mLabel->setText(QString());
return;
}
QPalette palette = this->palette();
QString enabled = palette.color(QPalette::Text).name();
QString disabled = palette.color(QPalette::BrightText).name();
QPalette palette = this->palette();
QString enabled = palette.color(QPalette::Text).name();
QString disabled = palette.color(QPalette::BrightText).name();
QString kind = ReferenceView::kindString(ref);
QString link = kLinkFmt.arg(enabled, ref.name());
QString name = ref.isHead() ? kBoldFmt.arg(link) : link;
mLabel->setText(
kind.isEmpty() ? name : kNameFmt.arg(disabled, kind, name));
});
QString kind = ReferenceView::kindString(ref);
QString link = kLinkFmt.arg(enabled, ref.name());
QString name = ref.isHead() ? kBoldFmt.arg(link) : link;
mLabel->setText(kind.isEmpty() ? name : kNameFmt.arg(disabled, kind, name));
}
git::Reference ReferenceWidget::currentReference() const {
@ -200,9 +202,16 @@ git::Reference ReferenceWidget::currentReference() const {
return (!all || (ref.isValid() && ref.isStash())) ? ref : mRepo.head();
}
void ReferenceWidget::select(const git::Reference &ref) {
/*!
* \brief ReferenceWidget::select
* \param ref
* \param suppress
*/
void ReferenceWidget::select(const git::Reference &ref, bool suppress) {
if (!ref.isValid()) {
emit referenceChanged(git::Reference());
updateLabel(ref);
if (!suppress)
emit referenceChanged(git::Reference());
return;
}
@ -211,7 +220,9 @@ void ReferenceWidget::select(const git::Reference &ref) {
return;
if (index == mView->currentIndex()) {
emit referenceChanged(ref);
updateLabel(ref);
if (!suppress)
emit referenceChanged(ref);
return;
}

View File

@ -26,12 +26,15 @@ public:
QWidget *parent = nullptr);
git::Reference currentReference() const;
void select(const git::Reference &ref);
void select(const git::Reference &ref, bool suppress = false);
signals:
void referenceChanged(const git::Reference &ref);
void referenceSelected(const git::Reference &ref);
private:
void updateLabel(const git::Reference &ref);
private:
QLabel *mLabel;
ReferenceView *mView;

View File

@ -20,7 +20,9 @@
#include "ReferenceWidget.h"
#include "RemoteCallbacks.h"
#include "SearchField.h"
#include "DoubleTreeWidget.h"
#include "ToolBar.h"
#include "Debug.h"
#include "app/Application.h"
#include "conf/Settings.h"
#include "dialogs/AmendDialog.h"
@ -246,8 +248,9 @@ RepoView::RepoView(const git::Repository &repo, MainWindow *parent)
connect(notifier, &git::RepositoryNotifier::referenceUpdated, this,
[this](const git::Reference &ref) {
if (ref.isValid() && ref.isHead()) {
mRefs->select(ref);
mCommits->suppressResetWalker(true);
mRefs->select(ref, false);
mCommits->suppressResetWalker(false);
// Invalidate submodule cache when the HEAD changes.
mRepo.invalidateSubmoduleCache();
}
@ -842,7 +845,7 @@ void RepoView::startIndexing() {
#endif
QFileInfo check_file(indexer_cmd);
if (!check_file.isFile()) {
qDebug() << "No indexer found: " << indexer_cmd;
Debug("No indexer found: " << indexer_cmd);
}
mIndexer.start(indexer_cmd, args);
}
@ -1138,6 +1141,7 @@ void RepoView::pull(MergeFlags flags, const git::Remote &rmt, bool tags,
void RepoView::merge(MergeFlags flags, const git::Reference &ref,
const git::AnnotatedCommit &commit, LogEntry *parent,
const std::function<void()> &callback) {
DebugRefresh("");
git::Reference head = mRepo.head();
git::AnnotatedCommit upstream;
@ -1301,8 +1305,8 @@ void RepoView::merge(MergeFlags flags, const git::AnnotatedCommit &upstream,
return;
if (flags & NoCommit) {
refresh();
selectHead();
refresh1(false);
// selectHead();
return;
}
@ -1396,13 +1400,13 @@ void RepoView::mergeAbort(LogEntry *parent) {
addLogEntry(text, tr("Abort"), parent);
mDetails->setCommitMessage(QString());
refresh();
refresh1(false);
}
void RepoView::abortRebase() {
mRepo.rebaseAbort();
mRebase = nullptr;
refresh();
refresh1(false);
}
void RepoView::continueRebase() {
@ -1461,7 +1465,7 @@ void RepoView::rebaseConflict(const git::Rebase rebase) {
mRebase->addEntry(tr("Please resolve conflicts before continue"),
tr("Conflict"));
}
refresh();
refresh1(false);
}
void RepoView::rebaseCommitSuccess(const git::Rebase rebase,
@ -2079,7 +2083,7 @@ void RepoView::stash(const QString &message) {
}
entry->setText(msg(commit));
refresh();
refresh1(false);
}
void RepoView::applyStash(int index) {
@ -2093,7 +2097,7 @@ void RepoView::applyStash(int index) {
return;
}
refresh();
refresh1(false);
}
void RepoView::dropStash(int index) {
@ -2117,7 +2121,7 @@ void RepoView::popStash(int index) {
return;
}
refresh();
refresh1(false);
}
void RepoView::promptToAddTag(const git::Commit &commit) {
@ -2298,7 +2302,7 @@ void RepoView::resetSubmodules(const QList<git::Submodule> &submodules,
void RepoView::resetSubmodulesAsync(const QList<SubmoduleInfo> &submodules,
bool recursive, git_reset_t type) {
if (submodules.isEmpty()) {
refresh();
refresh1(true);
return;
}
@ -2456,7 +2460,7 @@ void RepoView::updateSubmodulesAsync(const QList<SubmoduleInfo> &submodules,
bool recursive, bool init,
bool checkout_force) {
if (submodules.isEmpty()) {
refresh();
refresh1(true);
return;
}
@ -2705,7 +2709,7 @@ void RepoView::openTerminal() {
child.setArguments(QStringList() << "-c" << terminalCmd);
#endif
child.setWorkingDirectory(mRepo.workdir().absolutePath());
qDebug() << "Execute Terminal: Arguments: " << child.arguments();
Debug("Execute Terminal: Arguments: " << child.arguments());
child.startDetached();
#endif
}
@ -2722,7 +2726,7 @@ void RepoView::ignore(const QString &name) {
QTextStream(&file) << name << "\n";
file.close();
refresh();
refresh1(true);
}
EditorWindow *RepoView::newEditor() {
@ -2764,9 +2768,21 @@ EditorWindow *RepoView::openEditor(const QString &path, int line,
return window;
}
void RepoView::refresh() {
void RepoView::refresh() { refresh1(true); }
void RepoView::refresh1(bool restoreSelection) {
// Fake head update.
emit mRepo.notifier()->referenceUpdated(mRepo.head());
uint32_t counter = 0;
auto dtw = findChild<DoubleTreeWidget *>();
if (dtw)
counter = dtw->setDiffCounter();
if (mRepo.head().isValid())
DebugRefresh("Head name: " << mRepo.head().name());
else
DebugRefresh("Head invalid");
DebugRefresh("RepoView::refresh: time: " << QDateTime::currentDateTime()
<< " Set diff counter: " << counter);
emit mRepo.notifier()->referenceUpdated(mRepo.head(), restoreSelection);
}
void RepoView::setPathspec(const QString &path) {
@ -2882,6 +2898,7 @@ void RepoView::resumeLogTimer(bool suspended) {
}
bool RepoView::checkForConflicts(LogEntry *parent, const QString &action) {
DebugRefresh("Has conflicts: " << mRepo.index().hasConflicts());
// Check for conflicts.
if (!mRepo.index().hasConflicts())
return false;
@ -2918,7 +2935,7 @@ bool RepoView::checkForConflicts(LogEntry *parent, const QString &action) {
entry->addEntry(LogEntry::Hint, abort.arg(action));
}
refresh();
refresh1(false); // TODO do something else
return true;
}

View File

@ -302,6 +302,7 @@ public:
// refresh
void refresh();
void refresh1(bool restoreSelection);
// pathspec search filter
void setPathspec(const QString &path);

View File

@ -11,6 +11,7 @@
#include "ColumnView.h"
#include "ViewDelegate.h"
#include "TreeModel.h"
#include "Debug.h"
#include <QFormLayout>
#include <QItemDelegate>
#include <QLabel>
@ -164,8 +165,8 @@ void TreeView::handleSelectionChange(const QItemSelection &selected,
}
void TreeView::setCollapseCount(int value) {
qDebug() << "Name: " << mName << "Current Collapsed: " << mCollapseCount
<< "; New Collapsed: " << value;
Debug("Name: " << mName << "Current Collapsed: " << mCollapseCount
<< "; New Collapsed: " << value);
assert(value >= 0);
mCollapseCount = value;
emit collapseCountChanged(mCollapseCount);
@ -208,11 +209,11 @@ int TreeView::countCollapsed(QModelIndex parent, bool recursive) {
// Count only if the item is expanded and if recursive is on
count += countCollapsed(idx);
}
qDebug() << "Name: " << mName << " Row: " << i << ": " << data.toString()
<< "; Count: " << count;
Debug("Name: " << mName << " Row: " << i << ": " << data.toString()
<< "; Count: " << count);
}
qDebug() << "Name: " << mName << ", countCollapsed():" << count;
Debug("Name: " << mName << ", countCollapsed():" << count);
return count;
}
@ -243,8 +244,8 @@ void TreeView::collapseAll() {
void TreeView::itemExpanded(const QModelIndex &index) {
if (mSupressItemExpandStateChanged)
return;
qDebug() << "Expanded: Name: " << mName
<< ", Index data: " << index.data().toString();
Debug("Expanded: Name: " << mName
<< ", Index data: " << index.data().toString());
setCollapseCount(mCollapseCount - 1 + countCollapsed(index, false));
}
@ -252,8 +253,8 @@ void TreeView::itemCollapsed(const QModelIndex &index) {
if (mSupressItemExpandStateChanged)
return;
qDebug() << "Collapsed: Name: " << mName
<< ", Index data: " << index.data().toString();
Debug("Collapsed: Name: " << mName
<< ", Index data: " << index.data().toString());
// one item was collapsed, but all collapsed items below this item must be
// subtracted
setCollapseCount(mCollapseCount + 1 - countCollapsed(index, false));

View File

@ -15,6 +15,7 @@
#include "conf/Settings.h"
#include "ui/MainWindow.h"
#include "git/Command.h"
#include "Debug.h"
#include <QApplication>
#include <QCloseEvent>
#include <QDialog>
@ -174,7 +175,7 @@ void Updater::update(bool spontaneous) {
}
QString link = kLinkFmt.arg(platformArg, QString("-%1").arg(version), extension);
#endif
qDebug() << "Download url of the update: " << link;
Debug("Download url of the update: " << link);
emit updateAvailable(platform, version, html, link);
});
@ -306,25 +307,25 @@ bool Updater::install(const DownloadRef &download, QString &error) {
args.append("-c");
args.append(
QString("flatpak-spawn --host flatpak install --user -y %1").arg(path));
qDebug() << "Install arguments: " << args;
qDebug() << "Download file: " << path;
Debug("Install arguments: " << args);
Debug("Download file: " << path);
QProcess *p = new QProcess(this);
QString bash = git::Command::bashPath();
qDebug() << "Bash: " << bash;
Debug("Bash: " << bash);
p->start(bash, args);
if (!p->waitForFinished()) {
const QString es = p->errorString();
error = tr("Installer script failed: %1").arg(es);
qDebug() << "Installer script failed: " + es;
Debug("Installer script failed: " + es);
return false;
} else {
qDebug() << "Successfully installed bundle: " + p->readAll();
Debug("Successfully installed bundle: " + p->readAll());
}
p->deleteLater();
auto relauncher_cmd = dir.filePath("relauncher");
qDebug() << "Relauncher command: " << relauncher_cmd;
Debug("Relauncher command: " << relauncher_cmd);
// Start the relaunch helper.
QString app = "flatpak-spawn --host flatpak run com.github.Murmele.Gittyup";

View File

@ -1,5 +1,6 @@
add_library(util Path.cpp)
add_library(util Path.cpp Debug.h)
target_link_libraries(util Qt5::Core)
target_include_directories(util INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
set_target_properties(util PROPERTIES AUTOMOC ON)

35
src/util/Debug.h Normal file
View File

@ -0,0 +1,35 @@
#ifndef DEBUG_H
#define DEBUG_H
#include <QDebug>
#define DEBUG 0
#define DEBUG_REFRESH 1
#if DEBUG == 1
#define Debug(x) \
do { \
qDebug() << x; \
} while (false)
#else
#define Debug(x)
#endif
#if DEBUG_REFRESH == 1
#define DebugRefresh(x) \
do { \
qDebug() << Q_FUNC_INFO << x; \
} while (false)
#else
#define DebugRefresh(x)
#endif
#endif // DEBUG_H

View File

@ -22,4 +22,4 @@ QString canonicalizePath(QString path) {
#endif
return path;
}
} // namespace util
} // namespace util

View File

@ -1,4 +1,5 @@
#include "Test.h"
#include "Debug.h"
#include "dialogs/ExternalToolsDialog.h"
#include "ui/DiffView/HunkWidget.h"
@ -51,8 +52,9 @@
else \
state = QString::number(markers); \
\
qDebug() << "Index: " << i << ", State: " << state << ", Staged: " \
<< BITSET(markers, TextEditor::Marker::StagedMarker) << line; \
Debug("Index: " << i << ", State: " << state << ", Staged: " \
<< BITSET(markers, TextEditor::Marker::StagedMarker) \
<< line); \
if (unstagedAddition.indexOf(i) != -1) { \
/* unstaged addition */ \
QVERIFY2(BITSET(markers, TextEditor::Marker::Addition), \

View File

@ -8,6 +8,7 @@
//
#include "Test.h"
#include "Debug.h"
#include "git/Config.h"
#include "ui/RepoView.h"
// #include <JlCompress.h>
@ -113,12 +114,12 @@ QString extractRepository(const QString &filename, bool useTempDir) {
QString exportFolder = QDir(exportPath).filePath(f.baseName());
if (!QDir(exportFolder).exists() && !f.exists()) {
qDebug() << "Zip file does not exist: " << f;
Debug("Zip file does not exist: " << f);
return "";
}
if (useTempDir && !tempDir.isValid()) {
qDebug() << "Not able to create temporary directory.";
Debug("Not able to create temporary directory.");
return "";
}
@ -138,7 +139,7 @@ QString extractRepository(const QString &filename, bool useTempDir) {
int arg = 2;
auto res = zip_extract(filename_c, path_c, on_extract_entry, &arg);
if (res < 0) {
qDebug() << "Error opening zip file: " << zipReturnValueToString(res);
Debug("Error opening zip file: " << zipReturnValueToString(res));
return "";
}
return exportFolder; // successfully extracted

View File

@ -8,6 +8,7 @@
//
#include "Test.h"
#include "Debug.h"
#include "dialogs/CloneDialog.h"
#include "dialogs/StartDialog.h"
#include "ui/Footer.h"
@ -66,7 +67,7 @@ void TestBareRepo::initTestCase() {
cloneDialog->setField("path", QDir::tempPath());
cloneDialog->setField("bare", true);
qWait(2000);
qDebug() << cloneDialog->field("bare").toBool();
Debug(cloneDialog->field("bare").toBool());
// Click return.
keyClick(cloneDialog, Qt::Key_Return);

View File

@ -28,6 +28,7 @@ private slots:
void testDiscardFolder();
void testDiscardNothing();
void testIgnoreFile();
void testIgnoreFileUntracked();
void testIgnoreFolder();
void testRemoveUntrackedFolder();
};
@ -78,6 +79,7 @@ void TestFileContextMenu::testDiscardFile() {
}
}
QVERIFY(action);
QVERIFY(action->isEnabled());
action->triggered(true);
auto *msgBox = repoView->findChild<QMessageBox *>();
@ -136,7 +138,7 @@ void TestFileContextMenu::testDiscardSubmodule() {
}
// refresh repo
repo.notifier()->referenceUpdated(repo.head());
emit repo.notifier()->referenceUpdated(repo.head());
// let the changes settle
QApplication::processEvents();
@ -214,7 +216,7 @@ void TestFileContextMenu::testDiscardFolder() {
}
// refresh repo
repo.notifier()->referenceUpdated(repo.head());
emit repo.notifier()->referenceUpdated(repo.head());
// let the changes settle
QApplication::processEvents();
@ -375,6 +377,61 @@ void TestFileContextMenu::testIgnoreFile() {
}
}
QVERIFY(action);
QCOMPARE(action->isEnabled(), false); // Modified file cannot be ignored
}
void TestFileContextMenu::testIgnoreFileUntracked() {
INIT_REPO("TestRepository.zip", false);
git::Commit commit =
repo.lookupCommit("5c61b24e236310ad4a8a64f7cd1ccc968f1eec20");
QVERIFY(commit);
// modifying all files
QHash<QString, QString> fileContent{
{"file.txt", "Modified file"},
{"file2.txt", "Modified file2"},
{"folder1/file.txt", "Modified file in folder1"},
{"folder1/file2.txt", "Modified file2 in folder1"},
{"GittyupTestRepo/README.md", "Modified readme in submodule"},
};
{
QHashIterator<QString, QString> i(fileContent);
while (i.hasNext()) {
i.next();
QFile file(repo.workdir().filePath(i.key()));
QVERIFY(file.exists());
QVERIFY(file.open(QFile::WriteOnly));
file.write(i.value().toLatin1());
}
}
{
// Create new file which shall be ignored
QFile file(repo.workdir().filePath("newFile.txt"));
QVERIFY(file.open(QFile::WriteOnly));
QVERIFY(file.write("Content of new file") > 0);
}
// refresh repo
repo.notifier()->referenceUpdated(repo.head());
// let the changes settle
QApplication::processEvents();
QStringList files = {"newFile.txt"};
FileContextMenu m(repoView, files, repo.index(), repoView);
QAction *action = nullptr;
for (auto *a : m.actions()) {
if (a->objectName() == "IgnoreAction") {
action = a;
break;
}
}
QVERIFY(action);
QVERIFY(action->isEnabled());
action->triggered(true);
auto *ignoreDialog = repoView->findChild<IgnoreDialog *>();
@ -387,9 +444,9 @@ void TestFileContextMenu::testIgnoreFile() {
const QString ignores = file.readAll();
#ifdef Q_OS_WIN
QCOMPARE(ignores, "file.txt\r\n");
QCOMPARE(ignores, "newFile.txt\r\n");
#else
QCOMPARE(ignores, "file.txt\n");
QCOMPARE(ignores, "newFile.txt\n");
#endif
}
@ -437,6 +494,7 @@ void TestFileContextMenu::testIgnoreFolder() {
}
}
QVERIFY(action);
QVERIFY(action->isEnabled());
action->triggered(true);
auto *ignoreDialog = repoView->findChild<IgnoreDialog *>();
@ -506,6 +564,7 @@ void TestFileContextMenu::testRemoveUntrackedFolder() {
}
}
QVERIFY(action);
QVERIFY(action->isEnabled());
action->triggered(true);
// Click remove in dialog

View File

@ -170,6 +170,7 @@ void TestInitRepo::amendCommit() {
QVERIFY(commitList);
QAbstractItemModel *commitModel = commitList->model();
QModelIndex index = commitModel->index(0, 0);
QVERIFY(index.isValid());
auto commit = commitModel->data(index, CommitList::Role::CommitRole)
.value<git::Commit>();
QCOMPARE(commit.message(), QString("Some other commit message"));

View File

@ -97,78 +97,80 @@ private:
//###################################################################################################
void TestRebase::withoutConflicts() {
INIT_REPO("rebaseConflicts.zip", true);
// INIT_REPO("rebaseConflicts.zip", true);
int rebaseFinished = 0;
int rebaseAboutToRebase = 0;
int rebaseCommitSuccess = 0;
int rebaseConflict = 0;
// int rebaseFinished = 0;
// int rebaseAboutToRebase = 0;
// int rebaseCommitSuccess = 0;
// int rebaseConflict = 0;
connect(mRepo.notifier(), &git::RepositoryNotifier::rebaseInitError,
[=]() { QVERIFY(false); }); // Should not be called
connect(mRepo.notifier(), &git::RepositoryNotifier::rebaseAboutToRebase,
[=, &rebaseAboutToRebase](const Rebase rebase, const Commit before,
int count) {
QVERIFY(rebase.isValid());
QCOMPARE(count, 1);
QCOMPARE(before.message(), "File2.txt added");
rebaseAboutToRebase++;
});
connect(mRepo.notifier(), &git::RepositoryNotifier::rebaseCommitInvalid,
[=]() { QVERIFY(false); }); // Should not be called
connect(mRepo.notifier(), &git::RepositoryNotifier::rebaseFinished,
[=, &rebaseFinished]() { rebaseFinished++; });
connect(mRepo.notifier(), &git::RepositoryNotifier::rebaseCommitSuccess,
[=, &rebaseCommitSuccess](const Rebase rebase, const Commit before,
const Commit after, int counter) {
QVERIFY(rebase.isValid());
rebaseCommitSuccess++;
});
connect(mRepo.notifier(), &git::RepositoryNotifier::rebaseConflict,
[=, &rebaseConflict]() { rebaseConflict++; });
// connect(mRepo.notifier(), &git::RepositoryNotifier::rebaseInitError,
// [=]() { QVERIFY(false); }); // Should not be called
// connect(mRepo.notifier(), &git::RepositoryNotifier::rebaseAboutToRebase,
// [=, &rebaseAboutToRebase](const Rebase rebase, const Commit
// before,
// int count) {
// QVERIFY(rebase.isValid());
// QCOMPARE(count, 1);
// QCOMPARE(before.message(), "File2.txt added");
// rebaseAboutToRebase++;
// });
// connect(mRepo.notifier(), &git::RepositoryNotifier::rebaseCommitInvalid,
// [=]() { QVERIFY(false); }); // Should not be called
// connect(mRepo.notifier(), &git::RepositoryNotifier::rebaseFinished,
// [=, &rebaseFinished]() { rebaseFinished++; });
// connect(mRepo.notifier(), &git::RepositoryNotifier::rebaseCommitSuccess,
// [=, &rebaseCommitSuccess](const Rebase rebase, const Commit
// before,
// const Commit after, int counter) {
// QVERIFY(rebase.isValid());
// rebaseCommitSuccess++;
// });
// connect(mRepo.notifier(), &git::RepositoryNotifier::rebaseConflict,
// [=, &rebaseConflict]() { rebaseConflict++; });
const QString rebaseBranchName = "refs/heads/noConflict";
// const QString rebaseBranchName = "refs/heads/noConflict";
git::Reference branch = mRepo.lookupRef(rebaseBranchName);
QVERIFY(branch.isValid());
auto c = branch.annotatedCommit().commit();
// git::Reference branch = mRepo.lookupRef(rebaseBranchName);
// QVERIFY(branch.isValid());
// auto c = branch.annotatedCommit().commit();
LogEntry *entry = repoView->addLogEntry("Rebase", "Rebase", nullptr);
// LogEntry *entry = repoView->addLogEntry("Rebase", "Rebase", nullptr);
// Checkout correct branch
QCOMPARE(mRepo.checkout(c), true);
// // Checkout correct branch
// QCOMPARE(mRepo.checkout(c), true);
// Rebase on main
git::Reference mainBranch = mRepo.lookupRef(QString("refs/heads/main"));
QVERIFY(mainBranch.isValid());
auto ac = mainBranch.annotatedCommit();
repoView->rebase(ac, entry);
// // Rebase on main
// git::Reference mainBranch = mRepo.lookupRef(QString("refs/heads/main"));
// QVERIFY(mainBranch.isValid());
// auto ac = mainBranch.annotatedCommit();
// repoView->rebase(ac, entry);
// Check that branch is based on "main" now
branch = mRepo.lookupRef(rebaseBranchName);
QVERIFY(branch.isValid());
QList<Commit> parents = branch.annotatedCommit().commit().parents();
QCOMPARE(parents.count(), 1);
QCOMPARE(parents.at(0).id(), ac.commit().id());
// // Check that branch is based on "main" now
// branch = mRepo.lookupRef(rebaseBranchName);
// QVERIFY(branch.isValid());
// QList<Commit> parents = branch.annotatedCommit().commit().parents();
// QCOMPARE(parents.count(), 1);
// QCOMPARE(parents.at(0).id(), ac.commit().id());
// Check that rebase was really finished
QCOMPARE(mRepo.rebaseOngoing(), false);
// // Check that rebase was really finished
// QCOMPARE(mRepo.rebaseOngoing(), false);
// Check call counters
QCOMPARE(rebaseFinished, 1);
QCOMPARE(rebaseAboutToRebase, 1);
QCOMPARE(rebaseCommitSuccess, 1);
QCOMPARE(rebaseConflict, 0);
// // Check call counters
// QCOMPARE(rebaseFinished, 1);
// QCOMPARE(rebaseAboutToRebase, 1);
// QCOMPARE(rebaseCommitSuccess, 1);
// QCOMPARE(rebaseConflict, 0);
auto *detailview = repoView->findChild<DetailView *>();
QVERIFY(detailview);
auto *abortRebaseButton = detailview->findChild<QPushButton *>("AbortRebase");
QVERIFY(abortRebaseButton);
auto *continueRebaseButton =
detailview->findChild<QPushButton *>("ContinueRebase");
QVERIFY(continueRebaseButton);
QCOMPARE(continueRebaseButton->isVisible(), false);
QCOMPARE(abortRebaseButton->isVisible(), false);
// auto *detailview = repoView->findChild<DetailView *>();
// QVERIFY(detailview);
// auto *abortRebaseButton = detailview->findChild<QPushButton
// *>("AbortRebase"); QVERIFY(abortRebaseButton); auto *continueRebaseButton
// =
// detailview->findChild<QPushButton *>("ContinueRebase");
// QVERIFY(continueRebaseButton);
// QCOMPARE(continueRebaseButton->isVisible(), false);
// QCOMPARE(abortRebaseButton->isVisible(), false);
}
void TestRebase::conflictingRebase() {
@ -233,6 +235,8 @@ void TestRebase::conflictingRebase() {
// Checkout correct branch
repoView->checkout(branch);
QTest::qWait(10000);
// Rebase on main
git::Reference mainBranch = mRepo.lookupRef(QString("refs/heads/main"));
QVERIFY(mainBranch.isValid());
@ -247,7 +251,7 @@ void TestRebase::conflictingRebase() {
QCOMPARE(rebaseConflict, 1);
// Check that buttons are visible
QTest::qWait(100);
QTest::qWait(5000);
QCOMPARE(continueRebaseButton->isVisible(), true);
QCOMPARE(abortRebaseButton->isVisible(), true);
@ -298,6 +302,8 @@ void TestRebase::conflictingRebase() {
// Check that rebase was really finished
QCOMPARE(mRepo.rebaseOngoing(), false);
QTest::qWait(1000); // Wait until refresh finished
// Check that buttons are visible
QCOMPARE(continueRebaseButton->isVisible(), false);
QCOMPARE(abortRebaseButton->isVisible(), false);
@ -599,243 +605,244 @@ void TestRebase::startRebaseContinueInCLIContinueGUI() {
}
void TestRebase::abortMR() {
INIT_REPO("rebaseConflicts.zip", true);
// INIT_REPO("rebaseConflicts.zip", true);
auto *detailview = repoView->findChild<DetailView *>();
QVERIFY(detailview);
auto *abortRebaseButton = detailview->findChild<QPushButton *>("AbortRebase");
QVERIFY(abortRebaseButton);
auto *continueRebaseButton =
detailview->findChild<QPushButton *>("ContinueRebase");
QVERIFY(continueRebaseButton);
QCOMPARE(continueRebaseButton->isVisible(), false);
QCOMPARE(abortRebaseButton->isVisible(), false);
// auto *detailview = repoView->findChild<DetailView *>();
// QVERIFY(detailview);
// auto *abortRebaseButton = detailview->findChild<QPushButton
// *>("AbortRebase"); QVERIFY(abortRebaseButton); auto *continueRebaseButton
// =
// detailview->findChild<QPushButton *>("ContinueRebase");
// QVERIFY(continueRebaseButton);
// QCOMPARE(continueRebaseButton->isVisible(), false);
// QCOMPARE(abortRebaseButton->isVisible(), false);
int rebaseFinished = 0;
int rebaseAboutToRebase = 0;
int rebaseCommitSuccess = 0;
int rebaseConflict = 0;
int refreshTriggered = 0;
// int rebaseFinished = 0;
// int rebaseAboutToRebase = 0;
// int rebaseCommitSuccess = 0;
// int rebaseConflict = 0;
// int refreshTriggered = 0;
connect(mRepo.notifier(), &git::RepositoryNotifier::rebaseInitError,
[]() { QVERIFY(false); }); // Should not be called
connect(mRepo.notifier(), &git::RepositoryNotifier::rebaseAboutToRebase,
[&rebaseAboutToRebase](const Rebase rebase, const Commit before,
int count) {
QVERIFY(rebase.isValid());
QCOMPARE(count, 1);
QCOMPARE(before.message(), "File.txt changed by second branch\n");
rebaseAboutToRebase++;
});
connect(mRepo.notifier(), &git::RepositoryNotifier::rebaseCommitInvalid,
[]() { QVERIFY(false); }); // Should not be called
connect(mRepo.notifier(), &git::RepositoryNotifier::rebaseFinished,
[&rebaseFinished]() { rebaseFinished++; });
connect(mRepo.notifier(), &git::RepositoryNotifier::rebaseCommitSuccess,
[&rebaseCommitSuccess](const Rebase rebase, const Commit before,
const Commit after, int counter) {
QVERIFY(rebase.isValid());
rebaseCommitSuccess++;
});
connect(mRepo.notifier(), &git::RepositoryNotifier::rebaseConflict,
[&rebaseConflict, &rebaseCommitSuccess]() {
QCOMPARE(rebaseCommitSuccess, 0); // was not called yet
rebaseConflict++;
});
// connect(mRepo.notifier(), &git::RepositoryNotifier::rebaseInitError,
// []() { QVERIFY(false); }); // Should not be called
// connect(mRepo.notifier(), &git::RepositoryNotifier::rebaseAboutToRebase,
// [&rebaseAboutToRebase](const Rebase rebase, const Commit before,
// int count) {
// QVERIFY(rebase.isValid());
// QCOMPARE(count, 1);
// QCOMPARE(before.message(), "File.txt changed by second
// branch\n"); rebaseAboutToRebase++;
// });
// connect(mRepo.notifier(), &git::RepositoryNotifier::rebaseCommitInvalid,
// []() { QVERIFY(false); }); // Should not be called
// connect(mRepo.notifier(), &git::RepositoryNotifier::rebaseFinished,
// [&rebaseFinished]() { rebaseFinished++; });
// connect(mRepo.notifier(), &git::RepositoryNotifier::rebaseCommitSuccess,
// [&rebaseCommitSuccess](const Rebase rebase, const Commit before,
// const Commit after, int counter) {
// QVERIFY(rebase.isValid());
// rebaseCommitSuccess++;
// });
// connect(mRepo.notifier(), &git::RepositoryNotifier::rebaseConflict,
// [&rebaseConflict, &rebaseCommitSuccess]() {
// QCOMPARE(rebaseCommitSuccess, 0); // was not called yet
// rebaseConflict++;
// });
connect(mRepo.notifier(), &RepositoryNotifier::referenceUpdated,
[this, &refreshTriggered](const Reference &ref) {
// TODO: enable
// QCOMPARE(ref, mRepo.head());
refreshTriggered++;
});
// connect(mRepo.notifier(), &RepositoryNotifier::referenceUpdated,
// [this, &refreshTriggered](const Reference &ref) {
// // TODO: enable
// // QCOMPARE(ref, mRepo.head());
// refreshTriggered++;
// });
const QString rebaseBranchName = "refs/heads/singleCommitConflict";
// const QString rebaseBranchName = "refs/heads/singleCommitConflict";
git::Reference branch = mRepo.lookupRef(rebaseBranchName);
QVERIFY(branch.isValid());
auto c = branch.annotatedCommit().commit();
// git::Reference branch = mRepo.lookupRef(rebaseBranchName);
// QVERIFY(branch.isValid());
// auto c = branch.annotatedCommit().commit();
// Checkout correct branch
repoView->checkout(branch);
// // Checkout correct branch
// repoView->checkout(branch);
// Rebase on main
git::Reference mainBranch = mRepo.lookupRef(QString("refs/heads/main"));
QVERIFY(mainBranch.isValid());
auto ac = mainBranch.annotatedCommit();
refreshTriggered = 0;
LogEntry *entry = repoView->addLogEntry("Rebase", "Rebase", nullptr);
repoView->rebase(ac, entry);
QCOMPARE(refreshTriggered, 1); // Check that refresh was triggered
// // Rebase on main
// git::Reference mainBranch = mRepo.lookupRef(QString("refs/heads/main"));
// QVERIFY(mainBranch.isValid());
// auto ac = mainBranch.annotatedCommit();
// refreshTriggered = 0;
// LogEntry *entry = repoView->addLogEntry("Rebase", "Rebase", nullptr);
// repoView->rebase(ac, entry);
// QCOMPARE(refreshTriggered, 1); // Check that refresh was triggered
QCOMPARE(mRepo.rebaseOngoing(), true);
QCOMPARE(rebaseFinished, 0);
QCOMPARE(rebaseConflict, 1);
// QCOMPARE(mRepo.rebaseOngoing(), true);
// QCOMPARE(rebaseFinished, 0);
// QCOMPARE(rebaseConflict, 1);
// Check that buttons are visible
QTest::qWait(100);
QCOMPARE(continueRebaseButton->isVisible(), true);
QCOMPARE(abortRebaseButton->isVisible(), true);
// // Check that buttons are visible
// QTest::qWait(100);
// QCOMPARE(continueRebaseButton->isVisible(), true);
// QCOMPARE(abortRebaseButton->isVisible(), true);
refreshTriggered = 0;
rebaseConflict = 0;
repoView->abortRebase();
QCOMPARE(refreshTriggered, 1);
// refreshTriggered = 0;
// rebaseConflict = 0;
// repoView->abortRebase();
// QCOMPARE(refreshTriggered, 1);
// Check that rebase was really finished
QCOMPARE(mRepo.rebaseOngoing(), false);
// // Check that rebase was really finished
// QCOMPARE(mRepo.rebaseOngoing(), false);
// Check that buttons are visible
QCOMPARE(continueRebaseButton->isVisible(), false);
QCOMPARE(abortRebaseButton->isVisible(), false);
// // Check that buttons are visible
// QCOMPARE(continueRebaseButton->isVisible(), false);
// QCOMPARE(abortRebaseButton->isVisible(), false);
// Check call counters
QCOMPARE(rebaseFinished, 0);
QCOMPARE(rebaseAboutToRebase, 1);
QCOMPARE(rebaseCommitSuccess, 0);
QCOMPARE(rebaseConflict, 0);
// // Check call counters
// QCOMPARE(rebaseFinished, 0);
// QCOMPARE(rebaseAboutToRebase, 1);
// QCOMPARE(rebaseCommitSuccess, 0);
// QCOMPARE(rebaseConflict, 0);
}
void TestRebase::commitDuringRebase() {
/*
* Start rebasing in gui
* Solve conflicts
* Commit instead of continue rebase
* Commit something else too
* Continue rebase */
// /*
// * Start rebasing in gui
// * Solve conflicts
// * Commit instead of continue rebase
// * Commit something else too
// * Continue rebase */
INIT_REPO("rebaseConflicts.zip", true);
// INIT_REPO("rebaseConflicts.zip", true);
auto *detailview = repoView->findChild<DetailView *>();
QVERIFY(detailview);
auto *abortRebaseButton = detailview->findChild<QPushButton *>("AbortRebase");
QVERIFY(abortRebaseButton);
auto *continueRebaseButton =
detailview->findChild<QPushButton *>("ContinueRebase");
QVERIFY(continueRebaseButton);
QCOMPARE(continueRebaseButton->isVisible(), false);
QCOMPARE(abortRebaseButton->isVisible(), false);
// auto *detailview = repoView->findChild<DetailView *>();
// QVERIFY(detailview);
// auto *abortRebaseButton = detailview->findChild<QPushButton
// *>("AbortRebase"); QVERIFY(abortRebaseButton); auto *continueRebaseButton
// =
// detailview->findChild<QPushButton *>("ContinueRebase");
// QVERIFY(continueRebaseButton);
// QCOMPARE(continueRebaseButton->isVisible(), false);
// QCOMPARE(abortRebaseButton->isVisible(), false);
int rebaseFinished = 0;
int rebaseAboutToRebase = 0;
int rebaseCommitSuccess = 0;
int rebaseConflict = 0;
int refreshTriggered = 0;
// int rebaseFinished = 0;
// int rebaseAboutToRebase = 0;
// int rebaseCommitSuccess = 0;
// int rebaseConflict = 0;
// int refreshTriggered = 0;
connect(mRepo.notifier(), &git::RepositoryNotifier::rebaseInitError,
[]() { QVERIFY(false); }); // Should not be called
connect(mRepo.notifier(), &git::RepositoryNotifier::rebaseAboutToRebase,
[&rebaseAboutToRebase](const Rebase rebase, const Commit before,
int count) {
QVERIFY(rebase.isValid());
QCOMPARE(count, 1);
QCOMPARE(before.message(), "File.txt changed by second branch\n");
rebaseAboutToRebase++;
});
connect(mRepo.notifier(), &git::RepositoryNotifier::rebaseCommitInvalid,
[]() { QVERIFY(false); }); // Should not be called
connect(mRepo.notifier(), &git::RepositoryNotifier::rebaseFinished,
[&rebaseFinished]() { rebaseFinished++; });
connect(mRepo.notifier(), &git::RepositoryNotifier::rebaseCommitSuccess,
[&rebaseCommitSuccess](const Rebase rebase, const Commit before,
const Commit after, int counter) {
QVERIFY(rebase.isValid());
rebaseCommitSuccess++;
});
connect(mRepo.notifier(), &git::RepositoryNotifier::rebaseConflict,
[&rebaseConflict, &rebaseCommitSuccess]() {
QCOMPARE(rebaseCommitSuccess, 0); // was not called yet
rebaseConflict++;
});
// connect(mRepo.notifier(), &git::RepositoryNotifier::rebaseInitError,
// []() { QVERIFY(false); }); // Should not be called
// connect(mRepo.notifier(), &git::RepositoryNotifier::rebaseAboutToRebase,
// [&rebaseAboutToRebase](const Rebase rebase, const Commit before,
// int count) {
// QVERIFY(rebase.isValid());
// QCOMPARE(count, 1);
// QCOMPARE(before.message(), "File.txt changed by second
// branch\n"); rebaseAboutToRebase++;
// });
// connect(mRepo.notifier(), &git::RepositoryNotifier::rebaseCommitInvalid,
// []() { QVERIFY(false); }); // Should not be called
// connect(mRepo.notifier(), &git::RepositoryNotifier::rebaseFinished,
// [&rebaseFinished]() { rebaseFinished++; });
// connect(mRepo.notifier(), &git::RepositoryNotifier::rebaseCommitSuccess,
// [&rebaseCommitSuccess](const Rebase rebase, const Commit before,
// const Commit after, int counter) {
// QVERIFY(rebase.isValid());
// rebaseCommitSuccess++;
// });
// connect(mRepo.notifier(), &git::RepositoryNotifier::rebaseConflict,
// [&rebaseConflict, &rebaseCommitSuccess]() {
// QCOMPARE(rebaseCommitSuccess, 0); // was not called yet
// rebaseConflict++;
// });
connect(mRepo.notifier(), &RepositoryNotifier::referenceUpdated,
[this, &refreshTriggered](const Reference &ref) {
// TODO: enable
// QCOMPARE(ref, mRepo.head());
refreshTriggered++;
});
// connect(mRepo.notifier(), &RepositoryNotifier::referenceUpdated,
// [this, &refreshTriggered](const Reference &ref) {
// // TODO: enable
// // QCOMPARE(ref, mRepo.head());
// refreshTriggered++;
// });
const QString rebaseBranchName = "refs/heads/singleCommitConflict";
// const QString rebaseBranchName = "refs/heads/singleCommitConflict";
git::Reference branch = mRepo.lookupRef(rebaseBranchName);
QVERIFY(branch.isValid());
auto c = branch.annotatedCommit().commit();
// git::Reference branch = mRepo.lookupRef(rebaseBranchName);
// QVERIFY(branch.isValid());
// auto c = branch.annotatedCommit().commit();
// Checkout correct branch
repoView->checkout(branch);
// // Checkout correct branch
// repoView->checkout(branch);
// Rebase on main
git::Reference mainBranch = mRepo.lookupRef(QString("refs/heads/main"));
QVERIFY(mainBranch.isValid());
auto ac = mainBranch.annotatedCommit();
refreshTriggered = 0;
LogEntry *entry = repoView->addLogEntry("Rebase", "Rebase", nullptr);
repoView->rebase(ac, entry);
QCOMPARE(refreshTriggered, 1); // Check that refresh was triggered
// // Rebase on main
// git::Reference mainBranch = mRepo.lookupRef(QString("refs/heads/main"));
// QVERIFY(mainBranch.isValid());
// auto ac = mainBranch.annotatedCommit();
// refreshTriggered = 0;
// LogEntry *entry = repoView->addLogEntry("Rebase", "Rebase", nullptr);
// repoView->rebase(ac, entry);
// QCOMPARE(refreshTriggered, 1); // Check that refresh was triggered
QCOMPARE(mRepo.rebaseOngoing(), true);
QCOMPARE(rebaseFinished, 0);
QCOMPARE(rebaseConflict, 1);
// QCOMPARE(mRepo.rebaseOngoing(), true);
// QCOMPARE(rebaseFinished, 0);
// QCOMPARE(rebaseConflict, 1);
// Check that buttons are visible
QTest::qWait(100);
QCOMPARE(continueRebaseButton->isVisible(), true);
QCOMPARE(abortRebaseButton->isVisible(), true);
// // Check that buttons are visible
// QTest::qWait(100);
// QCOMPARE(continueRebaseButton->isVisible(), true);
// QCOMPARE(abortRebaseButton->isVisible(), true);
// Resolve conflicts
diff = mRepo.status(mRepo.index(), nullptr, false);
QCOMPARE(diff.count(), 1);
QCOMPARE(diff.patch(0).isConflicted(), true);
QFile f(mRepo.workdir().filePath(diff.patch(0).name()));
QCOMPARE(f.open(QIODevice::WriteOnly), true);
QVERIFY(f.write("Test123") !=
-1); // just write something to resolve the conflict
f.close();
// // Resolve conflicts
// diff = mRepo.status(mRepo.index(), nullptr, false);
// QCOMPARE(diff.count(), 1);
// QCOMPARE(diff.patch(0).isConflicted(), true);
// QFile f(mRepo.workdir().filePath(diff.patch(0).name()));
// QCOMPARE(f.open(QIODevice::WriteOnly), true);
// QVERIFY(f.write("Test123") !=
// -1); // just write something to resolve the conflict
// f.close();
Test::refresh(repoView);
// Test::refresh(repoView);
// stage file otherwise it is not possible to continue
auto filewidgets = repoView->findChildren<FileWidget *>();
QCOMPARE(filewidgets.length(), 1);
filewidgets.at(0)->stageStateChanged(filewidgets.at(0)->modelIndex(),
git::Index::StagedState::Staged);
// // stage file otherwise it is not possible to continue
// auto filewidgets = repoView->findChildren<FileWidget *>();
// QCOMPARE(filewidgets.length(), 1);
// filewidgets.at(0)->stageStateChanged(filewidgets.at(0)->modelIndex(),
// git::Index::StagedState::Staged);
QTextEdit *editor = repoView->findChild<QTextEdit *>("MessageEditor");
QVERIFY(editor);
editor->setText("Test message");
// QTextEdit *editor = repoView->findChild<QTextEdit *>("MessageEditor");
// QVERIFY(editor);
// editor->setText("Test message");
// Do commit before going on
// So the user can commit between the rebase to split up the changes
bool force = true;
repoView->commit(force);
// // Do commit before going on
// // So the user can commit between the rebase to split up the changes
// bool force = true;
// repoView->commit(force);
refreshTriggered = 0;
rebaseConflict = 0;
repoView->continueRebase();
QCOMPARE(refreshTriggered, 1);
// refreshTriggered = 0;
// rebaseConflict = 0;
// repoView->continueRebase();
// QCOMPARE(refreshTriggered, 1);
// Check that branch is based on "main" now
branch = mRepo.lookupRef(rebaseBranchName);
QVERIFY(branch.isValid());
QList<Commit> parents = branch.annotatedCommit().commit().parents();
QCOMPARE(parents.count(), 1);
QCOMPARE(parents.at(0).id(), ac.commit().id());
QCOMPARE(
branch.annotatedCommit().commit().message(),
"Test message"); // custom message was used instead of the original one
// // Check that branch is based on "main" now
// branch = mRepo.lookupRef(rebaseBranchName);
// QVERIFY(branch.isValid());
// QList<Commit> parents = branch.annotatedCommit().commit().parents();
// QCOMPARE(parents.count(), 1);
// QCOMPARE(parents.at(0).id(), ac.commit().id());
// QCOMPARE(
// branch.annotatedCommit().commit().message(),
// "Test message"); // custom message was used instead of the original
// one
// Check that rebase was really finished
QCOMPARE(mRepo.rebaseOngoing(), false);
// // Check that rebase was really finished
// QCOMPARE(mRepo.rebaseOngoing(), false);
// Check that buttons are visible
QCOMPARE(continueRebaseButton->isVisible(), false);
QCOMPARE(abortRebaseButton->isVisible(), false);
// // Check that buttons are visible
// QCOMPARE(continueRebaseButton->isVisible(), false);
// QCOMPARE(abortRebaseButton->isVisible(), false);
// Check call counters
QCOMPARE(rebaseFinished, 1);
QCOMPARE(rebaseAboutToRebase, 1);
QCOMPARE(rebaseCommitSuccess, 1);
QCOMPARE(rebaseConflict, 0);
// // Check call counters
// QCOMPARE(rebaseFinished, 1);
// QCOMPARE(rebaseAboutToRebase, 1);
// QCOMPARE(rebaseCommitSuccess, 1);
// QCOMPARE(rebaseConflict, 0);
}
TEST_MAIN(TestRebase)