2025-01-10 13:48:38 +01:00
|
|
|
#include <QUrl>
|
|
|
|
#include <QtCore/QDir>
|
|
|
|
#include <QDebug>
|
2025-01-10 14:41:04 +01:00
|
|
|
#include <QStandardPaths>
|
2025-01-17 10:40:54 +01:00
|
|
|
extern "C" {
|
|
|
|
#include <git2.h>
|
|
|
|
}
|
2025-01-13 17:59:08 +01:00
|
|
|
|
2025-01-10 13:48:38 +01:00
|
|
|
#include "git.h"
|
2025-01-13 18:11:16 +01:00
|
|
|
#include "utils.h"
|
2025-01-17 10:40:54 +01:00
|
|
|
#include "jobs/clonejob.h"
|
|
|
|
#include "jobs/gitjob.h"
|
2025-01-13 17:59:08 +01:00
|
|
|
|
2025-01-17 10:40:54 +01:00
|
|
|
Git::Git():
|
2025-02-21 15:50:27 +01:00
|
|
|
m_sem(std::unique_ptr<QSemaphore>(new QSemaphore(1))),
|
|
|
|
m_ssh_homedir (QStandardPaths::writableLocation(
|
|
|
|
QStandardPaths::AppDataLocation).append("/.ssh"))
|
2025-01-10 13:48:38 +01:00
|
|
|
{
|
2025-02-21 15:50:27 +01:00
|
|
|
qDebug() << "[Git] SSH Home is " << m_ssh_homedir.absolutePath();
|
|
|
|
QDir m_ssh_homedir(this->m_ssh_homedir);
|
|
|
|
if (!m_ssh_homedir.exists()) {
|
|
|
|
m_ssh_homedir.mkpath(".");
|
|
|
|
}
|
2025-01-17 10:40:54 +01:00
|
|
|
git_libgit2_init();
|
2025-01-13 17:59:08 +01:00
|
|
|
}
|
|
|
|
|
2025-01-17 10:40:54 +01:00
|
|
|
Git::~Git()
|
2025-01-13 17:59:08 +01:00
|
|
|
{
|
2025-01-17 10:40:54 +01:00
|
|
|
git_libgit2_shutdown();
|
2025-01-13 17:59:08 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2025-01-17 10:40:54 +01:00
|
|
|
bool Git::clone(QString url, QString path, cred_type mode)
|
2025-01-13 17:59:08 +01:00
|
|
|
{
|
2025-01-17 10:40:54 +01:00
|
|
|
if (!this->m_sem->tryAcquire(1, 500)) {
|
2025-02-21 15:50:27 +01:00
|
|
|
qWarning() << "[Git] Can acquire git semaphore a command is already running ";
|
2025-01-17 10:40:54 +01:00
|
|
|
return false;
|
|
|
|
}
|
2025-01-13 17:59:08 +01:00
|
|
|
auto v = overload {
|
2025-02-18 14:18:34 +01:00
|
|
|
[](const HTTP & x) { UNUSED(x); return "HTTP"; },
|
|
|
|
[](const HTTPUserPass & x) { UNUSED(x); return "HTTPAuth"; },
|
|
|
|
[](const SSHKey & x) { UNUSED(x); return "SSHKey"; },
|
2025-01-13 17:59:08 +01:00
|
|
|
};
|
2025-01-17 10:40:54 +01:00
|
|
|
qDebug() << "Creating clone Job " << url << " " << path << " " << std::visit(v, mode);
|
|
|
|
CloneJob *clone_job = new CloneJob(url, path, mode);
|
|
|
|
connect(clone_job, &CloneJob::resultReady, this, &Git::cloneResult);
|
|
|
|
connect(clone_job, &CloneJob::finished, clone_job, &QObject::deleteLater);
|
|
|
|
clone_job->start();
|
|
|
|
return true;
|
2025-01-10 13:48:38 +01:00
|
|
|
}
|
2025-01-13 17:59:08 +01:00
|
|
|
|
2025-01-14 08:15:03 +01:00
|
|
|
bool Git::cloneHttp(QString url, QString path)
|
2025-01-13 17:59:08 +01:00
|
|
|
{
|
2025-02-21 15:50:27 +01:00
|
|
|
qInfo() << "[Git] Call clone command Http " << url << " " << path;
|
2025-01-13 17:59:08 +01:00
|
|
|
HTTP mode = {};
|
|
|
|
return this->clone(url, path, mode);
|
|
|
|
}
|
|
|
|
|
2025-01-14 08:15:03 +01:00
|
|
|
bool Git::cloneHttpPass(QString url, QString path, QString pass)
|
2025-01-13 18:11:16 +01:00
|
|
|
{
|
2025-02-21 15:50:27 +01:00
|
|
|
qInfo() << "[Git] Call clone command HttpPass " << url << " " << path;
|
2025-01-17 10:40:54 +01:00
|
|
|
HTTPUserPass mode = { pass };
|
2025-01-13 17:59:08 +01:00
|
|
|
return this->clone(url, path, mode);
|
|
|
|
}
|
2025-01-17 10:40:54 +01:00
|
|
|
|
2025-02-21 15:50:27 +01:00
|
|
|
bool Git::cloneSshKey(QString url, QString path, QString passphrase)
|
|
|
|
{
|
|
|
|
qInfo() << "[Git] Call clone command HttpPass " << url << " " << path;
|
|
|
|
|
|
|
|
SSHKey mode = { this->pubKeyPath(), this->privKeyPath(), passphrase };
|
|
|
|
return this->clone(url, path, mode);
|
|
|
|
}
|
|
|
|
|
2025-01-17 10:40:54 +01:00
|
|
|
void Git::cloneResult(const bool err)
|
|
|
|
{
|
|
|
|
|
|
|
|
if (err) {
|
|
|
|
emit cloneFailed(); // TODO error message
|
|
|
|
} else {
|
|
|
|
emit cloneSucceed();
|
|
|
|
}
|
|
|
|
this->m_sem->release();
|
|
|
|
}
|
2025-02-21 15:50:27 +01:00
|
|
|
|
|
|
|
bool Git::importSshKey(QUrl source_path, bool is_private){
|
|
|
|
auto destination_path = is_private ? this->privKeyPath() : this->pubKeyPath();
|
|
|
|
|
|
|
|
QFile source_file(source_path.toLocalFile());
|
|
|
|
|
|
|
|
if (!source_file.exists()) {
|
|
|
|
qWarning() << "[Git] Source file does not exist.";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
QDir target_dir = QFileInfo(destination_path).absoluteDir();
|
|
|
|
if (!target_dir.exists()) {
|
|
|
|
if (!target_dir.mkpath(".")) {
|
|
|
|
qWarning() << "[Git] Failed to create target directory.";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return source_file.copy(destination_path);
|
|
|
|
}
|