From 2559f986938158e0881bcae8a46eb82a75c82413 Mon Sep 17 00:00:00 2001
From: Orgad Shaneh <orgad.shaneh@audiocodes.com>
Date: Mon, 7 Oct 2013 10:26:13 +0300
Subject: [PATCH] Git: Improve branch name validation

* Do not allow leading dash
* Do not allow existing local branches

Change-Id: I3efbb90b7099719a7e90cada85a58a0f91bd9730
Reviewed-by: Tobias Hunger <tobias.hunger@digia.com>
---
 src/plugins/git/branchadddialog.cpp | 19 ++++++++++++++-----
 src/plugins/git/branchadddialog.h   |  2 +-
 src/plugins/git/branchdialog.cpp    | 10 ++--------
 3 files changed, 17 insertions(+), 14 deletions(-)

diff --git a/src/plugins/git/branchadddialog.cpp b/src/plugins/git/branchadddialog.cpp
index 979b0cdb545..df5d2ba9cf1 100644
--- a/src/plugins/git/branchadddialog.cpp
+++ b/src/plugins/git/branchadddialog.cpp
@@ -30,6 +30,8 @@
 #include "branchadddialog.h"
 #include "ui_branchadddialog.h"
 
+#include <utils/hostosinfo.h>
+
 #include <QPushButton>
 #include <QValidator>
 
@@ -46,7 +48,7 @@ namespace Internal {
 class BranchNameValidator : public QValidator
 {
 public:
-    BranchNameValidator(QObject *parent = 0) :
+    BranchNameValidator(const QStringList &localBranches, QObject *parent = 0) :
         QValidator(parent),
         m_invalidChars(QLatin1String(
                                    "\\s"          // no whitespace
@@ -59,8 +61,9 @@ public:
                                    "|@\\{"      // no "@{" sequence
                                    "|\\\\"      // no backslash
                                    "|//"    // no double slash
-                                   "|^/"  // no leading slash
-                                   ))
+                                   "|^[/-]"  // no leading slash or dash
+                                   )),
+        m_localBranches(localBranches)
     {
     }
 
@@ -87,22 +90,28 @@ public:
         if (input.endsWith(QLatin1Char('/'))) // no slash at the end (but allowed in the middle)
             return Intermediate;
 
+        if (m_localBranches.contains(input, Utils::HostOsInfo::isWindowsHost()
+                                     ? Qt::CaseInsensitive : Qt::CaseSensitive)) {
+            return Intermediate;
+        }
+
         // is a valid branch name
         return Acceptable;
     }
 
 private:
     const QRegExp m_invalidChars;
+    QStringList m_localBranches;
 };
 
 
-BranchAddDialog::BranchAddDialog(bool addBranch, QWidget *parent) :
+BranchAddDialog::BranchAddDialog(const QStringList &localBranches, bool addBranch, QWidget *parent) :
     QDialog(parent),
     m_ui(new Ui::BranchAddDialog)
 {
     m_ui->setupUi(this);
     setWindowTitle(addBranch ? tr("Add Branch") : tr("Rename Branch"));
-    m_ui->branchNameEdit->setValidator(new BranchNameValidator(this));
+    m_ui->branchNameEdit->setValidator(new BranchNameValidator(localBranches, this));
     connect(m_ui->branchNameEdit, SIGNAL(textChanged(QString)), this, SLOT(updateButtonStatus()));
 }
 
diff --git a/src/plugins/git/branchadddialog.h b/src/plugins/git/branchadddialog.h
index eb9df638f48..df67d55a4cf 100644
--- a/src/plugins/git/branchadddialog.h
+++ b/src/plugins/git/branchadddialog.h
@@ -45,7 +45,7 @@ class BranchAddDialog : public QDialog
     Q_OBJECT
 
 public:
-    BranchAddDialog(bool addBranch, QWidget *parent);
+    BranchAddDialog(const QStringList &localBranches, bool addBranch, QWidget *parent);
     ~BranchAddDialog();
 
     void setBranchName(const QString &);
diff --git a/src/plugins/git/branchdialog.cpp b/src/plugins/git/branchdialog.cpp
index fa5321f479f..9fadf16934a 100644
--- a/src/plugins/git/branchdialog.cpp
+++ b/src/plugins/git/branchdialog.cpp
@@ -154,7 +154,7 @@ void BranchDialog::add()
         ++i;
     }
 
-    BranchAddDialog branchAddDialog(true, this);
+    BranchAddDialog branchAddDialog(localNames, true, this);
     branchAddDialog.setBranchName(suggestedName);
     branchAddDialog.setTrackedBranchName(isTag ? QString() : trackedBranch, !isLocal);
 
@@ -276,7 +276,7 @@ void BranchDialog::rename()
     if (!isTag)
         localNames = m_model->localBranchNames();
 
-    BranchAddDialog branchAddDialog(false, this);
+    BranchAddDialog branchAddDialog(localNames, false, this);
     if (isTag)
         branchAddDialog.setWindowTitle(tr("Rename Tag"));
     branchAddDialog.setBranchName(oldName);
@@ -287,12 +287,6 @@ void BranchDialog::rename()
     if (branchAddDialog.result() == QDialog::Accepted && m_model) {
         if (branchAddDialog.branchName() == oldName)
             return;
-        if (localNames.contains(branchAddDialog.branchName())) {
-            QMessageBox::critical(this, tr("Branch Exists"),
-                                  tr("Local branch \'%1\' already exists.")
-                                  .arg(branchAddDialog.branchName()));
-            return;
-        }
         if (isTag)
             m_model->renameTag(oldName, branchAddDialog.branchName());
         else
-- 
GitLab