Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Utilities
Kate
Commits
1164d2c6
Commit
1164d2c6
authored
Feb 09, 2021
by
Waqar Ahmed
Browse files
Implement new branch simple checkcout
parent
f4d90a82
Changes
6
Hide whitespace changes
Inline
Side-by-side
addons/project/branchesdialog.cpp
View file @
1164d2c6
...
...
@@ -199,7 +199,12 @@ BranchesDialog::BranchesDialog(QWidget *parent, KTextEditor::MainWindow *mainWin
void
BranchesDialog
::
openDialog
()
{
const
QVector
<
GitUtils
::
Branch
>
branches
=
GitUtils
::
getAllBranches
(
m_projectPath
);
GitUtils
::
Branch
newBranch
;
newBranch
.
name
=
QStringLiteral
(
"Create New Branch"
);
GitUtils
::
Branch
newBranchFrom
;
newBranchFrom
.
name
=
QStringLiteral
(
"Create New Branch From..."
);
QVector
<
GitUtils
::
Branch
>
branches
{
newBranch
,
newBranchFrom
};
/*QVector<GitUtils::Branch> */
branches
<<
GitUtils
::
getAllBranches
(
m_projectPath
);
m_model
->
refresh
(
branches
);
reselectFirst
();
...
...
@@ -259,19 +264,29 @@ void BranchesDialog::onCheckoutDone()
Q_EMIT
branchChanged
(
res
.
branch
);
}
KTextEditor
::
Message
*
msg
=
new
KTextEditor
::
Message
(
msgStr
,
msgType
);
msg
->
setPosition
(
KTextEditor
::
Message
::
TopInView
);
msg
->
setAutoHide
(
3000
);
msg
->
setAutoHideMode
(
KTextEditor
::
Message
::
Immediate
);
msg
->
setView
(
m_mainWindow
->
activeView
());
m_mainWindow
->
activeView
()
->
document
()
->
postMessage
(
msg
);
sendMessage
(
msgStr
,
msgType
==
KTextEditor
::
Message
::
Warning
);
}
void
BranchesDialog
::
slotReturnPressed
()
{
if
(
m_model
->
rowCount
()
==
0
)
{
createNewBranch
(
m_lineEdit
->
text
());
;
return
;
}
const
auto
branch
=
m_proxyModel
->
data
(
m_treeView
->
currentIndex
(),
BranchesDialogModel
::
CheckoutName
).
toString
();
QFuture
<
GitUtils
::
CheckoutResult
>
future
=
QtConcurrent
::
run
(
&
GitUtils
::
checkoutBranch
,
m_projectPath
,
branch
);
m_checkoutWatcher
.
setFuture
(
future
);
const
auto
itemType
=
(
BranchesDialogModel
::
ItemType
)
m_proxyModel
->
data
(
m_treeView
->
currentIndex
(),
BranchesDialogModel
::
ItemTypeRole
).
toInt
();
if
(
itemType
==
BranchesDialogModel
::
BranchItem
)
{
QFuture
<
GitUtils
::
CheckoutResult
>
future
=
QtConcurrent
::
run
(
&
GitUtils
::
checkoutBranch
,
m_projectPath
,
branch
);
m_checkoutWatcher
.
setFuture
(
future
);
}
else
if
(
itemType
==
BranchesDialogModel
::
CreateBranch
)
{
m_model
->
clear
();
m_lineEdit
->
setPlaceholderText
(
i18n
(
"Enter new branch name. Press 'Esc' to cancel."
));
return
;
}
else
if
(
itemType
==
BranchesDialogModel
::
CreateBranchFrom
)
{
}
m_lineEdit
->
clear
();
hide
();
...
...
@@ -283,6 +298,36 @@ void BranchesDialog::reselectFirst()
m_treeView
->
setCurrentIndex
(
index
);
}
void
BranchesDialog
::
sendMessage
(
const
QString
&
message
,
bool
warn
)
{
KTextEditor
::
Message
*
msg
=
new
KTextEditor
::
Message
(
message
,
warn
?
KTextEditor
::
Message
::
Warning
:
KTextEditor
::
Message
::
Positive
);
msg
->
setPosition
(
KTextEditor
::
Message
::
TopInView
);
msg
->
setAutoHide
(
3000
);
msg
->
setAutoHideMode
(
KTextEditor
::
Message
::
Immediate
);
msg
->
setView
(
m_mainWindow
->
activeView
());
m_mainWindow
->
activeView
()
->
document
()
->
postMessage
(
msg
);
}
void
BranchesDialog
::
createNewBranch
(
const
QString
&
branch
)
{
if
(
branch
.
isEmpty
())
{
m_lineEdit
->
clear
();
hide
();
return
;
}
// the branch name might be invalid, let git handle it
const
GitUtils
::
CheckoutResult
r
=
GitUtils
::
checkoutNewBranch
(
m_projectPath
,
branch
);
const
bool
warn
=
true
;
if
(
r
.
returnCode
==
0
)
{
sendMessage
(
i18n
(
"Checked out to new branch: %1"
,
r
.
branch
),
!
warn
);
}
else
{
sendMessage
(
i18n
(
"Failed to create new branch. Error
\"
%1
\"
"
,
r
.
error
),
warn
);
}
m_lineEdit
->
clear
();
hide
();
}
void
BranchesDialog
::
updateViewGeometry
()
{
m_treeView
->
resizeColumnToContents
(
0
);
...
...
addons/project/branchesdialog.h
View file @
1164d2c6
...
...
@@ -45,8 +45,8 @@ private Q_SLOTS:
void
onCheckoutDone
();
private:
void
sendMessage
(
const
QString
&
message
,
bool
warn
);
void
createNewBranch
(
const
QString
&
branch
);
void
sendMessage
(
const
QString
&
message
,
bool
warn
);
void
createNewBranch
(
const
QString
&
branch
);
private:
QTreeView
*
m_treeView
;
...
...
addons/project/branchesdialogmodel.cpp
View file @
1164d2c6
...
...
@@ -43,12 +43,15 @@ QVariant BranchesDialogModel::data(const QModelIndex &idx, int role) const
return
branch
.
score
;
}
else
if
(
role
==
Role
::
OriginalSorting
)
{
return
branch
.
dateSort
;
}
else
if
(
role
==
Qt
::
DecorationRole
)
{
static
const
auto
branchIcon
=
QIcon
(
QStringLiteral
(
":/kxmlgui5/kateproject/sc-apps-git.svg"
));
return
branchIcon
;
}
else
if
(
role
==
Role
::
CheckoutName
)
{
return
branch
.
t
ype
==
GitUtils
::
RefType
::
Remote
?
branch
.
name
.
mid
(
branch
.
remote
.
size
()
+
1
)
:
branch
.
name
;
return
branch
.
refT
ype
==
GitUtils
::
RefType
::
Remote
?
branch
.
name
.
mid
(
branch
.
remote
.
size
()
+
1
)
:
branch
.
name
;
}
else
if
(
role
==
Role
::
RefType
)
{
return
branch
.
type
;
return
branch
.
refType
;
}
else
if
(
role
==
Role
::
ItemTypeRole
)
{
return
branch
.
itemType
;
}
return
{};
...
...
@@ -56,7 +59,17 @@ QVariant BranchesDialogModel::data(const QModelIndex &idx, int role) const
void
BranchesDialogModel
::
refresh
(
QVector
<
GitUtils
::
Branch
>
branches
)
{
Branch
create
{
branches
.
at
(
0
).
name
,
{},
{},
0
,
0
,
ItemType
::
CreateBranch
};
Branch
createFrom
{
branches
.
at
(
1
).
name
,
{},
{},
0
,
1
,
ItemType
::
CreateBranchFrom
};
QVector
<
Branch
>
temp
{
create
,
createFrom
};
for
(
int
i
=
2
;
i
<
branches
.
size
();
++
i
)
{
temp
.
append
({
branches
.
at
(
i
).
name
,
branches
.
at
(
i
).
remote
,
branches
.
at
(
i
).
type
,
-
1
,
i
,
ItemType
::
BranchItem
});
}
beginResetModel
();
m_modelEntries
=
std
::
move
(
branches
);
m_modelEntries
=
std
::
move
(
temp
);
// m_modelEntries = std::move(branches);
endResetModel
();
}
addons/project/branchesdialogmodel.h
View file @
1164d2c6
...
...
@@ -17,17 +17,20 @@ class BranchesDialogModel : public QAbstractTableModel
{
Q_OBJECT
public:
enum
Role
{
FuzzyScore
=
Qt
::
UserRole
+
1
,
OriginalSorting
,
CheckoutName
,
RefType
,
};
enum
Role
{
FuzzyScore
=
Qt
::
UserRole
+
1
,
OriginalSorting
,
CheckoutName
,
RefType
,
Creator
,
ItemTypeRole
};
enum
ItemType
{
BranchItem
,
CreateBranch
,
CreateBranchFrom
};
explicit
BranchesDialogModel
(
QObject
*
parent
=
nullptr
);
int
rowCount
(
const
QModelIndex
&
parent
=
QModelIndex
())
const
override
;
int
columnCount
(
const
QModelIndex
&
parent
)
const
override
;
QVariant
data
(
const
QModelIndex
&
idx
,
int
role
)
const
override
;
void
refresh
(
QVector
<
GitUtils
::
Branch
>
branches
);
void
clear
()
{
beginResetModel
();
QVector
<
Branch
>
().
swap
(
m_modelEntries
);
endResetModel
();
}
bool
setData
(
const
QModelIndex
&
index
,
const
QVariant
&
value
,
int
role
)
override
{
...
...
@@ -42,7 +45,16 @@ public:
}
private:
QVector
<
GitUtils
::
Branch
>
m_modelEntries
;
struct
Branch
{
QString
name
;
QString
remote
;
GitUtils
::
RefType
refType
;
int
score
;
int
dateSort
;
ItemType
itemType
;
};
QVector
<
BranchesDialogModel
::
Branch
>
m_modelEntries
;
// QVector<GitUtils::Branch> m_modelEntries;
};
#endif
addons/project/gitutils.cpp
View file @
1164d2c6
...
...
@@ -5,10 +5,9 @@
*/
#include "gitutils.h"
#include <QDateTime>
#include <QDebug>
#include <QDir>
#include <QProcess>
#include <QRegularExpression>
bool
GitUtils
::
isGitRepo
(
const
QString
&
repo
)
{
...
...
@@ -49,41 +48,77 @@ GitUtils::CheckoutResult GitUtils::checkoutBranch(const QString &repo, const QSt
return
res
;
}
GitUtils
::
CheckoutResult
GitUtils
::
checkoutNewBranch
(
const
QString
&
repo
,
const
QString
&
newBranch
,
const
QString
&
fromBranch
)
{
QProcess
git
;
git
.
setWorkingDirectory
(
repo
);
QStringList
args
{
QStringLiteral
(
"checkout"
),
QStringLiteral
(
"-q"
),
QStringLiteral
(
"-b"
),
newBranch
};
if
(
!
fromBranch
.
isEmpty
())
{
args
.
append
(
fromBranch
);
}
git
.
start
(
QStringLiteral
(
"git"
),
args
);
CheckoutResult
res
;
res
.
branch
=
newBranch
;
if
(
git
.
waitForStarted
()
&&
git
.
waitForFinished
(
-
1
))
{
res
.
returnCode
=
git
.
exitCode
();
res
.
error
=
QString
::
fromUtf8
(
git
.
readAllStandardError
());
}
return
res
;
}
#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
constexpr
auto
SkipEmptyParts
=
QString
::
SkipEmptyParts
;
#else
constexpr
auto
SkipEmptyParts
=
Qt
::
SkipEmptyParts
;
#endif
static
GitUtils
::
Branch
parseLocalBranch
(
const
QString
&
raw
)
{
auto
data
=
raw
.
split
(
QStringLiteral
(
"{sp}"
),
SkipEmptyParts
);
return
GitUtils
::
Branch
{
data
.
first
().
remove
(
QLatin1String
(
"refs/heads/"
)),
QString
(),
GitUtils
::
Head
};
}
static
GitUtils
::
Branch
parseRemoteBranch
(
const
QString
&
raw
)
{
auto
data
=
raw
.
split
(
QStringLiteral
(
"{sp}"
),
SkipEmptyParts
);
int
indexofRemote
=
data
.
at
(
0
).
indexOf
(
QLatin1Char
(
'/'
),
13
);
return
GitUtils
::
Branch
{
data
.
first
().
remove
(
QLatin1String
(
"refs/remotes/"
)),
data
.
at
(
0
).
mid
(
13
,
indexofRemote
-
13
),
GitUtils
::
Remote
};
}
QVector
<
GitUtils
::
Branch
>
GitUtils
::
getAllBranchesAndTags
(
const
QString
&
repo
,
RefType
ref
)
{
// git for-each-ref --format '%(refname) %(objectname) %(*objectname)'
QProcess
git
;
git
.
setWorkingDirectory
(
repo
);
QStringList
args
{
QStringLiteral
(
"for-each-ref"
),
QStringLiteral
(
"--format"
),
QStringLiteral
(
"%(refname)"
),
QStringLiteral
(
"--sort=-committerdate"
)};
QStringList
args
{
QStringLiteral
(
"for-each-ref"
),
QStringLiteral
(
"--format"
),
QStringLiteral
(
"%(refname){sp}"
),
QStringLiteral
(
"--sort=-committerdate"
)};
if
(
ref
&
RefType
::
Head
)
{
args
.
append
(
QStringLiteral
(
"refs/heads"
));
}
if
(
ref
&
RefType
::
Remote
)
{
args
.
append
(
QStringLiteral
(
"refs/remotes"
));
}
if
(
ref
&
RefType
::
Tag
)
{
args
.
append
(
QStringLiteral
(
"refs/tags"
));
args
.
append
(
QStringLiteral
(
"--sort=-taggerdate"
));
}
git
.
start
(
QStringLiteral
(
"git"
),
args
);
QVector
<
Branch
>
branches
;
if
(
git
.
waitForStarted
()
&&
git
.
waitForFinished
(
-
1
))
{
QString
gitout
=
QString
::
fromUtf8
(
git
.
readAllStandardOutput
());
QVector
<
QStringRef
>
out
=
gitout
.
splitRef
(
QLatin1Char
(
'\n'
));
static
const
QRegularExpression
headRe
(
QStringLiteral
(
"^refs/heads/([^ ]+)$"
));
static
const
QRegularExpression
remoteRe
(
QStringLiteral
(
"^refs/remotes/([^/]+)/([^ ]+)"
));
static
const
QRegularExpression
tagRe
(
QStringLiteral
(
"^refs/tags/([^ ]+)$"
));
QStringList
out
=
gitout
.
split
(
QLatin1Char
(
'\n'
));
branches
.
reserve
(
out
.
size
());
QRegularExpressionMatch
m
;
// clang-format off
for
(
const
auto
&
o
:
out
)
{
if
(
ref
&
Head
&&
(
m
=
headRe
.
match
(
o
)).
hasMatch
())
{
branches
.
append
({
m
.
captured
(
1
),
QString
(),
// no remote
RefType
::
Head
,
-
1
});
}
else
if
(
ref
&
Remote
&&
(
m
=
remoteRe
.
match
(
o
)).
hasMatch
())
{
branches
.
append
({
m
.
captured
(
1
).
append
(
QLatin1Char
(
'/'
)
+
m
.
captured
(
2
)),
m
.
captured
(
1
),
RefType
::
Remote
,
-
1
});
}
else
if
(
ref
&
Tag
&&
(
m
=
tagRe
.
match
(
o
)).
hasMatch
())
{
branches
.
append
({
m
.
captured
(
1
),
QString
(),
// no remote
RefType
::
Tag
,
-
1
});
if
(
ref
&
Head
&&
o
.
startsWith
(
QLatin1String
(
"refs/heads"
)))
{
branches
.
append
(
parseLocalBranch
(
o
));
}
else
if
(
ref
&
Remote
&&
o
.
startsWith
(
QLatin1String
(
"refs/remotes"
)))
{
branches
.
append
(
parseRemoteBranch
(
o
));
}
else
if
(
ref
&
Tag
&&
o
.
startsWith
(
QLatin1String
(
"refs/tags/"
)))
{
int
indexofSp
=
o
.
indexOf
(
QLatin1String
(
"{sp}"
));
branches
.
append
({
o
.
mid
(
10
,
indexofSp
),
{},
RefType
::
Tag
});
}
}
// clang-format on
...
...
addons/project/gitutils.h
View file @
1164d2c6
...
...
@@ -17,9 +17,15 @@ enum RefType {
All
=
0x7
,
};
/**
* @brief Represents a branch
*/
struct
Branch
{
/** Branch name */
QString
name
;
/** remote name, will be empty for local branches */
QString
remote
;
/** Ref type @see RefType */
RefType
type
;
};
...
...
@@ -35,6 +41,8 @@ QString getCurrentBranchName(const QString &repo);
CheckoutResult
checkoutBranch
(
const
QString
&
repo
,
const
QString
&
branch
);
CheckoutResult
checkoutNewBranch
(
const
QString
&
repo
,
const
QString
&
newBranch
,
const
QString
&
fromBranch
=
QString
());
/**
* @brief get all local and remote branches
*/
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment