1#include "BranchDlg.h"
2#include "ui_BranchDlg.h"
3
4#include <GitBase.h>
5#include <GitBranches.h>
6#include <GitCache.h>
7#include <GitConfig.h>
8#include <GitQlientStyles.h>
9#include <GitStashes.h>
10
11#include <QFile>
12#include <QMessageBox>
13
14#include <utility>
15
16BranchDlg::BranchDlg(BranchDlgConfig config, QWidget *parent)
17 : QDialog(parent)
18 , ui(new Ui::BranchDlg)
19 , mConfig(std::move(config))
20{
21 setStyleSheet(GitQlientStyles::getStyles());
22
23 ui->setupUi(this);
24 ui->leOldName->setText(mConfig.mCurrentBranchName);
25
26 ui->chbCopyRemote->setHidden(true);
27
28 switch (mConfig.mDialogMode)
29 {
30 case BranchDlgMode::CREATE:
31 setWindowTitle(tr("Create branch"));
32 break;
33 case BranchDlgMode::RENAME:
34 ui->pbAccept->setText(tr("Rename"));
35 setWindowTitle("Rename branch");
36 break;
37 case BranchDlgMode::CREATE_CHECKOUT:
38 setWindowTitle(tr("Create and checkout branch"));
39 ui->leOldName->setHidden(true);
40 break;
41 case BranchDlgMode::CREATE_FROM_COMMIT:
42 setWindowTitle(tr("Create branch at commit"));
43 ui->leOldName->setHidden(true);
44 break;
45 case BranchDlgMode::CREATE_CHECKOUT_FROM_COMMIT:
46 setWindowTitle(tr("Create and checkout branch"));
47 ui->leOldName->setHidden(true);
48 break;
49 case BranchDlgMode::STASH_BRANCH:
50 setWindowTitle(tr("Stash branch"));
51 break;
52 case BranchDlgMode::PUSH_UPSTREAM:
53 ui->chbCopyRemote->setVisible(true);
54 connect(ui->chbCopyRemote, &CheckBox::clicked, this, &BranchDlg::copyBranchName);
55 setWindowTitle(tr("Push upstream branch"));
56 ui->pbAccept->setText(tr("Push"));
57 break;
58 default:
59 break;
60 }
61
62 connect(ui->leNewName, &QLineEdit::editingFinished, this, &BranchDlg::checkNewBranchName);
63 connect(ui->leNewName, &QLineEdit::returnPressed, this, &BranchDlg::accept);
64 connect(ui->pbAccept, &QPushButton::clicked, this, &BranchDlg::accept);
65 connect(ui->pbCancel, &QPushButton::clicked, this, &BranchDlg::reject);
66}
67
68BranchDlg::~BranchDlg()
69{
70 delete ui;
71}
72
73void BranchDlg::checkNewBranchName()
74{
75 if (ui->leNewName->text() == ui->leOldName->text() && mConfig.mDialogMode != BranchDlgMode::PUSH_UPSTREAM)
76 ui->leNewName->setStyleSheet("border: 1px solid red;");
77}
78
79void BranchDlg::accept()
80{
81 if (ui->leNewName->text() == ui->leOldName->text() && mConfig.mDialogMode != BranchDlgMode::PUSH_UPSTREAM)
82 ui->leNewName->setStyleSheet("border: 1px solid red;");
83 else
84 {
85 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
86
87 QScopedPointer<GitBranches> git(new GitBranches(mConfig.mGit));
88 GitExecResult ret;
89
90 if (mConfig.mDialogMode == BranchDlgMode::CREATE)
91 {
92 ret = git->createBranchFromAnotherBranch(ui->leOldName->text(), ui->leNewName->text());
93
94 if (ret.success)
95 {
96 auto type = References::Type::LocalBranch;
97 auto sha = mConfig.mCache->getShaOfReference(ui->leOldName->text(), type);
98
99 if (sha.isEmpty())
100 {
101 type = References::Type::RemoteBranches;
102 sha = mConfig.mCache->getShaOfReference(ui->leOldName->text(), type);
103 }
104
105 if (!sha.isEmpty())
106 {
107 mConfig.mCache->insertReference(sha, type, ui->leNewName->text());
108 emit mConfig.mCache->signalCacheUpdated();
109 }
110 }
111 }
112 else if (mConfig.mDialogMode == BranchDlgMode::CREATE_CHECKOUT)
113 {
114 ret = git->checkoutNewLocalBranch(ui->leNewName->text());
115
116 if (ret.success)
117 {
118 mConfig.mCache->insertReference(mConfig.mGit->getLastCommit().output.trimmed(),
119 References::Type::LocalBranch, ui->leNewName->text());
120 emit mConfig.mCache->signalCacheUpdated();
121 }
122 }
123 else if (mConfig.mDialogMode == BranchDlgMode::RENAME)
124 {
125 ret = git->renameBranch(ui->leOldName->text(), ui->leNewName->text());
126
127 if (ret.success)
128 {
129 const auto type = References::Type::LocalBranch;
130 const auto sha = mConfig.mCache->getShaOfReference(ui->leOldName->text(), type);
131
132 mConfig.mCache->deleteReference(sha, type, ui->leOldName->text());
133 mConfig.mCache->insertReference(sha, type, ui->leNewName->text());
134 emit mConfig.mCache->signalCacheUpdated();
135 }
136 }
137 else if (mConfig.mDialogMode == BranchDlgMode::CREATE_FROM_COMMIT)
138 {
139 ret = git->createBranchAtCommit(ui->leOldName->text(), ui->leNewName->text());
140
141 if (ret.success)
142 {
143 mConfig.mCache->insertReference(ui->leOldName->text(), References::Type::LocalBranch,
144 ui->leNewName->text());
145 emit mConfig.mCache->signalCacheUpdated();
146 }
147 }
148 else if (mConfig.mDialogMode == BranchDlgMode::CREATE_CHECKOUT_FROM_COMMIT)
149 {
150 ret = git->checkoutBranchFromCommit(ui->leOldName->text(), ui->leNewName->text());
151
152 if (ret.success)
153 {
154 mConfig.mCache->insertReference(ui->leOldName->text(), References::Type::LocalBranch,
155 ui->leNewName->text());
156 emit mConfig.mCache->signalCacheUpdated();
157 }
158 }
159 else if (mConfig.mDialogMode == BranchDlgMode::STASH_BRANCH)
160 {
161 QScopedPointer<GitStashes> git(new GitStashes(mConfig.mGit));
162 ret = git->stashBranch(ui->leOldName->text(), ui->leNewName->text());
163 }
164 else if (mConfig.mDialogMode == BranchDlgMode::PUSH_UPSTREAM)
165 {
166 ret = git->pushUpstream(ui->leNewName->text());
167
168 if (ret.success)
169 {
170 QScopedPointer<GitConfig> git(new GitConfig(mConfig.mGit));
171 const auto remote = git->getRemoteForBranch(ui->leNewName->text());
172
173 if (remote.success)
174 {
175 const auto sha = mConfig.mCache->getShaOfReference(ui->leOldName->text(), References::Type::LocalBranch);
176 mConfig.mCache->insertReference(sha, References::Type::RemoteBranches,
177 QString("%1/%2").arg(remote.output, ui->leNewName->text()));
178 emit mConfig.mCache->signalCacheUpdated();
179 }
180 }
181 }
182
183 QApplication::restoreOverrideCursor();
184
185 if (!ret.success)
186 {
187 QDialog::reject();
188
189 QMessageBox msgBox(
190 QMessageBox::Critical, tr("Error on branch action!"),
191 QString(tr("There were problems during the branch operation. Please, see the detailed description "
192 "for more information.")),
193 QMessageBox::Ok, this);
194 msgBox.setDetailedText(ret.output);
195 msgBox.setStyleSheet(GitQlientStyles::getStyles());
196 msgBox.exec();
197 }
198 else
199 QDialog::accept();
200 }
201}
202
203void BranchDlg::copyBranchName()
204{
205 const auto remote = ui->leOldName->text();
206 ui->leNewName->setText(remote);
207}
208