[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: [libqgit2] /: Support cloning a repository
From: Peter_Kümmel <syntheticpp () gmx ! net>
Date: 2014-02-28 19:59:49
Message-ID: E1WJTb3-0006j7-V2 () scm ! kde ! org
[Download RAW message or body]
Git commit 7ea0526b4ff748463eed158cf96647e6a0d270eb by Peter Kümmel.
Committed on 28/02/2014 at 19:50.
Pushed by kuemmel into branch 'master'.
Support cloning a repository
M +1 -1 CMakeLists.txt
M +35 -0 src/qgitrepository.cpp
M +21 -1 src/qgitrepository.h
M +2 -0 tests/CMakeLists.txt
A +107 -0 tests/Clone.cpp [License: UNKNOWN] *
M +22 -1 tests/TestHelpers.h
The files marked with a * at the end have a non valid license. Please read: \
http://techbase.kde.org/Policies/Licensing_Policy and use the headers which are \
listed at that page.
http://commits.kde.org/libqgit2/7ea0526b4ff748463eed158cf96647e6a0d270eb
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f65fee9..b662eb2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -145,7 +145,7 @@ FILE(GLOB QGIT2_HEADERS src/*.h)
# MOC
if(Qt5Core_FOUND)
else()
- QT4_WRAP_CPP(MOC_SRC src/qgitindexmodel.h)
+ QT4_WRAP_CPP(MOC_SRC src/qgitindexmodel.h src/qgitrepository.h)
endif()
message(STATUS)
diff --git a/src/qgitrepository.cpp b/src/qgitrepository.cpp
index 77a508c..7d7c0d5 100644
--- a/src/qgitrepository.cpp
+++ b/src/qgitrepository.cpp
@@ -333,4 +333,39 @@ const git_repository* Repository::constData() const
return d.data();
}
+
+int Repository::fetchProgressCallback(const git_transfer_progress* stats, void* \
data) +{
+ if (!data) {
+ return 1;
+ }
+ Repository* repo = static_cast<Repository*>(data);
+ int percent = (int)(0.5 + 100.0 * ((double)stats->received_objects) / \
((double)stats->total_objects)); + if (percent != repo->m_clone_progress) {
+ emit repo->cloneProgress(percent);
+ repo->m_clone_progress = percent;
+ }
+ return 0;
+}
+
+
+void Repository::clone(const QString& url, const QString& path)
+{
+ git_clone_options opts;
+ memset(&opts, 0, sizeof(git_clone_options));
+ opts = GIT_CLONE_OPTIONS_INIT;
+
+ opts.remote_callbacks.transfer_progress = &fetchProgressCallback;
+ opts.remote_callbacks.payload = (void*)this;;
+
+ opts.checkout_opts = GIT_CHECKOUT_OPTS_INIT;
+ opts.checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
+
+ m_clone_progress = 0;
+ git_repository* repo = NULL;
+ qGitThrow(git_clone(&repo, qPrintable(url), qPrintable(path), &opts));
+ d = ptr_type(repo, git_repository_free);
+}
+
+
} // namespace LibQGit2
diff --git a/src/qgitrepository.h b/src/qgitrepository.h
index f09c359..1e07675 100644
--- a/src/qgitrepository.h
+++ b/src/qgitrepository.h
@@ -23,6 +23,7 @@
#include <QtCore/QSharedPointer>
#include <QtCore/QStringList>
+#include <QtCore/QObject>
#include "libqgit2_export.h"
@@ -49,8 +50,10 @@ namespace LibQGit2
* @ingroup LibQGit2
* @{
*/
- class LIBQGIT2_EXPORT Repository
+ class LIBQGIT2_EXPORT Repository : public QObject
{
+ Q_OBJECT
+
public:
/**
@@ -413,12 +416,29 @@ namespace LibQGit2
*/
StatusList status(const StatusOptions *options) const;
+ /**
+ * Clone a git repository.
+ *
+ * Signal cloneProgress(int) is emitted with progress in percent.
+ *
+ * @param url URL of the git repository
+ * @param path non-existing directory for the new clone
+ * @throws LibQGit2::Exception
+ */
+ void clone(const QString& url, const QString& path);
+
git_repository* data() const;
const git_repository* constData() const;
+ signals:
+ void cloneProgress(int);
+
private:
typedef QSharedPointer<git_repository> ptr_type;
ptr_type d;
+
+ int m_clone_progress;
+ static int fetchProgressCallback(const git_transfer_progress* stats, \
void* data); };
/**@}*/
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index b82f42a..a099b01 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -6,6 +6,7 @@ endif()
set(testdir ${CMAKE_BINARY_DIR}/TestDir)
file(MAKE_DIRECTORY ${testdir})
add_definitions(-DTEST_DIR=${testdir})
+remove_definitions(-DMAKE_LIBQGIT2_LIB)
set(existing_repository ${testdir}/existing_repository)
add_definitions(-DTEST_EXISTING_REPOSITORY=${existing_repository})
@@ -44,3 +45,4 @@ endmacro()
addTest(Init)
addTest(Revision)
addTest(StatusOptions)
+addTest(Clone)
diff --git a/tests/Clone.cpp b/tests/Clone.cpp
new file mode 100644
index 0000000..2aa4eff
--- /dev/null
+++ b/tests/Clone.cpp
@@ -0,0 +1,107 @@
+#include "TestHelpers.h"
+
+#include <QCoreApplication>
+#include <QTimer>
+
+
+#include <iostream>
+#include <bitset>
+
+#include "qgitcommit.h"
+#include "qgitrepository.h"
+
+using namespace LibQGit2;
+
+
+class TestClone : public QObject
+{
+ Q_OBJECT
+
+public:
+ TestClone();
+
+public slots:
+ void cloneProgress(int p)
+ {
+ m_clone_progress = p;
+ if (p % 20 == 0) {
+ qDebug() << qPrintable(QString("Progress : %1%").arg(p));
+ }
+ }
+
+private slots:
+ void fileProtocol();
+ void gitProtocol();
+ void httpProtocol();
+ void httpsProtocol();
+
+private:
+ int m_clone_progress;
+ const QString testdir;
+
+ void clone(const QString& url);
+};
+
+
+
+TestClone::TestClone() : testdir(VALUE_TO_STR(TEST_DIR))
+{
+}
+
+
+void TestClone::clone(const QString& url)
+{
+ LibQGit2::Repository repo;
+ connect(&repo, SIGNAL(cloneProgress(int)), this, SLOT(cloneProgress(int)));
+
+ QString dirname = url;
+ dirname.replace(":", "");
+ dirname.replace("//", "/");
+ dirname.replace("//", "/");
+ dirname.replace("/", "_");
+ dirname.replace(".", "_");
+ const QString repoPath = testdir + "/clone_test/" + dirname;
+
+ removeDir(repoPath);
+ sleep::ms(500);
+ m_clone_progress = 0;
+
+ qDebug() << "Cloning " << url;
+ try {
+ repo.clone(url, repoPath);
+ }
+ catch (const LibQGit2::Exception& ex) {
+ QFAIL(ex.what());
+ }
+
+ QCOMPARE(m_clone_progress, 100);
+}
+
+
+void TestClone::fileProtocol()
+{
+ clone("file:///" + VALUE_TO_QSTR(TEST_EXISTING_REPOSITORY) + "/.git");
+}
+
+
+void TestClone::gitProtocol()
+{
+ clone("git://anongit.kde.org/libqgit2");
+}
+
+
+void TestClone::httpProtocol()
+{
+ clone("http://anongit.kde.org/libqgit2");
+}
+
+
+void TestClone::httpsProtocol()
+{
+ clone("https://github.com/lgiordani/libqgit2.git");
+}
+
+
+QTEST_MAIN(TestClone);
+
+#include "Clone.moc"
diff --git a/tests/TestHelpers.h b/tests/TestHelpers.h
index f3e3a9c..fb28672 100644
--- a/tests/TestHelpers.h
+++ b/tests/TestHelpers.h
@@ -3,11 +3,22 @@
#include <QTest>
#include <QDir>
+#include <QDebug>
+#include <QTimer>
+#include <QThread>
#include "qgitexception.h"
#define TO_STR(s) #s
#define VALUE_TO_STR(s) TO_STR(s)
+#define VALUE_TO_QSTR(s) QLatin1String(TO_STR(s))
+
+
+struct sleep : QThread
+{
+ static void ms(int msec) { QThread::msleep(msec); }
+};
+
bool removeDir(const QString & dirName)
{
@@ -21,6 +32,13 @@ bool removeDir(const QString & dirName)
}
else {
result = QFile::remove(info.absoluteFilePath());
+ if (!result) {
+ \
QFile(info.absoluteFilePath()).setPermissions(QFile::WriteOwner); + \
result = QFile::remove(info.absoluteFilePath()); + }
+ if (!result) {
+ qDebug() << "Could not remove " << info.absoluteFilePath();
+ }
}
if (!result) {
@@ -28,6 +46,9 @@ bool removeDir(const QString & dirName)
}
}
result = dir.rmdir(dirName);
+ if (!result) {
+ qDebug() << "Could not remove " << dirName;
+ }
}
return result;
-}
+}
\ No newline at end of file
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic