#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; }