From a6eb1b26403d6ad63acf30c9db1eba246835b77e Mon Sep 17 00:00:00 2001
From: "Christian A. Reiter" <christian.a.reiter@gmail.com>
Date: Sun, 9 Dec 2012 14:12:43 +0100
Subject: [PATCH] add branch name validation to git VCS plugin

Task-number: QTCREATORBUG-8370

Change-Id: Iadca383dc01a55deab2cbfdb5ef439dfb0f2ab12
Reviewed-by: Orgad Shaneh <orgads@gmail.com>
Reviewed-by: Tobias Hunger <tobias.hunger@digia.com>
---
 src/plugins/git/branchadddialog.cpp | 70 +++++++++++++++++++++++++++++
 src/plugins/git/branchadddialog.h   |  3 ++
 2 files changed, 73 insertions(+)

diff --git a/src/plugins/git/branchadddialog.cpp b/src/plugins/git/branchadddialog.cpp
index 4f9df40187d..ccb4cef21a2 100644
--- a/src/plugins/git/branchadddialog.cpp
+++ b/src/plugins/git/branchadddialog.cpp
@@ -30,14 +30,78 @@
 #include "branchadddialog.h"
 #include "ui_branchadddialog.h"
 
+#include <QPushButton>
+#include <QValidator>
+
 namespace Git {
 namespace Internal {
 
+/*!
+ * \brief Validates the corresponding string as a valid git branch name
+ *
+ * The class does this by a couple of rules that are applied on the string.
+ *
+ */
+class BranchNameValidator : public QValidator
+{
+public:
+    BranchNameValidator(QObject *parent = 0) :
+        QValidator(parent),
+        m_invalidChars(QLatin1String(
+                                   "\\s"          // no whitespace
+                                   "|~"         // no "~"
+                                   "|\\^"       // no "^"
+                                   "|\\["       // no "["
+                                   "|\\.\\."    // no ".."
+                                   "|/\\."      // no slashdot
+                                   "|:"         // no ":"
+                                   "|@\\{"      // no "@{" sequence
+                                   "|\\\\"      // no backslash
+                                   "|//"    // no double slash
+                                   "|^/"  // no leading slash
+                                   ))
+    {
+    }
+
+    ~BranchNameValidator() {}
+
+    State validate(QString &input, int &pos) const
+    {
+        Q_UNUSED(pos)
+
+        // NoGos
+
+        if (input.contains(m_invalidChars))
+            return Invalid;
+
+
+        // "Intermediate" patterns, may change to Acceptable when user edits further:
+
+        if (input.endsWith(QLatin1String(".lock"))) //..may not end with ".lock"
+            return Intermediate;
+
+        if (input.endsWith(QLatin1Char('.'))) // no dot at the end (but allowed in the middle)
+            return Intermediate;
+
+        if (input.endsWith(QLatin1Char('/'))) // no slash at the end (but allowed in the middle)
+            return Intermediate;
+
+        // is a valid branch name
+        return Acceptable;
+    }
+
+private:
+    const QRegExp m_invalidChars;
+};
+
+
 BranchAddDialog::BranchAddDialog(QWidget *parent) :
     QDialog(parent),
     m_ui(new Ui::BranchAddDialog)
 {
     m_ui->setupUi(this);
+    m_ui->branchNameEdit->setValidator(new BranchNameValidator(this));
+    connect(m_ui->branchNameEdit, SIGNAL(textChanged(QString)), this, SLOT(updateButtonStatus()));
 }
 
 BranchAddDialog::~BranchAddDialog()
@@ -72,5 +136,11 @@ bool BranchAddDialog::track()
     return m_ui->trackingCheckBox->isChecked();
 }
 
+/*! Updates the ok button enabled state of the dialog according to the validity of the branch name. */
+void BranchAddDialog::updateButtonStatus()
+{
+    m_ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(m_ui->branchNameEdit->hasAcceptableInput());
+}
+
 } // namespace Internal
 } // namespace Git
diff --git a/src/plugins/git/branchadddialog.h b/src/plugins/git/branchadddialog.h
index 77bd9b87041..ed8055a4736 100644
--- a/src/plugins/git/branchadddialog.h
+++ b/src/plugins/git/branchadddialog.h
@@ -55,6 +55,9 @@ public:
 
     bool track();
 
+private slots:
+    void updateButtonStatus();
+
 private:
     Ui::BranchAddDialog *m_ui;
 };
-- 
GitLab