diff --git a/git/git_client.cpp b/git/git_client.cpp new file mode 100644 index 0000000..17eacd9 --- /dev/null +++ b/git/git_client.cpp @@ -0,0 +1,144 @@ +#include "git_client.h" +#include "update.h" + +#include +#include +#include + +GitClient::GitClient(QString const &workingDirectory, QString const &branchName) + : m_workingDirectory(workingDirectory) + , m_branchName(branchName) { +} + +void GitClient::setWorkingDirectory(QString const &workingDirectory) { + m_workingDirectory = workingDirectory; +} + +QString GitClient::workingDirectory() const { + return m_workingDirectory; +} + +void GitClient::setBranchName(QString const &branchName) { + m_branchName = branchName; +} + +QString GitClient::branchName() const { + return m_branchName; +} + +std::optional GitClient::gitCloneRepository(QString const &repPath) { + QString gitCommand("git clone "); + gitCommand += repPath; + Command c(gitCommand); + if (c.execute(m_workingDirectory)) { + QString result = c.getCommandResult(); + if (!result.isEmpty()) { + // Cloning into 'customer_281'...\n + static QRegularExpression re("(^\\s*Cloning\\s+into\\s+[']\\s*)(.*)(\\s*['].*$)"); + QRegularExpressionMatch match = re.match(result); + if (match.hasMatch()) { + if (re.captureCount() == 3) { // start with full match (0), then the other 3 matches + return match.captured(2); + } + } + } + } + return std::nullopt; +} + +bool GitClient::gitCheckout(QString const &branchName) { + QString gitCommand("git checkout "); + gitCommand += branchName; + Command c(gitCommand); + return c.execute(m_workingDirectory); +} + +std::optional GitClient::gitCloneBranch(QString const &repPath, + QString const &branchName) { + if (std::optional rep = gitCloneRepository(repPath)) { + QDir wd(m_workingDirectory); + if (wd.cd(rep.value())) { + m_workingDirectory = wd.absolutePath(); + if (gitCheckout(branchName)) { + return branchName; + } + } + } + return std::nullopt; +} + +std::optional GitClient::gitDiff(QString const &commits) { + // 409f198..6c22726 + QString gitCommand("git diff --compact-summary "); + gitCommand += commits; + + Command c(gitCommand); + if (c.execute(m_workingDirectory)) { + QString s = c.getCommandResult().trimmed(); + QStringList lines = Update::split(s, '\n'); + QStringList fileNames; + // each line has the format "etc/psa_config/DC2C_print01.json | 1 + + // or the format "etc/psa_config/DC2C_print01.json (new) | 1 + + // the filenames are relativ to the repository + for (int i = 0; i < lines.size(); ++i) { + int newIndex = lines.at(i).indexOf("(new)"); + if (newIndex != -1) { + QString fileName = lines.at(i).mid(0, newIndex).trimmed(); + fileNames << fileName; + } else { + int pipeIndex = lines.at(i).indexOf('|'); + if (pipeIndex != -1) { + QString fileName = lines.at(i).mid(0, pipeIndex).trimmed(); + fileNames << fileName; + } + } + } + if (!fileNames.isEmpty()) { + return fileNames; + } + } + return std::nullopt; +} + +std::optional GitClient::gitFetch() { + Command c("git fetch"); + if (c.execute(m_workingDirectory)) { + QString s = c.getCommandResult().trimmed(); + QStringList lines = Update::split(s, '\n'); + if (!lines.empty()) { + // 409f198..6c22726 zg1/zone1 -> origin/zg1/zone1 + static QRegularExpression re("(^\\s*)([0-9A-Fa-f]+..[0-9A-Fa-f]+)(.*$)"); + QRegularExpressionMatch match = re.match(lines.last()); + if (match.hasMatch()) { + if (re.captureCount() == 3) { // start with full match (0), then the other 3 matches + return match.captured(2); + } + } + } + } + return std::nullopt; +} + +bool GitClient::gitFetchAndDiff() { + if (gitFetch()) { + QString gitCommand("git diff --compact-summary HEAD..FETCH_HEAD"); + Command c(gitCommand); + return c.execute(m_workingDirectory); + } + return false; +} + +bool GitClient::gitPull() { + Command c("git pull"); + return c.execute(m_workingDirectory); +} + +std::optional GitClient::gitMerge() { + Command c("git merge"); + if (c.execute(m_workingDirectory)) { + QString s = c.getCommandResult(); + QStringList lst = Update::split(s, '\n'); + return lst; + } + return std::nullopt; +} diff --git a/git/git_client.h b/git/git_client.h new file mode 100644 index 0000000..63f446e --- /dev/null +++ b/git/git_client.h @@ -0,0 +1,35 @@ +#ifndef GIT_CLIENT_H_INCLUDED +#define GIT_CLIENT_H_INCLUDED + + +#include + +#include "process/command.h" + + +class GitClient { + QString m_workingDirectory; + QString m_branchName; + + std::optional gitCloneRepository(QString const &repPath); + bool gitCheckout(QString const &branchName); + + public: + explicit GitClient(QString const &workingDirectory = QCoreApplication::applicationDirPath(), + QString const &branchName = "master"); + + void setWorkingDirectory(QString const &workingDirectory); + QString workingDirectory() const; + void setBranchName(QString const &branchName); + QString branchName() const; + + std::optional gitCloneBranch(QString const &repPath, QString const &branchName); + + std::optional gitFetch(); + bool gitFetchAndDiff(); + bool gitPull(); + std::optional gitDiff(QString const &commit); + std::optional gitMerge(); +}; + +#endif // GIT_CLIENT_H_INCLUDED