1#include "GitBranches.h"
2
3#include <GitBase.h>
4#include <GitConfig.h>
5
6#include <QLogger.h>
7
8using namespace QLogger;
9
10GitBranches::GitBranches(const QSharedPointer<GitBase> &gitBase)
11 : mGitBase(gitBase)
12{
13}
14
15GitExecResult GitBranches::createBranchFromAnotherBranch(const QString &oldName, const QString &newName)
16{
17 QLog_Debug("Git", QString("Creating branch from another branch: {%1} and {%2}").arg(oldName, newName));
18
19 const auto cmd = QString("git branch %1 %2").arg(newName, oldName);
20
21 QLog_Trace("Git", QString("Creating branch from another branch: {%1}").arg(cmd));
22
23 const auto ret = mGitBase->run(cmd);
24
25 return ret;
26}
27
28GitExecResult GitBranches::createBranchAtCommit(const QString &commitSha, const QString &branchName)
29{
30 QLog_Debug("Git", QString("Creating a branch from a commit: {%1} at {%2}").arg(branchName, commitSha));
31
32 const auto cmd = QString("git branch %1 %2").arg(branchName, commitSha);
33
34 QLog_Trace("Git", QString("Creating a branch from a commit: {%1}").arg(cmd));
35
36 const auto ret = mGitBase->run(cmd);
37
38 return ret;
39}
40
41GitExecResult GitBranches::checkoutBranchFromCommit(const QString &commitSha, const QString &branchName)
42{
43 QLog_Debug("Git",
44 QString("Creating and checking out a branch from a commit: {%1} at {%2}").arg(branchName, commitSha));
45
46 const auto cmd = QString("git checkout -b %1 %2").arg(branchName, commitSha);
47
48 QLog_Trace("Git", QString("Creating and checking out a branch from a commit: {%1}").arg(cmd));
49
50 const auto ret = mGitBase->run(cmd);
51
52 if (ret.success)
53 mGitBase->updateCurrentBranch();
54
55 return ret;
56}
57
58GitExecResult GitBranches::checkoutLocalBranch(const QString &branchName)
59{
60 QLog_Debug("Git", QString("Checking out local branch: {%1}").arg(branchName));
61
62 const auto cmd = QString("git checkout %1").arg(branchName);
63
64 QLog_Trace("Git", QString("Checking out local branch: {%1}").arg(cmd));
65
66 const auto ret = mGitBase->run(cmd);
67
68 if (ret.success)
69 mGitBase->updateCurrentBranch();
70
71 return ret;
72}
73
74GitExecResult GitBranches::checkoutRemoteBranch(const QString &branchName)
75{
76 QLog_Debug("Git", QString("Checking out remote branch: {%1}").arg(branchName));
77
78 auto localBranch = branchName;
79 if (localBranch.startsWith("origin/"))
80 localBranch.remove("origin/");
81
82 const auto cmd = QString("git checkout -b %1 %2").arg(localBranch, branchName);
83
84 QLog_Trace("Git", QString("Checking out remote branch: {%1}").arg(cmd));
85
86 auto ret = mGitBase->run(cmd);
87 const auto output = ret.output;
88
89 if (ret.success && !output.contains("fatal:"))
90 mGitBase->updateCurrentBranch();
91 else if (output.contains("already exists"))
92 {
93 QRegExp rx("\'\\w+\'");
94 rx.indexIn(ret.output);
95 auto value = rx.capturedTexts().constFirst();
96 value.remove("'");
97
98 if (!value.isEmpty())
99 ret = checkoutLocalBranch(value);
100 else
101 ret.success = false;
102 }
103
104 return ret;
105}
106
107GitExecResult GitBranches::checkoutNewLocalBranch(const QString &branchName)
108{
109 QLog_Debug("Git", QString("Checking out new local branch: {%1}").arg(branchName));
110
111 const auto cmd = QString("git checkout -b %1").arg(branchName);
112
113 QLog_Trace("Git", QString("Checking out new local branch: {%1}").arg(cmd));
114
115 const auto ret = mGitBase->run(cmd);
116
117 if (ret.success)
118 mGitBase->updateCurrentBranch();
119
120 return ret;
121}
122
123GitExecResult GitBranches::renameBranch(const QString &oldName, const QString &newName)
124{
125 QLog_Debug("Git", QString("Renaming branch: {%1} at {%2}").arg(oldName, newName));
126
127 const auto cmd = QString("git branch -m %1 %2").arg(oldName, newName);
128
129 QLog_Trace("Git", QString("Renaming branch: {%1}").arg(cmd));
130
131 const auto ret = mGitBase->run(cmd);
132
133 if (ret.success)
134 mGitBase->updateCurrentBranch();
135
136 return ret;
137}
138
139GitExecResult GitBranches::removeLocalBranch(const QString &branchName)
140{
141 QLog_Debug("Git", QString("Removing local branch: {%1}").arg(branchName));
142
143 const auto cmd = QString("git branch -D %1").arg(branchName);
144
145 QLog_Trace("Git", QString("Removing local branch: {%1}").arg(cmd));
146
147 const auto ret = mGitBase->run(cmd);
148
149 return ret;
150}
151
152GitExecResult GitBranches::removeRemoteBranch(const QString &branchName)
153{
154 auto branch = branchName;
155 branch = branch.mid(branch.indexOf('/') + 1);
156
157 QLog_Debug("Git", QString("Removing a remote branch: {%1}").arg(branch));
158
159 QScopedPointer<GitConfig> gitConfig(new GitConfig(mGitBase));
160
161 auto ret = gitConfig->getRemoteForBranch(branch);
162
163 const auto cmd = QString("git push --delete %2 %1").arg(branch, ret.success ? ret.output : QString("origin"));
164
165 QLog_Trace("Git", QString("Removing a remote branch: {%1}").arg(cmd));
166
167 ret = mGitBase->run(cmd);
168
169 return ret;
170}
171
172GitExecResult GitBranches::getLastCommitOfBranch(const QString &branch)
173{
174 QLog_Debug("Git", QString("Getting last commit of a branch: {%1}").arg(branch));
175
176 const auto cmd = QString("git rev-parse %1").arg(branch);
177
178 QLog_Trace("Git", QString("Getting last commit of a branch: {%1}").arg(cmd));
179
180 auto ret = mGitBase->run(cmd);
181
182 if (ret.success)
183 ret.output = ret.output.trimmed();
184
185 return ret;
186}
187
188GitExecResult GitBranches::pushUpstream(const QString &branchName)
189{
190 QLog_Debug("Git", QString("Pushing upstream: {%1}").arg(branchName));
191
192 const auto cmd = QString("git push --set-upstream origin %1").arg(branchName);
193
194 QLog_Trace("Git", QString("Pushing upstream: {%1}").arg(cmd));
195
196 const auto ret = mGitBase->run(cmd);
197
198 return ret;
199}
200
201GitExecResult GitBranches::rebaseOnto(const QString &currentBranch, const QString &startBranch,
202 const QString &fromBranch) const
203{
204 QLog_Debug("Git", QString("Git rebase {%1} into {%2}").arg(currentBranch, fromBranch));
205
206 const auto cmd = QString("git rebase --onto %1 %2 %3").arg(currentBranch, startBranch, fromBranch);
207 return mGitBase->run(cmd);
208}
209