1#include "HistoryWidget.h"
2
3#include <AmendWidget.h>
4#include <BranchesWidget.h>
5#include <CheckBox.h>
6#include <CommitHistoryModel.h>
7#include <CommitHistoryView.h>
8#include <CommitInfo.h>
9#include <CommitInfoWidget.h>
10#include <FileDiffWidget.h>
11#include <FileEditor.h>
12#include <FullDiffWidget.h>
13#include <GitBase.h>
14#include <GitBranches.h>
15#include <GitCache.h>
16#include <GitConfig.h>
17#include <GitHistory.h>
18#include <GitLocal.h>
19#include <GitMerge.h>
20#include <GitQlientSettings.h>
21#include <GitQlientStyles.h>
22#include <GitRemote.h>
23#include <GitRepoLoader.h>
24#include <GitWip.h>
25#include <RepositoryViewDelegate.h>
26#include <WipWidget.h>
27
28#include <QLogger.h>
29
30#include <QApplication>
31#include <QGridLayout>
32#include <QLabel>
33#include <QLineEdit>
34#include <QMenu>
35#include <QMessageBox>
36#include <QPushButton>
37#include <QScreen>
38#include <QSplitter>
39#include <QStackedWidget>
40
41using namespace QLogger;
42
43HistoryWidget::HistoryWidget(const QSharedPointer<GitCache> &cache, const QSharedPointer<GitBase> git,
44 const QSharedPointer<GitServerCache> &gitServerCache,
45 const QSharedPointer<GitQlientSettings> &settings, QWidget *parent)
46 : QFrame(parent)
47 , mGit(git)
48 , mCache(cache)
49 , mGitServerCache(gitServerCache)
50 , mSettings(settings)
51 , mWipWidget(new WipWidget(mCache, mGit))
52 , mAmendWidget(new AmendWidget(mCache, mGit))
53 , mCommitInfoWidget(new CommitInfoWidget(mCache, mGit))
54 , mReturnFromFull(new QPushButton())
55 , mUserName(new QLabel())
56 , mUserEmail(new QLabel())
57 , mSplitter(new QSplitter())
58{
59 setAttribute(Qt::WA_DeleteOnClose);
60
61 QScopedPointer<GitConfig> gitConfig(new GitConfig(mGit));
62 const auto localUserInfo = gitConfig->getLocalUserInfo();
63 const auto globalUserInfo = gitConfig->getGlobalUserInfo();
64
65 mUserName->setText(localUserInfo.mUserName.isEmpty() ? globalUserInfo.mUserName : localUserInfo.mUserName);
66 mUserEmail->setText(localUserInfo.mUserEmail.isEmpty() ? globalUserInfo.mUserEmail : localUserInfo.mUserEmail);
67
68 const auto wipInfoFrame = new QFrame();
69 wipInfoFrame->setObjectName("wipInfoFrame");
70 const auto wipInfoLayout = new QVBoxLayout(wipInfoFrame);
71 wipInfoLayout->setContentsMargins(QMargins());
72 wipInfoLayout->setSpacing(10);
73 wipInfoLayout->addWidget(mUserName);
74 wipInfoLayout->addWidget(mUserEmail);
75
76 mCommitStackedWidget = new QStackedWidget();
77 mCommitStackedWidget->setCurrentIndex(0);
78 mCommitStackedWidget->addWidget(mCommitInfoWidget);
79 mCommitStackedWidget->addWidget(mWipWidget);
80 mCommitStackedWidget->addWidget(mAmendWidget);
81
82 const auto wipLayout = new QVBoxLayout();
83 wipLayout->setContentsMargins(QMargins());
84 wipLayout->setSpacing(5);
85 wipLayout->addWidget(wipInfoFrame);
86 wipLayout->addWidget(mCommitStackedWidget);
87
88 const auto wipFrame = new QFrame();
89 wipFrame->setLayout(wipLayout);
90 wipFrame->setMinimumWidth(200);
91 wipFrame->setMaximumWidth(500);
92
93 connect(mWipWidget, &CommitChangesWidget::signalShowDiff, this, &HistoryWidget::showFileDiff);
94 connect(mWipWidget, &CommitChangesWidget::changesCommitted, this, &HistoryWidget::returnToView);
95 connect(mWipWidget, &CommitChangesWidget::changesCommitted, this, &HistoryWidget::changesCommitted);
96 connect(mWipWidget, &CommitChangesWidget::changesCommitted, this, &HistoryWidget::cleanCommitPanels);
97 connect(mWipWidget, &CommitChangesWidget::signalCheckoutPerformed, this, &HistoryWidget::onRevertedChanges);
98 connect(mWipWidget, &CommitChangesWidget::signalShowFileHistory, this, &HistoryWidget::signalShowFileHistory);
99 connect(mWipWidget, &CommitChangesWidget::signalUpdateWip, this, &HistoryWidget::signalUpdateWip);
100 connect(mWipWidget, &CommitChangesWidget::changeReverted, this, [this](const QString &revertedFile) {
101 if (mFileDiff->getCurrentFile().contains(revertedFile))
102 {
103 returnToView();
104 onRevertedChanges();
105 }
106 });
107
108 connect(mAmendWidget, &CommitChangesWidget::logReload, this, &HistoryWidget::logReload);
109 connect(mAmendWidget, &CommitChangesWidget::signalShowDiff, this, &HistoryWidget::showFileDiff);
110 connect(mAmendWidget, &CommitChangesWidget::changesCommitted, this, &HistoryWidget::returnToView);
111 connect(mAmendWidget, &CommitChangesWidget::changesCommitted, this, &HistoryWidget::changesCommitted);
112 connect(mAmendWidget, &CommitChangesWidget::changesCommitted, this, &HistoryWidget::cleanCommitPanels);
113 connect(mAmendWidget, &CommitChangesWidget::signalCheckoutPerformed, this, &HistoryWidget::onRevertedChanges);
114 connect(mAmendWidget, &CommitChangesWidget::signalShowFileHistory, this, &HistoryWidget::signalShowFileHistory);
115 connect(mAmendWidget, &CommitChangesWidget::signalUpdateWip, this, &HistoryWidget::signalUpdateWip);
116 connect(mAmendWidget, &CommitChangesWidget::signalCancelAmend, this, &HistoryWidget::selectCommit);
117
118 connect(mCommitInfoWidget, &CommitInfoWidget::signalOpenFileCommit, this, &HistoryWidget::showFileDiff);
119 connect(mCommitInfoWidget, &CommitInfoWidget::signalShowFileHistory, this, &HistoryWidget::signalShowFileHistory);
120
121 mSearchInput = new QLineEdit();
122 mSearchInput->setObjectName("SearchInput");
123 mSearchInput->setPlaceholderText(tr("Press Enter to search by SHA or log message..."));
124 connect(mSearchInput, &QLineEdit::returnPressed, this, &HistoryWidget::search);
125
126 mRepositoryModel = new CommitHistoryModel(mCache, mGit, mGitServerCache);
127 mRepositoryView = new CommitHistoryView(mCache, mGit, mSettings, mGitServerCache);
128
129 connect(mRepositoryView, &CommitHistoryView::fullReload, this, &HistoryWidget::fullReload);
130 connect(mRepositoryView, &CommitHistoryView::referencesReload, this, &HistoryWidget::referencesReload);
131 connect(mRepositoryView, &CommitHistoryView::logReload, this, &HistoryWidget::logReload);
132
133 connect(mRepositoryView, &CommitHistoryView::signalOpenDiff, this, &HistoryWidget::onOpenFullDiff);
134 connect(mRepositoryView, &CommitHistoryView::signalOpenCompareDiff, this, &HistoryWidget::signalOpenCompareDiff);
135 connect(mRepositoryView, &CommitHistoryView::clicked, this, &HistoryWidget::commitSelected);
136 connect(mRepositoryView, &CommitHistoryView::customContextMenuRequested, this, [this](const QPoint &pos) {
137 const auto rowIndex = mRepositoryView->indexAt(pos);
138 commitSelected(rowIndex);
139 });
140 connect(mRepositoryView, &CommitHistoryView::signalAmendCommit, this, &HistoryWidget::onAmendCommit);
141 connect(mRepositoryView, &CommitHistoryView::signalMergeRequired, this, &HistoryWidget::mergeBranch);
142 connect(mRepositoryView, &CommitHistoryView::mergeSqushRequested, this, &HistoryWidget::mergeSquashBranch);
143 connect(mRepositoryView, &CommitHistoryView::signalCherryPickConflict, this,
144 &HistoryWidget::signalCherryPickConflict);
145 connect(mRepositoryView, &CommitHistoryView::signalPullConflict, this, &HistoryWidget::signalPullConflict);
146 connect(mRepositoryView, &CommitHistoryView::showPrDetailedView, this, &HistoryWidget::showPrDetailedView);
147
148 mRepositoryView->setObjectName("historyGraphView");
149 mRepositoryView->setModel(mRepositoryModel);
150 mRepositoryView->setItemDelegate(mItemDelegate
151 = new RepositoryViewDelegate(cache, mGit, mGitServerCache, mRepositoryView));
152 mRepositoryView->setEnabled(true);
153
154 mBranchesWidget = new BranchesWidget(mCache, mGit);
155
156 connect(mBranchesWidget, &BranchesWidget::fullReload, this, &HistoryWidget::fullReload);
157 connect(mBranchesWidget, &BranchesWidget::logReload, this, &HistoryWidget::logReload);
158
159 connect(mBranchesWidget, &BranchesWidget::signalSelectCommit, mRepositoryView, &CommitHistoryView::focusOnCommit);
160 connect(mBranchesWidget, &BranchesWidget::signalSelectCommit, this, &HistoryWidget::goToSha);
161 connect(mBranchesWidget, &BranchesWidget::signalOpenSubmodule, this, &HistoryWidget::signalOpenSubmodule);
162 connect(mBranchesWidget, &BranchesWidget::signalMergeRequired, this, &HistoryWidget::mergeBranch);
163 connect(mBranchesWidget, &BranchesWidget::mergeSqushRequested, this, &HistoryWidget::mergeSquashBranch);
164 connect(mBranchesWidget, &BranchesWidget::signalPullConflict, this, &HistoryWidget::signalPullConflict);
165 connect(mBranchesWidget, &BranchesWidget::panelsVisibilityChanged, this, &HistoryWidget::panelsVisibilityChanged);
166
167 const auto cherryPickBtn = new QPushButton(tr("Cherry-pick"));
168 cherryPickBtn->setEnabled(false);
169 cherryPickBtn->setObjectName("cherryPickBtn");
170 cherryPickBtn->setToolTip("Cherry-pick the commit");
171 connect(cherryPickBtn, &QPushButton::clicked, this, &HistoryWidget::cherryPickCommit);
172 connect(mSearchInput, &QLineEdit::textChanged, this,
173 [cherryPickBtn](const QString &text) { cherryPickBtn->setEnabled(!text.isEmpty()); });
174
175 mChShowAllBranches = new CheckBox(tr("Show all branches"));
176 mChShowAllBranches->setChecked(mSettings->localValue("ShowAllBranches", true).toBool());
177 connect(mChShowAllBranches, &CheckBox::toggled, this, &HistoryWidget::onShowAllUpdated);
178
179 const auto graphOptionsLayout = new QHBoxLayout();
180 graphOptionsLayout->setContentsMargins(QMargins());
181 graphOptionsLayout->setSpacing(10);
182 graphOptionsLayout->addWidget(mSearchInput);
183 graphOptionsLayout->addWidget(cherryPickBtn);
184 graphOptionsLayout->addWidget(mChShowAllBranches);
185
186 const auto viewLayout = new QVBoxLayout();
187 viewLayout->setContentsMargins(QMargins());
188 viewLayout->setSpacing(5);
189 viewLayout->addLayout(graphOptionsLayout);
190 viewLayout->addWidget(mRepositoryView);
191
192 mGraphFrame = new QFrame();
193 mGraphFrame->setLayout(viewLayout);
194
195 mFileDiff = new FileDiffWidget(mGit, mCache);
196
197 mReturnFromFull->setIcon(QIcon(":/icons/back"));
198 connect(mReturnFromFull, &QPushButton::clicked, this, &HistoryWidget::returnToView);
199 mFullDiffWidget = new FullDiffWidget(mGit, mCache);
200
201 const auto fullFrame = new QFrame();
202 const auto fullLayout = new QGridLayout(fullFrame);
203 fullLayout->setSpacing(10);
204 fullLayout->setContentsMargins(QMargins());
205 fullLayout->addWidget(mReturnFromFull, 0, 0);
206 fullLayout->addItem(new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Fixed), 0, 1);
207 fullLayout->addWidget(mFullDiffWidget, 1, 0, 1, 2);
208
209 mCenterStackedWidget = new QStackedWidget();
210 mCenterStackedWidget->setMinimumWidth(600);
211 mCenterStackedWidget->insertWidget(static_cast<int>(Pages::Graph), mGraphFrame);
212 mCenterStackedWidget->insertWidget(static_cast<int>(Pages::FileDiff), mFileDiff);
213 mCenterStackedWidget->insertWidget(static_cast<int>(Pages::FullDiff), fullFrame);
214
215 connect(mFileDiff, &FileDiffWidget::exitRequested, this, &HistoryWidget::returnToView);
216 connect(mFileDiff, &FileDiffWidget::fileStaged, this, &HistoryWidget::signalUpdateWip);
217 connect(mFileDiff, &FileDiffWidget::fileReverted, this, &HistoryWidget::signalUpdateWip);
218
219 connect(mWipWidget, &WipWidget::signalEditFile, mFileDiff, [this](const QString &fileName) {
220 showFileDiffEdition(CommitInfo::ZERO_SHA, mCache->commitInfo(CommitInfo::ZERO_SHA).firstParent(), fileName);
221 });
222
223 mSplitter->insertWidget(0, wipFrame);
224 mSplitter->insertWidget(1, mCenterStackedWidget);
225 mSplitter->setCollapsible(1, false);
226 mSplitter->insertWidget(2, mBranchesWidget);
227
228 const auto minimalActive = mBranchesWidget->isMinimalViewActive();
229 const auto branchesWidth = minimalActive ? 50 : 200;
230
231 rearrangeSplittrer(minimalActive);
232
233 connect(mBranchesWidget, &BranchesWidget::minimalViewStateChanged, this, &HistoryWidget::rearrangeSplittrer);
234
235 const auto splitterSate = mSettings->localValue("HistoryWidgetState", QByteArray()).toByteArray();
236
237 if (splitterSate.isEmpty())
238 mSplitter->setSizes({ 200, 500, branchesWidth });
239 else
240 mSplitter->restoreState(splitterSate);
241
242 const auto layout = new QHBoxLayout(this);
243 layout->setContentsMargins(QMargins());
244 layout->addWidget(mSplitter);
245
246 mCenterStackedWidget->setCurrentIndex(static_cast<int>(Pages::Graph));
247 mCenterStackedWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
248 mBranchesWidget->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
249}
250
251HistoryWidget::~HistoryWidget()
252{
253 mSettings->setLocalValue("HistoryWidgetState", mSplitter->saveState());
254
255 delete mItemDelegate;
256 delete mRepositoryModel;
257}
258
259void HistoryWidget::clear()
260{
261 mRepositoryView->clear();
262 resetWip();
263 mBranchesWidget->clear();
264 mCommitInfoWidget->clear();
265 mAmendWidget->clear();
266
267 mCommitStackedWidget->setCurrentIndex(mCommitStackedWidget->currentIndex());
268}
269
270void HistoryWidget::resetWip()
271{
272 mWipWidget->clear();
273}
274
275void HistoryWidget::loadBranches(bool fullReload)
276{
277 if (fullReload)
278 mBranchesWidget->showBranches();
279 else
280 mBranchesWidget->refreshCurrentBranchLink();
281}
282
283void HistoryWidget::updateUiFromWatcher()
284{
285 if (const auto widget = dynamic_cast<CommitChangesWidget *>(mCommitStackedWidget->currentWidget()))
286 widget->reload();
287
288 if (const auto widget = dynamic_cast<IDiffWidget *>(mCenterStackedWidget->currentWidget()))
289 widget->reload();
290}
291
292void HistoryWidget::focusOnCommit(const QString &sha)
293{
294 mRepositoryView->focusOnCommit(sha);
295}
296
297void HistoryWidget::updateGraphView(int totalCommits)
298{
299 mRepositoryModel->onNewRevisions(totalCommits);
300
301 selectCommit(CommitInfo::ZERO_SHA);
302
303 mRepositoryView->selectionModel()->select(
304 QItemSelection(mRepositoryModel->index(0, 0), mRepositoryModel->index(0, mRepositoryModel->columnCount() - 1)),
305 QItemSelectionModel::Select);
306}
307
308void HistoryWidget::keyPressEvent(QKeyEvent *event)
309{
310 if (event->key() == Qt::Key_Shift)
311 mReverseSearch = true;
312
313 QFrame::keyPressEvent(event);
314}
315
316void HistoryWidget::keyReleaseEvent(QKeyEvent *event)
317{
318 if (event->key() == Qt::Key_Shift)
319 mReverseSearch = false;
320
321 QFrame::keyReleaseEvent(event);
322}
323
324void HistoryWidget::onOpenFullDiff(const QString &sha)
325{
326 if (sha == CommitInfo::ZERO_SHA)
327 {
328 const auto commit = mCache->commitInfo(CommitInfo::ZERO_SHA);
329 QScopedPointer<GitHistory> git(new GitHistory(mGit));
330 const auto ret = git->getCommitDiff(CommitInfo::ZERO_SHA, commit.firstParent());
331
332 if (ret.success && !ret.output.isEmpty())
333 {
334 mFullDiffWidget->loadDiff(CommitInfo::ZERO_SHA, commit.firstParent(), ret.output);
335 mCenterStackedWidget->setCurrentIndex(static_cast<int>(Pages::FullDiff));
336 }
337 else
338 QMessageBox::warning(this, tr("No diff available!"), tr("There is no diff to show."));
339 }
340 else
341 emit signalOpenDiff(sha);
342}
343
344void HistoryWidget::rearrangeSplittrer(bool minimalActive)
345{
346 if (minimalActive)
347 {
348 mBranchesWidget->setFixedWidth(50);
349 mSplitter->setCollapsible(2, false);
350 }
351 else
352 {
353 mBranchesWidget->setMinimumWidth(250);
354 mBranchesWidget->setMaximumWidth(500);
355 mSplitter->setCollapsible(2, true);
356 }
357}
358
359void HistoryWidget::cleanCommitPanels()
360{
361 mWipWidget->clearStaged();
362 mAmendWidget->clearStaged();
363}
364
365void HistoryWidget::onRevertedChanges()
366{
367 QScopedPointer<GitWip> git(new GitWip(mGit, mCache));
368 git->updateWip();
369
370 updateUiFromWatcher();
371}
372
373void HistoryWidget::onCommitTitleMaxLenghtChanged()
374{
375 mWipWidget->setCommitTitleMaxLength();
376 mAmendWidget->setCommitTitleMaxLength();
377}
378
379void HistoryWidget::onPanelsVisibilityChanged()
380{
381 mBranchesWidget->onPanelsVisibilityChaned();
382}
383
384void HistoryWidget::search()
385{
386 if (const auto text = mSearchInput->text(); !text.isEmpty())
387 {
388 auto commitInfo = mCache->commitInfo(text);
389
390 if (commitInfo.isValid())
391 goToSha(text);
392 else
393 {
394 auto selectedItems = mRepositoryView->selectedIndexes();
395 auto startingRow = 0;
396
397 if (!selectedItems.isEmpty())
398 {
399 std::sort(selectedItems.begin(), selectedItems.end(),
400 [](const QModelIndex index1, const QModelIndex index2) { return index1.row() <= index2.row(); });
401 startingRow = selectedItems.constFirst().row();
402 }
403
404 commitInfo = mCache->searchCommitInfo(text, startingRow + 1, mReverseSearch);
405
406 if (commitInfo.isValid())
407 goToSha(commitInfo.sha);
408 else
409 QMessageBox::information(this, tr("Not found!"), tr("No commits where found based on the search text."));
410 }
411 }
412}
413
414void HistoryWidget::goToSha(const QString &sha)
415{
416 mRepositoryView->focusOnCommit(sha);
417
418 selectCommit(sha);
419}
420
421void HistoryWidget::commitSelected(const QModelIndex &index)
422{
423 const auto sha = mRepositoryModel->sha(index.row());
424
425 selectCommit(sha);
426}
427
428void HistoryWidget::onShowAllUpdated(bool showAll)
429{
430 GitQlientSettings settings(mGit->getGitDir());
431 settings.setLocalValue("ShowAllBranches", showAll);
432
433 emit signalAllBranchesActive(showAll);
434 emit logReload();
435}
436
437void HistoryWidget::mergeBranch(const QString &current, const QString &branchToMerge)
438{
439 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
440 QScopedPointer<GitMerge> git(new GitMerge(mGit, mCache));
441 const auto ret = git->merge(current, { branchToMerge });
442
443 QScopedPointer<GitWip> gitWip(new GitWip(mGit, mCache));
444 gitWip->updateWip();
445
446 QApplication::restoreOverrideCursor();
447
448 processMergeResponse(ret);
449}
450
451void HistoryWidget::mergeSquashBranch(const QString &current, const QString &branchToMerge)
452{
453 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
454 QScopedPointer<GitMerge> git(new GitMerge(mGit, mCache));
455 const auto ret = git->squashMerge(current, { branchToMerge });
456
457 QScopedPointer<GitWip> gitWip(new GitWip(mGit, mCache));
458 gitWip->updateWip();
459
460 QApplication::restoreOverrideCursor();
461
462 processMergeResponse(ret);
463}
464
465void HistoryWidget::processMergeResponse(const GitExecResult &ret)
466{
467 if (!ret.success)
468 {
469 QMessageBox msgBox(
470 QMessageBox::Critical, tr("Merge failed"),
471 QString(tr("There were problems during the merge. Please, see the detailed description for more "
472 "information.<br><br>GitQlient will show the merge helper tool.")),
473 QMessageBox::Ok, this);
474 msgBox.setDetailedText(ret.output);
475 msgBox.setStyleSheet(GitQlientStyles::getStyles());
476 msgBox.exec();
477
478 emit signalMergeConflicts();
479 }
480 else
481 {
482 if (!ret.output.isEmpty())
483 {
484 if (ret.output.contains("error: could not apply", Qt::CaseInsensitive)
485 || ret.output.contains(" conflict", Qt::CaseInsensitive))
486 {
487 QMessageBox msgBox(
488 QMessageBox::Warning, tr("Merge status"),
489 tr("There were problems during the merge. Please, see the detailed description for more information."),
490 QMessageBox::Ok, this);
491 msgBox.setDetailedText(ret.output);
492 msgBox.setStyleSheet(GitQlientStyles::getStyles());
493 msgBox.exec();
494
495 emit signalMergeConflicts();
496 }
497 else
498 {
499 emit fullReload();
500
501 QMessageBox msgBox(
502 QMessageBox::Information, tr("Merge successful"),
503 tr("The merge was successfully done. See the detailed description for more information."),
504 QMessageBox::Ok, this);
505 msgBox.setDetailedText(ret.output);
506 msgBox.setStyleSheet(GitQlientStyles::getStyles());
507 msgBox.exec();
508 }
509 }
510 }
511}
512
513void HistoryWidget::selectCommit(const QString &goToSha)
514{
515 const auto isWip = goToSha == CommitInfo::ZERO_SHA;
516 mCommitStackedWidget->setCurrentIndex(isWip);
517
518 QLog_Info("UI", QString("Selected commit {%1}").arg(goToSha));
519
520 if (isWip)
521 mWipWidget->reload();
522 else
523 mCommitInfoWidget->configure(goToSha);
524}
525
526void HistoryWidget::onAmendCommit(const QString &sha)
527{
528 mCommitStackedWidget->setCurrentIndex(2);
529 mAmendWidget->configure(sha);
530}
531
532void HistoryWidget::returnToView()
533{
534 mCenterStackedWidget->setCurrentIndex(static_cast<int>(Pages::Graph));
535 mBranchesWidget->returnToSavedView();
536}
537
538void HistoryWidget::cherryPickCommit()
539{
540 if (auto commit = mCache->commitInfo(mSearchInput->text()); commit.isValid())
541 {
542 const auto lastShaBeforeCommit = mGit->getLastCommit().output.trimmed();
543 const auto git = QScopedPointer<GitLocal>(new GitLocal(mGit));
544 const auto ret = git->cherryPickCommit(commit.sha);
545
546 if (ret.success)
547 {
548 mSearchInput->clear();
549
550 commit.sha = mGit->getLastCommit().output.trimmed();
551
552 mCache->insertCommit(commit);
553 mCache->deleteReference(lastShaBeforeCommit, References::Type::LocalBranch, mGit->getCurrentBranch());
554 mCache->insertReference(commit.sha, References::Type::LocalBranch, mGit->getCurrentBranch());
555
556 QScopedPointer<GitHistory> gitHistory(new GitHistory(mGit));
557 const auto ret = gitHistory->getDiffFiles(commit.sha, lastShaBeforeCommit);
558
559 mCache->insertRevisionFiles(commit.sha, lastShaBeforeCommit, RevisionFiles(ret.output));
560
561 emit mCache->signalCacheUpdated();
562 emit logReload();
563 }
564 else
565 {
566 if (ret.output.contains("error: could not apply", Qt::CaseInsensitive)
567 || ret.output.contains(" conflict", Qt::CaseInsensitive))
568 {
569 emit signalCherryPickConflict(QStringList());
570 }
571 else
572 {
573 QMessageBox msgBox(QMessageBox::Critical, tr("Error while cherry-pick"),
574 tr("There were problems during the cherry-pick operation. Please, see the detailed "
575 "description for more information."),
576 QMessageBox::Ok, this);
577 msgBox.setDetailedText(ret.output);
578 msgBox.setStyleSheet(GitQlientStyles::getStyles());
579 msgBox.exec();
580 }
581 }
582 }
583 else
584 {
585 const auto git = QScopedPointer<GitLocal>(new GitLocal(mGit));
586 const auto ret = git->cherryPickCommit(mSearchInput->text());
587
588 if (ret.success)
589 {
590 mSearchInput->clear();
591 emit logReload();
592 }
593 }
594}
595
596void HistoryWidget::showFileDiff(const QString &sha, const QString &parentSha, const QString &fileName, bool isCached)
597{
598 if (sha == CommitInfo::ZERO_SHA)
599 {
600 mFileDiff->configure(sha, parentSha, fileName, isCached);
601 mCenterStackedWidget->setCurrentIndex(static_cast<int>(Pages::FileDiff));
602 mBranchesWidget->forceMinimalView();
603 }
604 else
605 emit signalShowDiff(sha, parentSha, fileName, isCached);
606}
607
608void HistoryWidget::showFileDiffEdition(const QString &sha, const QString &parentSha, const QString &fileName)
609{
610 if (sha == CommitInfo::ZERO_SHA)
611 {
612 mFileDiff->configure(sha, parentSha, fileName, true);
613 mCenterStackedWidget->setCurrentIndex(static_cast<int>(Pages::FileDiff));
614 mBranchesWidget->forceMinimalView();
615 }
616 else
617 emit signalShowDiff(sha, parentSha, fileName, false);
618}
619