From 7df112b687c8694153ef3a5938921104b6e75115 Mon Sep 17 00:00:00 2001 From: Petar Perisin <petar.perisin@gmail.com> Date: Fri, 21 Dec 2012 23:49:29 +0100 Subject: [PATCH] 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> --- src/plugins/git/branchdialog.cpp | 39 +++++++++ src/plugins/git/branchdialog.h | 2 + src/plugins/git/branchdialog.ui | 133 +++++++++++++++++++++---------- src/plugins/git/gitclient.cpp | 23 +++++- src/plugins/git/gitclient.h | 6 +- 5 files changed, 156 insertions(+), 47 deletions(-) diff --git a/src/plugins/git/branchdialog.cpp b/src/plugins/git/branchdialog.cpp index 59eaa1ec7eb..b39adce43c9 100644 --- a/src/plugins/git/branchdialog.cpp +++ b/src/plugins/git/branchdialog.cpp @@ -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); diff --git a/src/plugins/git/branchdialog.h b/src/plugins/git/branchdialog.h index cded4f1c038..5e06e343deb 100644 --- a/src/plugins/git/branchdialog.h +++ b/src/plugins/git/branchdialog.h @@ -71,6 +71,8 @@ private slots: void remove(); void diff(); void log(); + void merge(); + void rebase(); protected: void changeEvent(QEvent *e); diff --git a/src/plugins/git/branchdialog.ui b/src/plugins/git/branchdialog.ui index 1689119b666..5c9f1fd462f 100644 --- a/src/plugins/git/branchdialog.ui +++ b/src/plugins/git/branchdialog.ui @@ -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>&Add...</string> - </property> - </widget> - </item> - <item row="1" column="2"> - <widget class="QPushButton" name="removeButton"> - <property name="text"> - <string>&Remove</string> - </property> - </widget> - </item> - <item row="2" column="0"> - <widget class="QPushButton" name="diffButton"> - <property name="text"> - <string>&Diff</string> - </property> - </widget> - </item> - <item row="2" column="2"> - <widget class="QPushButton" name="logButton"> - <property name="text"> - <string>&Log</string> - </property> - </widget> - </item> - <item row="1" column="1"> - <widget class="QPushButton" name="checkoutButton"> - <property name="text"> - <string>&Checkout</string> + <item> + <layout class="QVBoxLayout" name="verticalLayout"> + <property name="spacing"> + <number>15</number> </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>&Add...</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="removeButton"> + <property name="text"> + <string>&Remove</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="checkoutButton"> + <property name="text"> + <string>&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>&Diff</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="logButton"> + <property name="text"> + <string>&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>&Merge</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="rebaseButton"> + <property name="text"> + <string>Re&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> diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index ac42ce7cc88..988883ed2c7 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -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."); diff --git a/src/plugins/git/gitclient.h b/src/plugins/git/gitclient.h index afc6f4968bd..8482febc92b 100644 --- a/src/plugins/git/gitclient.h +++ b/src/plugins/git/gitclient.h @@ -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, -- GitLab