Git: Added Merge and Rebase

Added git functions - "Merge" and "Rebase"
They are in the "Branches" dialog:
- Merge - merge selected branch into current one
- Rebase - rebase current branch on selected one

Task-number: QTCREATORBUG-8367

Change-Id: I9ed306c64d5d4b7bd1d58730a5e1009f0bd4ec0e
Reviewed-by: Orgad Shaneh <orgads@gmail.com>
Reviewed-by: Tobias Hunger <tobias.hunger@digia.com>
This commit is contained in:
Petar Perisin
2012-12-21 23:49:29 +01:00
committed by Tobias Hunger
parent 2396f34fda
commit 7df112b687
5 changed files with 156 additions and 47 deletions

View File

@@ -65,6 +65,8 @@ BranchDialog::BranchDialog(QWidget *parent) :
connect(m_ui->removeButton, SIGNAL(clicked()), this, SLOT(remove()));
connect(m_ui->diffButton, SIGNAL(clicked()), this, SLOT(diff()));
connect(m_ui->logButton, SIGNAL(clicked()), this, SLOT(log()));
connect(m_ui->mergeButton, SIGNAL(clicked()), this, SLOT(merge()));
connect(m_ui->rebaseButton, SIGNAL(clicked()), this, SLOT(rebase()));
m_ui->branchView->setModel(m_model);
@@ -102,11 +104,14 @@ void BranchDialog::enableButtons()
const bool currentSelected = hasSelection && idx == m_model->currentBranch();
const bool isLocal = m_model->isLocal(idx);
const bool isLeaf = m_model->isLeaf(idx);
const bool currentLocal = m_model->isLocal(m_model->currentBranch());
m_ui->removeButton->setEnabled(hasSelection && !currentSelected && isLocal && isLeaf);
m_ui->logButton->setEnabled(hasSelection && isLeaf);
m_ui->diffButton->setEnabled(hasSelection && isLeaf);
m_ui->checkoutButton->setEnabled(hasSelection && !currentSelected && isLeaf);
m_ui->rebaseButton->setEnabled(hasSelection && !currentSelected && isLeaf && currentLocal);
m_ui->mergeButton->setEnabled(hasSelection && !currentSelected && isLeaf && currentLocal);
}
void BranchDialog::refresh()
@@ -194,6 +199,40 @@ void BranchDialog::log()
GitPlugin::instance()->gitClient()->graphLog(m_repository, branchName);
}
void BranchDialog::merge()
{
QModelIndex idx = selectedIndex();
QTC_CHECK(m_model->isLocal(m_model->currentBranch())); // otherwise the button would not be enabled!
QTC_CHECK(idx != m_model->currentBranch()); // otherwise the button would not be enabled!
const QString branch = m_model->branchName(idx);
GitClient *gitClient = GitPlugin::instance()->gitClient();
QString stashMessage;
if (gitClient->gitStatus(m_repository, StatusMode(NoUntracked | NoSubmodules)) == GitClient::StatusChanged)
stashMessage = gitClient->synchronousStash(m_repository, QLatin1String("merge"));
if (gitClient->synchronousMerge(m_repository, branch) && (!stashMessage.isEmpty()))
gitClient->stashPop(m_repository);
}
void BranchDialog::rebase()
{
QModelIndex idx = selectedIndex();
QTC_CHECK(m_model->isLocal(m_model->currentBranch())); // otherwise the button would not be enabled!
QTC_CHECK(idx != m_model->currentBranch()); // otherwise the button would not be enabled!
const QString baseBranch = m_model->branchName(idx);
GitClient *gitClient = GitPlugin::instance()->gitClient();
QString stashMessage;
if (gitClient->gitStatus(m_repository, StatusMode(NoUntracked | NoSubmodules)) == GitClient::StatusChanged)
stashMessage = gitClient->synchronousStash(m_repository, QLatin1String("rebase"));
if (gitClient->synchronousRebase(m_repository, baseBranch) && (!stashMessage.isEmpty()))
gitClient->stashPop(m_repository);
}
void BranchDialog::changeEvent(QEvent *e)
{
QDialog::changeEvent(e);

View File

@@ -71,6 +71,8 @@ private slots:
void remove();
void diff();
void log();
void merge();
void rebase();
protected:
void changeEvent(QEvent *e);

View File

@@ -51,17 +51,14 @@
<property name="title">
<string>Branches</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="topMargin">
<number>4</number>
</property>
<property name="bottomMargin">
<number>4</number>
</property>
<property name="verticalSpacing">
<number>9</number>
</property>
<item row="0" column="0" colspan="3">
<item>
<widget class="QTreeView" name="branchView">
<property name="rootIsDecorated">
<bool>false</bool>
@@ -74,40 +71,95 @@
</attribute>
</widget>
</item>
<item row="1" column="0">
<widget class="QPushButton" name="addButton">
<property name="text">
<string>&amp;Add...</string>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>15</number>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="removeButton">
<property name="text">
<string>&amp;Remove</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QPushButton" name="diffButton">
<property name="text">
<string>&amp;Diff</string>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QPushButton" name="logButton">
<property name="text">
<string>&amp;Log</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="checkoutButton">
<property name="text">
<string>&amp;Checkout</string>
</property>
</widget>
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="spacing">
<number>3</number>
</property>
<item>
<widget class="QPushButton" name="addButton">
<property name="text">
<string>&amp;Add...</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="removeButton">
<property name="text">
<string>&amp;Remove</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="checkoutButton">
<property name="text">
<string>&amp;Checkout</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_4">
<property name="spacing">
<number>3</number>
</property>
<item>
<widget class="QPushButton" name="diffButton">
<property name="text">
<string>&amp;Diff</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="logButton">
<property name="text">
<string>&amp;Log</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_5">
<property name="spacing">
<number>3</number>
</property>
<item>
<widget class="QPushButton" name="mergeButton">
<property name="text">
<string>&amp;Merge</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="rebaseButton">
<property name="text">
<string>Re&amp;base</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
@@ -126,11 +178,6 @@
</widget>
<tabstops>
<tabstop>branchView</tabstop>
<tabstop>addButton</tabstop>
<tabstop>checkoutButton</tabstop>
<tabstop>removeButton</tabstop>
<tabstop>diffButton</tabstop>
<tabstop>logButton</tabstop>
<tabstop>buttonBox</tabstop>
<tabstop>refreshButton</tabstop>
</tabstops>

View File

@@ -2096,7 +2096,7 @@ bool GitClient::synchronousFetch(const QString &workingDirectory, const QString
return resp.result == Utils::SynchronousProcessResponse::Finished;
}
bool GitClient::synchronousPullOrRebase(const QString &workingDirectory, const QStringList &arguments, bool rebase)
bool GitClient::synchronousMergeOrRebase(const QString &workingDirectory, const QStringList &arguments, bool rebase)
{
// Disable UNIX terminals to suppress SSH prompting.
const unsigned flags = VcsBase::VcsBasePlugin::SshPasswordPrompt|VcsBase::VcsBasePlugin::ShowStdOutInLogWindow;
@@ -2115,14 +2115,14 @@ bool GitClient::synchronousPull(const QString &workingDirectory, bool rebase)
QStringList arguments(QLatin1String("pull"));
if (rebase)
arguments << QLatin1String("--rebase");
return synchronousPullOrRebase(workingDirectory, arguments, rebase);
return synchronousMergeOrRebase(workingDirectory, arguments, rebase);
}
bool GitClient::synchronousRebaseContinue(const QString &workingDirectory)
{
QStringList arguments(QLatin1String("rebase"));
arguments << QLatin1String("--continue");
return synchronousPullOrRebase(workingDirectory, arguments, true);
return synchronousMergeOrRebase(workingDirectory, arguments, true);
}
void GitClient::handleMergeConflicts(const QString &workingDir, bool rebase)
@@ -2196,6 +2196,23 @@ bool GitClient::synchronousPush(const QString &workingDirectory, const QString &
return resp.result == Utils::SynchronousProcessResponse::Finished;
}
bool GitClient::synchronousMerge(const QString &workingDirectory, const QString &branch)
{
QStringList arguments(QLatin1String("merge"));
arguments << branch;
return synchronousMergeOrRebase(workingDirectory, arguments, false);
}
bool GitClient::synchronousRebase(const QString &workingDirectory, const QString &baseBranch,
const QString &topicBranch)
{
QStringList arguments(QLatin1String("rebase"));
arguments << baseBranch;
if (!topicBranch.isEmpty())
arguments << topicBranch;
return synchronousMergeOrRebase(workingDirectory, arguments, true);
}
QString GitClient::msgNoChangedFiles()
{
return tr("There are no modified files.");

View File

@@ -179,6 +179,10 @@ public:
bool synchronousPull(const QString &workingDirectory, bool rebase);
bool synchronousRebaseContinue(const QString &workingDirectory);
bool synchronousPush(const QString &workingDirectory, const QString &remote = QString());
bool synchronousMerge(const QString &workingDirectory, const QString &branch);
bool synchronousRebase(const QString &workingDirectory,
const QString &baseBranch,
const QString &topicBranch = QString());
// git svn support (asynchronous).
void synchronousSubversionFetch(const QString &workingDirectory);
@@ -296,7 +300,7 @@ private:
QString *errorMessage,
bool revertStaging);
void connectRepositoryChanged(const QString & repository, VcsBase::Command *cmd);
bool synchronousPullOrRebase(const QString &workingDirectory, const QStringList &arguments, bool rebase);
bool synchronousMergeOrRebase(const QString &workingDirectory, const QStringList &arguments, bool rebase);
void handleMergeConflicts(const QString &workingDir, bool rebase);
bool tryLauchingGitK(const QProcessEnvironment &env,
const QString &workingDirectory,