diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index dbccb7ccb..9fd194bb6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -134,15 +134,16 @@ jobs: qt_arch: gcc_64 openssl_arch: linux-x86_64 ld_library_arch: linux-x86-64 - cmake_flags: "-DGENERATE_APPDATA=ON -DCMAKE_INSTALL_PREFIX=/usr -DUSE_SYSTEM_QT=ON -DENABLE_UPDATE_OVER_GUI=OFF" + cmake_flags: "-DGENERATE_APPDATA=ON -DCMAKE_INSTALL_PREFIX=/usr -DUSE_SYSTEM_QT=ON -DENABLE_UPDATE_OVER_GUI=OFF -DUSE_SSH=ON -DUSE_SYSTEM_LIBSSH2=ON -DUSE_SYSTEM_OPENSSL=ON" pack: 0 cmake_env: {} - name: macos - os: macos-12 + os: macos-13 ninja_platform: mac qt_platform: mac openssl_arch: darwin64-x86_64-cc + cmake_flags: "-DUSE_SYSTEM_OPENSSL=ON -DUSE_SSH:STRING=localbuild" cmake_env: {} pack: 1 @@ -154,30 +155,13 @@ jobs: qt_arch_check_only: win64_msvc2017_64 openssl_arch: VC-WIN64A msvc_arch: x64 - cmake_flags: "-DUSE_BUNDLED_ZLIB=1" + cmake_flags: "-DUSE_SSH:STRING=localbuild" cmake_env: CMAKE_RC_FLAGS: "/C 1252" CC: clang CXX: clang++ pack: 1 - - name: win32 - os: windows-latest - ninja_platform: win - qt_platform: windows - qt_arch: win32_msvc2019 - qt_arch_check_only: win32_msvc2017 - openssl_arch: VC-WIN32 - msvc_arch: x86 - cmake_flags: "-DUSE_BUNDLED_ZLIB=1" - cmake_env: - CMAKE_RC_FLAGS: "/C 1252" - CC: clang - CXX: clang++ - CMAKE_C_FLAGS: -m32 - CMAKE_CXX_FLAGS: -m32 - pack: 1 - steps: # otherwise the testcases will fail, because signature is invalid - name: Set git name and email @@ -203,6 +187,13 @@ jobs: with: perl-version: '5.30' + - name: Install Libssh2 + if: matrix.env.ninja_platform == 'linux' + run: | + sudo apt-get update + sudo apt-get -y install libssh2-1 + sudo apt-get -y install libssh2-1-dev + - name: Install Qt uses: jurplel/install-qt-action@v3.3.0 timeout-minutes: 10 @@ -244,25 +235,6 @@ jobs: if: matrix.env.ninja_platform == 'win' uses: ilammy/setup-nasm@v1.2.0 - - name: Build OpenSSL (Linux) - if: matrix.env.ninja_platform == 'linux' - run: | - cd dep/openssl/openssl - ./config -fPIC - make - - - name: Build OpenSSL (macOS) - if: matrix.env.ninja_platform == 'mac' - run: | - cd dep/openssl/openssl - - # this is necessary until https://github.com/openssl/openssl/issues/18720 - # is fixed in OpenSSL 1.1.1r - export CFLAGS=-Wno-error=implicit-function-declaration - - ./Configure ${{ matrix.env.openssl_arch }} no-shared - make - - name: Build OpenSSL (Windows) if: matrix.env.ninja_platform == 'win' run: | @@ -403,7 +375,6 @@ jobs: automatic_release_tag: 'development' files: | **/artifacts/Gittyup win64/Gittyup*.exe - **/artifacts/Gittyup win32/Gittyup*.exe **/artifacts/Gittyup macos/Gittyup*.dmg **/artifacts/GittyupFlatpak/*.flatpak **/artifacts/GittyupAppImage/Gittyup*.AppImage @@ -418,7 +389,6 @@ jobs: automatic_release_tag: ${{ github.ref_name }} files: | **/artifacts/Gittyup win64/Gittyup*.exe - **/artifacts/Gittyup win32/Gittyup*.exe **/artifacts/Gittyup macos/Gittyup*.dmg **/artifacts/GittyupFlatpak/*.flatpak **/artifacts/GittyupAppImage/Gittyup*.AppImage diff --git a/.gitignore b/.gitignore index f34e38739..ea9f67e55 100644 --- a/.gitignore +++ b/.gitignore @@ -5,9 +5,10 @@ build .vscode/ CMakeLists.txt.user cmake-build-debug/ +build* cmake-build-release/ build .idea/ .venv compile_commands.json -tags \ No newline at end of file +.flatpak-builder diff --git a/.gitmodules b/.gitmodules index 2ee39c1a4..c04026aee 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ [submodule "dep/libgit2/libgit2"] path = dep/libgit2/libgit2 - url = https://github.com/stinb/libgit2.git + url = https://github.com/Murmele/libgit2.git [submodule "dep/libssh2/libssh2"] path = dep/libssh2/libssh2 url = https://github.com/libssh2/libssh2.git diff --git a/com.github.Murmele.Gittyup.yml b/com.github.Murmele.Gittyup.yml index 32f8b0f11..4e0cdd73a 100644 --- a/com.github.Murmele.Gittyup.yml +++ b/com.github.Murmele.Gittyup.yml @@ -65,9 +65,24 @@ modules: - install -Dm755 $(which git-upload-archive) ${FLATPAK_DEST}/bin/ - install -Dm755 $(which git-upload-pack) ${FLATPAK_DEST}/bin/ + - name: libssh2 + rm-configure: true + sources: + - type: archive + url: https://www.libssh2.org/download/libssh2-1.11.0.tar.gz + sha256: 3736161e41e2693324deb38c26cfdc3efe6209d634ba4258db1cecff6a5ad461 + x-checker-data: + type: anitya + project-id: 1730 + url-template: https://www.libssh2.org/download/libssh2-$version.tar.gz + - type: script + commands: + - autoreconf -fiv + dest-filename: autogen.sh + - name: Gittyup buildsystem: cmake-ninja - config-opts: [-DCMAKE_BUILD_TYPE=Release, -DFLATPAK=ON, -DGENERATE_APPDATA=ON, -DENABLE_UPDATE_OVER_GUI=OFF, -DUSE_SYSTEM_OPENSSL:BOOL=ON] + config-opts: [-DCMAKE_BUILD_TYPE=Release, -DFLATPAK=ON, -DGENERATE_APPDATA=ON, -DENABLE_UPDATE_OVER_GUI=OFF, -DUSE_SYSTEM_OPENSSL:BOOL=ON, -DUSE_SSH=ON, -DUSE_SYSTEM_LIBSSH2=ON] builddir: true sources: - type: git diff --git a/dep/git/git b/dep/git/git index 4c53a8c20..61a22ddaf 160000 --- a/dep/git/git +++ b/dep/git/git @@ -1 +1 @@ -Subproject commit 4c53a8c20f8984adb226293a3ffd7b88c3f4ac1a +Subproject commit 61a22ddaf0626111193a17ac12f366bd6d167dff diff --git a/dep/libgit2/CMakeLists.txt b/dep/libgit2/CMakeLists.txt index dc3a232d6..cc68df799 100644 --- a/dep/libgit2/CMakeLists.txt +++ b/dep/libgit2/CMakeLists.txt @@ -2,18 +2,13 @@ set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE) -set(BUILD_CLAR +set(BUILD_TESTS OFF CACHE BOOL "" FORCE) set(STATIC_CRT OFF CACHE BOOL "" FORCE) -# Enabled manually. Don't search for it. -set(USE_SSH - OFF - CACHE BOOL "" FORCE) - if(WIN32) # Disable search for OpenSSL. set(USE_OPENSSL @@ -34,6 +29,8 @@ endif() if(NOT USE_SYSTEM_LIBGIT2) add_subdirectory(libgit2) + + # Include the generated experimental.h target_include_directories( - git2 INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/libgit2/include) + libgit2 INTERFACE ${PROJECT_BINARY_DIR}/dep/libgit2/libgit2/include/git2) endif() diff --git a/dep/libgit2/libgit2 b/dep/libgit2/libgit2 index 7861f401e..7d8fceccc 160000 --- a/dep/libgit2/libgit2 +++ b/dep/libgit2/libgit2 @@ -1 +1 @@ -Subproject commit 7861f401ea25e1ceaf7323c1585de4d633e0ec39 +Subproject commit 7d8fceccc61c5e74a1d2d4e1ad01f807828b6568 diff --git a/dep/libgit2/rebaseGittyupLibgit2.sh b/dep/libgit2/rebaseGittyupLibgit2.sh new file mode 100755 index 000000000..79a3cfbdd --- /dev/null +++ b/dep/libgit2/rebaseGittyupLibgit2.sh @@ -0,0 +1,42 @@ +declare -a branches=("fetch_annotated_tags" "blame_abort" "disableRenameDetection" "checkout_deletion_notification" "diff_checkout" "fix_push_callback_issues" "disable_mmap" "context_line_accessor´" "disableRenameDetection" "hash" "callback_connect_disconnect" "libgit2_includes_public", "local_libssh2") + +cd libgit2 + +git remote remove origin +git remote remove upstream +git remote add origin https://github.com/Murmele/libgit2.git +git remote add upstream https://github.com/libgit2/libgit2.git + +git fetch --all + +for branch in ${branches[@]}; do + echo $branch + git checkout -B $branch "origin/$branch" + RESULT=$? + if [ $RESULT -gt 0 ]; then + echo "Unable to checkout branch: $branch : Exitcode: $RESULT" + exit 1 + fi + git rebase upstream/main + RESULT=$? + if [ $RESULT -gt 0 ]; then + echo "Unable to rebase branch: $branch : Exitcode: $RESULT" + exit 1 + fi +done + +git checkout Gittyup +git reset --hard upstream/main + +for branch in ${branches[@]}; do + git merge --no-edit $branch + RESULT=$? + if [ $RESULT -gt 0 ]; then + echo "Unable to merge branch: $branch : Exitcode: $RESULT" + exit 1 + fi +done + +git push --force origin + +echo "Script finished. Check if all branches are rebased correctly and push them to origin!" diff --git a/dep/libssh2/CMakeLists.txt b/dep/libssh2/CMakeLists.txt index f43c150e6..28fc3a90b 100644 --- a/dep/libssh2/CMakeLists.txt +++ b/dep/libssh2/CMakeLists.txt @@ -1,6 +1,6 @@ if(USE_SYSTEM_LIBSSH2) if(PKG_CONFIG_FOUND) - pkg_check_modules(LIBSSH2 libssh2) + pkg_check_modules(LIBSSH2 REQUIRED libssh2) endif() else() diff --git a/dep/libssh2/libssh2 b/dep/libssh2/libssh2 index 6c59eea5a..c149a1272 160000 --- a/dep/libssh2/libssh2 +++ b/dep/libssh2/libssh2 @@ -1 +1 @@ -Subproject commit 6c59eea5a9ea77127ec0fa3d6815c8adc743dba3 +Subproject commit c149a12721b1caa9cf442efd770c61c590e8b568 diff --git a/dep/openssl/openssl b/dep/openssl/openssl index 3f499b24f..13baf8614 160000 --- a/dep/openssl/openssl +++ b/dep/openssl/openssl @@ -1 +1 @@ -Subproject commit 3f499b24f3bcd66db022074f7e8b4f6ee266a3ae +Subproject commit 13baf8614a63636af3a8d5c3a0d9dd41b656fe1d diff --git a/pack/CMakeLists.txt b/pack/CMakeLists.txt index c9b5f4de4..3729d2e0e 100644 --- a/pack/CMakeLists.txt +++ b/pack/CMakeLists.txt @@ -156,12 +156,12 @@ if(NOT APPLE) if(NOT USE_SYSTEM_OPENSSL) if(WIN32) if(CMAKE_SIZEOF_VOID_P EQUAL 8) - set(SSL_LIB_SUFFIX "-1_1-x64.dll") + set(SSL_LIB_SUFFIX "-3_4-x64.dll") else() - set(SSL_LIB_SUFFIX "-1_1.dll") + set(SSL_LIB_SUFFIX "-3_4.dll") endif() else() - set(SSL_LIB_SUFFIX ".so.1.1") + set(SSL_LIB_SUFFIX ".so.3.4") endif() foreach(SSL_LIB_NAME ssl crypto) @@ -183,7 +183,6 @@ if(NOT APPLE) WORLD_READ WORLD_EXECUTE COMPONENT ${GITTYUP_NAME} - OPTIONAL # if we use the system libssh, we have not built openssl ) endforeach() endif() diff --git a/src/conf/CMakeLists.txt b/src/conf/CMakeLists.txt index bbb0f2ce2..9a525e000 100644 --- a/src/conf/CMakeLists.txt +++ b/src/conf/CMakeLists.txt @@ -1,7 +1,7 @@ add_library(conf ConfFile.cpp Settings.cpp Setting.cpp RecentRepositories.cpp RecentRepository.cpp) -target_link_libraries(conf lua Qt5::Core util translation) +target_link_libraries(conf lua Qt5::Core translation gittyupUtil) # SRC_ definitions point to the source directly target_compile_definitions( diff --git a/src/dialogs/SubmoduleTableModel.cpp b/src/dialogs/SubmoduleTableModel.cpp index ea3df094a..3c9342f64 100644 --- a/src/dialogs/SubmoduleTableModel.cpp +++ b/src/dialogs/SubmoduleTableModel.cpp @@ -126,7 +126,8 @@ bool SubmoduleTableModel::setData(const QModelIndex &index, QMessageBox::Warning, tr("Deinitialize Submodule?"), text, QMessageBox::Cancel, qobject_cast(parent())); - if (GIT_SUBMODULE_STATUS_IS_WD_DIRTY(submodule.status())) + if (GIT_SUBMODULE_STATUS_IS_WD_DIRTY( + mRepo.submoduleStatus(submodule.name()))) mb->setInformativeText( tr("The submodule working directory contains uncommitted " "changes that will be lost if you continue.")); diff --git a/src/git/Branch.cpp b/src/git/Branch.cpp index 68e5cd0f6..360ea5336 100644 --- a/src/git/Branch.cpp +++ b/src/git/Branch.cpp @@ -83,7 +83,7 @@ Remote Branch::remote() const { return up.isValid() ? up.remote() : Remote(); } - git_buf buf = GIT_BUF_INIT_CONST(nullptr, 0); + git_buf buf = GIT_BUF_INIT; git_repository *repo = git_reference_owner(d.data()); if (git_branch_remote_name(&buf, repo, qualifiedName().toUtf8())) return Remote(); diff --git a/src/git/Buffer.cpp b/src/git/Buffer.cpp index 6b1f4fc02..4bd8cff8e 100644 --- a/src/git/Buffer.cpp +++ b/src/git/Buffer.cpp @@ -8,12 +8,12 @@ // #include "Buffer.h" +#include "git2/blob.h" namespace git { -Buffer::Buffer(const char *data, int size) - : d(GIT_BUF_INIT_CONST(data, size)) {} +Buffer::Buffer(const char *data, int size) : data(data), size(size) {} -bool Buffer::isBinary() const { return git_buf_is_binary(&d); } +bool Buffer::isBinary() const { return git_blob_data_is_binary(data, size); } } // namespace git diff --git a/src/git/Buffer.h b/src/git/Buffer.h index 45c00c124..77c69f174 100644 --- a/src/git/Buffer.h +++ b/src/git/Buffer.h @@ -10,8 +10,6 @@ #ifndef BUFFER_H #define BUFFER_H -#include "git2/buffer.h" - namespace git { class Buffer { @@ -21,7 +19,8 @@ class Buffer { bool isBinary() const; private: - git_buf d; + const char *data; + const int size; }; } // namespace git diff --git a/src/git/CMakeLists.txt b/src/git/CMakeLists.txt index c9553149b..1416df857 100644 --- a/src/git/CMakeLists.txt +++ b/src/git/CMakeLists.txt @@ -27,6 +27,9 @@ add_library( TagRef.cpp Tree.cpp) -target_link_libraries(git git2 Qt5::Core Qt5::Network util) +# we need both libgit2package and libgit2 otherwise we can't find the header +# files +target_link_libraries(git libgit2package libgit2 gittyupUtil Qt5::Core + Qt5::Network) set_target_properties(git PROPERTIES AUTOMOC ON) diff --git a/src/git/Config.cpp b/src/git/Config.cpp index 8f4e7cd98..eaf9eb711 100644 --- a/src/git/Config.cpp +++ b/src/git/Config.cpp @@ -102,7 +102,7 @@ QString Config::value(const QString &key, return defaultValue; } - git_buf buf = GIT_BUF_INIT_CONST(nullptr, 0); + git_buf buf = GIT_BUF_INIT; git_config_get_string_buf(&buf, d.data(), key.toUtf8()); QString value = QString::fromUtf8(buf.ptr, buf.size); git_buf_dispose(&buf); @@ -182,7 +182,7 @@ QString Config::globalPath() { config.remove("global.force"); } - git_buf buf = GIT_BUF_INIT_CONST(nullptr, 0); + git_buf buf = GIT_BUF_INIT; git_config_find_global(&buf); QString path = QString::fromUtf8(buf.ptr, buf.size); git_buf_dispose(&buf); diff --git a/src/git/Filter.cpp b/src/git/Filter.cpp index cfa03d8d5..c29f0094d 100644 --- a/src/git/Filter.cpp +++ b/src/git/Filter.cpp @@ -14,6 +14,7 @@ #include "git2/filter.h" #include "git2/repository.h" #include "git2/sys/filter.h" +#include "git2/sys/errors.h" #include #include @@ -38,9 +39,9 @@ struct FilterInfo { QString quote(const QString &path) { return QString("\"%1\"").arg(path); } -int apply(git_filter *self, void **payload, git_buf *to, const git_buf *from, - const git_filter_source *src) { - FilterInfo *info = reinterpret_cast(self); +int apply(const git_filter *self, QByteArray &to, const char *from, + const size_t from_length, const git_filter_source *src) { + const FilterInfo *info = reinterpret_cast(self); git_filter_mode_t mode = git_filter_source_mode(src); QString command = (mode == GIT_FILTER_SMUDGE) ? info->smudge : info->clean; @@ -59,7 +60,7 @@ int apply(git_filter *self, void **payload, git_buf *to, const git_buf *from, if (!process.waitForStarted()) return info->required ? GIT_EUSER : GIT_PASSTHROUGH; - process.write(from->ptr, from->size); + process.write(from); process.closeWriteChannel(); if (!process.waitForFinished() || process.exitCode()) { @@ -67,8 +68,52 @@ int apply(git_filter *self, void **payload, git_buf *to, const git_buf *from, return info->required ? GIT_EUSER : GIT_PASSTHROUGH; } - QByteArray data = process.readAll(); - git_buf_set(to, data.constData(), data.length()); + to = process.readAll(); + return 0; +} + +struct Stream { + git_writestream parent; // must be the first. No pointer! + git_writestream *next; + git_filter_mode_t mode; + const git_filter *filter; + const git_filter_source *filter_source; +}; + +static void stream_free(git_writestream *stream) { free(stream); } + +static int stream_close(git_writestream *s) { + struct Stream *stream = (struct Stream *)s; + stream->next->close(stream->next); + return 0; +} + +static int stream_write(git_writestream *s, const char *buffer, size_t len) { + + struct Stream *stream = (struct Stream *)s; + QByteArray to; + apply(stream->filter, to, buffer, len, stream->filter_source); + stream->next->write(stream->next, to.data(), to.length()); + return 0; +} + +// Called for every new stream +static int stream_init(git_writestream **out, git_filter *self, void **payload, + const git_filter_source *src, git_writestream *next) { + + struct Stream *stream = + static_cast(calloc(1, sizeof(struct Stream))); + if (!stream) + return -1; + + stream->parent.write = stream_write; + stream->parent.close = stream_close; + stream->parent.free = stream_free; + stream->next = next; + stream->filter_source = src; + stream->filter = self; + + *out = (git_writestream *)stream; return 0; } @@ -101,7 +146,7 @@ void Filter::init() { info.name = key.toUtf8(); info.attributes = kFilterFmt.arg(key).toUtf8(); - info.filter.apply = &apply; + info.filter.stream = stream_init; info.filter.attributes = info.attributes.constData(); git_filter_register(info.name.constData(), &info.filter, GIT_FILTER_DRIVER_PRIORITY); diff --git a/src/git/Id.cpp b/src/git/Id.cpp index 97de9472a..cfb071fe0 100644 --- a/src/git/Id.cpp +++ b/src/git/Id.cpp @@ -15,11 +15,11 @@ namespace git { namespace { -const Id kInvalidId = QByteArray(GIT_OID_RAWSZ, -1); +const Id kInvalidId = QByteArray(GIT_OID_SHA1_SIZE, -1); } // namespace -Id::Id() { memset(d.id, 0, GIT_OID_RAWSZ); } +Id::Id() { memset(d.id, 0, GIT_OID_SHA1_SIZE); } Id::Id(const QByteArray &id) { git_oid_fromraw(&d, reinterpret_cast(id.constData())); @@ -31,7 +31,7 @@ Id::Id(const git_oid *id) { if (id) { git_oid_cpy(&d, id); } else { - memset(d.id, 0, GIT_OID_RAWSZ); + memset(d.id, 0, GIT_OID_SHA1_SIZE); } } @@ -45,7 +45,7 @@ QString Id::toString() const { return toByteArray().toHex(); } QByteArray Id::toByteArray() const { const char *data = reinterpret_cast(d.id); - return QByteArray::fromRawData(data, GIT_OID_RAWSZ); + return QByteArray::fromRawData(data, GIT_OID_SHA1_SIZE); } bool Id::operator<(const Id &rhs) const { return (git_oid_cmp(&d, rhs) < 0); } diff --git a/src/git/Object.cpp b/src/git/Object.cpp index d7344ae3f..5b9b861fa 100644 --- a/src/git/Object.cpp +++ b/src/git/Object.cpp @@ -26,7 +26,7 @@ git_object_t Object::type() const { return git_object_type(d.data()); } Id Object::id() const { return git_object_id(d.data()); } QString Object::shortId() const { - git_buf buf = GIT_BUF_INIT_CONST(0, 0); + git_buf buf = GIT_BUF_INIT; git_object_short_id(&buf, d.data()); QByteArray result(buf.ptr, buf.size); git_buf_dispose(&buf); diff --git a/src/git/Patch.cpp b/src/git/Patch.cpp index 913104e4c..53818abc5 100644 --- a/src/git/Patch.cpp +++ b/src/git/Patch.cpp @@ -326,10 +326,9 @@ QByteArray Patch::generateResult(QList> &image, return result; // Apply filters. - git_buf out = GIT_BUF_INIT_CONST(nullptr, 0); - git_buf raw = GIT_BUF_INIT_CONST(result.constData(), result.length()); - (&out, filters, &raw); - git_buf_dispose(&raw); + git_buf out = GIT_BUF_INIT; + git_filter_list_apply_to_buffer(&out, filters, result.data(), + result.length()); QByteArray filtered(out.ptr, out.size); git_buf_dispose(&out); diff --git a/src/git/Remote.cpp b/src/git/Remote.cpp index dfd1013ba..24f3c8319 100644 --- a/src/git/Remote.cpp +++ b/src/git/Remote.cpp @@ -17,7 +17,8 @@ #include "git2/clone.h" #include "git2/remote.h" #include "git2/signature.h" -#include "libssh2.h" +#include "git2/sys/errors.h" +#include #include #include #include @@ -243,18 +244,16 @@ class ConfigFile { } // namespace -int Remote::Callbacks::connect(git_remote *remote, void *payload) { +void Remote::Callbacks::connected(git_remote *remote, void *payload) { Remote::Callbacks *cbs = reinterpret_cast(payload); cbs->mRemote = remote; - return 0; } -int Remote::Callbacks::disconnect(git_remote *remote, void *payload) { +void Remote::Callbacks::about_to_disconnect(git_remote *remote, void *payload) { Q_UNUSED(remote) Remote::Callbacks *cbs = reinterpret_cast(payload); cbs->mRemote = nullptr; - return 0; } int Remote::Callbacks::sideband(const char *str, int len, void *payload) { @@ -457,12 +456,12 @@ int Remote::Callbacks::update(const char *name, const git_oid *a, return 0; } -int Remote::Callbacks::url(git_buf *out, const char *url, int direction, - void *payload) { +int Remote::Callbacks::remoteReady(git_remote *remote, int direction, + void *payload) { Q_UNUSED(direction) Remote::Callbacks *cbs = reinterpret_cast(payload); - QString resolved(url); + QString resolved(git_remote_url(remote)); if (!cbs->url(resolved)) return -1; @@ -494,7 +493,7 @@ int Remote::Callbacks::url(git_buf *out, const char *url, int direction, } resolved = resolvedUrl.toString(); - git_buf_set(out, resolved.toUtf8(), resolved.length()); + git_remote_set_instance_url(remote, resolved.toUtf8()); return 0; } @@ -532,14 +531,14 @@ void Remote::setUrl(const QString &url) { Result Remote::fetch(Callbacks *callbacks, bool tags, bool prune) { git_fetch_options opts = GIT_FETCH_OPTIONS_INIT; - opts.callbacks.connect = &Remote::Callbacks::connect; - opts.callbacks.disconnect = &Remote::Callbacks::disconnect; + opts.callbacks.connected = &Remote::Callbacks::connected; + opts.callbacks.about_to_disconnect = &Remote::Callbacks::about_to_disconnect; opts.callbacks.sideband_progress = &Remote::Callbacks::sideband; opts.callbacks.credentials = &Remote::Callbacks::credentials; opts.callbacks.certificate_check = &Remote::Callbacks::certificate; opts.callbacks.transfer_progress = &Remote::Callbacks::transfer; opts.callbacks.update_tips = &Remote::Callbacks::update; - opts.callbacks.resolve_url = &Remote::Callbacks::url; + opts.callbacks.remote_ready = &Remote::Callbacks::remoteReady; opts.callbacks.payload = callbacks; QByteArray proxy = proxyUrl(url(), opts.proxy_opts.type); @@ -559,14 +558,14 @@ Result Remote::fetch(Callbacks *callbacks, bool tags, bool prune) { Result Remote::push(Callbacks *callbacks, const QStringList &refspecs) { git_push_options opts = GIT_PUSH_OPTIONS_INIT; - opts.callbacks.connect = &Remote::Callbacks::connect; - opts.callbacks.disconnect = &Remote::Callbacks::disconnect; + opts.callbacks.connected = &Remote::Callbacks::connected; + opts.callbacks.about_to_disconnect = &Remote::Callbacks::about_to_disconnect; opts.callbacks.sideband_progress = &Remote::Callbacks::sideband; opts.callbacks.credentials = &Remote::Callbacks::credentials; opts.callbacks.certificate_check = &Remote::Callbacks::certificate; opts.callbacks.transfer_progress = &Remote::Callbacks::transfer; opts.callbacks.update_tips = &Remote::Callbacks::update; - opts.callbacks.resolve_url = &Remote::Callbacks::url; + opts.callbacks.remote_ready = &Remote::Callbacks::remoteReady; opts.callbacks.pack_progress = &pack_progress; opts.callbacks.push_transfer_progress = &push_transfer_progress; opts.callbacks.push_update_reference = &push_update_reference; @@ -617,14 +616,15 @@ Result Remote::clone(Callbacks *callbacks, const QString &url, const QString &path, bool bare) { git_repository *repo = nullptr; git_clone_options opts = GIT_CLONE_OPTIONS_INIT; - opts.fetch_opts.callbacks.connect = &Remote::Callbacks::connect; - opts.fetch_opts.callbacks.disconnect = &Remote::Callbacks::disconnect; + opts.fetch_opts.callbacks.connected = &Remote::Callbacks::connected; + opts.fetch_opts.callbacks.about_to_disconnect = + &Remote::Callbacks::about_to_disconnect; opts.fetch_opts.callbacks.sideband_progress = &Remote::Callbacks::sideband; opts.fetch_opts.callbacks.credentials = &Remote::Callbacks::credentials; opts.fetch_opts.callbacks.certificate_check = &Remote::Callbacks::certificate; opts.fetch_opts.callbacks.transfer_progress = &Remote::Callbacks::transfer; opts.fetch_opts.callbacks.update_tips = &Remote::Callbacks::update; - opts.fetch_opts.callbacks.resolve_url = &Remote::Callbacks::url; + opts.fetch_opts.callbacks.remote_ready = &Remote::Callbacks::remoteReady; opts.fetch_opts.callbacks.payload = callbacks; opts.bare = bare; diff --git a/src/git/Remote.h b/src/git/Remote.h index 953c31a2d..8530eecdf 100644 --- a/src/git/Remote.h +++ b/src/git/Remote.h @@ -93,9 +93,9 @@ class Remote { virtual bool connectToAgent() const { return false; } // static callback wrappers - static int connect(git_remote *remote, void *payload); + static void connected(git_remote *remote, void *payload); - static int disconnect(git_remote *remote, void *payload); + static void about_to_disconnect(git_remote *remote, void *payload); static int sideband(const char *str, int len, void *payload); @@ -110,7 +110,7 @@ class Remote { static int update(const char *name, const git_oid *a, const git_oid *b, void *payload); - static int url(git_buf *out, const char *url, int direction, void *payload); + static int remoteReady(git_remote *remote, int direction, void *payload); protected: // Try to stop the current remote. diff --git a/src/git/Repository.cpp b/src/git/Repository.cpp index d7f91016f..0610be5a4 100644 --- a/src/git/Repository.cpp +++ b/src/git/Repository.cpp @@ -44,6 +44,7 @@ #include "git2/stash.h" #include "git2/tag.h" #include "git2/sys/repository.h" +#include "git2/sys/errors.h" #include #include #include @@ -179,7 +180,7 @@ Id Repository::workdirId(const QString &path) const { } QString Repository::message() const { - git_buf buf = GIT_BUF_INIT_CONST(nullptr, 0); + git_buf buf = GIT_BUF_INIT; git_repository_message(&buf, d->repo); return QString::fromUtf8(buf.ptr, buf.size); } @@ -337,7 +338,8 @@ Diff Repository::diffIndexToWorkdir(const Index &index, Diff::Callbacks *callbacks, bool ignoreWhitespace) const { git_diff_options opts = GIT_DIFF_OPTIONS_INIT; - opts.flags |= (GIT_DIFF_DISABLE_MMAP | GIT_DIFF_INCLUDE_TYPECHANGE); + opts.flags |= + GIT_DIFF_INCLUDE_TYPECHANGE; // GIT_DIFF_DISABLE_MMAP flag really needed? if (!appConfig().value("untracked.hide", false)) opts.flags |= GIT_DIFF_INCLUDE_UNTRACKED | GIT_DIFF_RECURSE_UNTRACKED_DIRS; @@ -613,7 +615,7 @@ Commit Repository::commit(const Signature &author, const Signature &committer, return Commit(); // Lookup the parent commit. - QVector parents; + QVector parents; if (Reference ref = head()) { if (Commit commit = ref.target()) parents.append(commit); @@ -709,6 +711,18 @@ Submodule Repository::lookupSubmodule(const QString &name) const { return Submodule(submodule); } +int Repository::submoduleStatus(const QString &name) const { + + unsigned int status; + // TODO: testing!!!! + int returnValue = + git_submodule_status(&status, d->repo, name.toLocal8Bit().data(), + GIT_SUBMODULE_IGNORE_UNSPECIFIED); + if (returnValue < 0) + return returnValue; + return status; +} + Remote Repository::addRemote(const QString &name, const QString &url) { // FIXME: Validate name? diff --git a/src/git/Repository.h b/src/git/Repository.h index 0abb27794..bec16b1ab 100644 --- a/src/git/Repository.h +++ b/src/git/Repository.h @@ -166,6 +166,7 @@ class Repository { void invalidateSubmoduleCache(); QList submodules() const; Submodule lookupSubmodule(const QString &path) const; + int submoduleStatus(const QString &name) const; // remote Remote addRemote(const QString &name, const QString &url); diff --git a/src/git/Submodule.cpp b/src/git/Submodule.cpp index f31e642c4..67e5a0e50 100644 --- a/src/git/Submodule.cpp +++ b/src/git/Submodule.cpp @@ -80,25 +80,18 @@ Id Submodule::indexId() const { return git_submodule_index_id(d.data()); } Id Submodule::workdirId() const { return git_submodule_wd_id(d.data()); } -int Submodule::status() const { - unsigned int status = 0; - if (git_submodule_status(&status, d.data(), GIT_SUBMODULE_IGNORE_UNSPECIFIED)) - return -1; - - return status; -} - Result Submodule::update(Remote::Callbacks *callbacks, bool init, bool checkout_force) { git_submodule_update_options opts = GIT_SUBMODULE_UPDATE_OPTIONS_INIT; - opts.fetch_opts.callbacks.connect = &Remote::Callbacks::connect; - opts.fetch_opts.callbacks.disconnect = &Remote::Callbacks::disconnect; + opts.fetch_opts.callbacks.connected = &Remote::Callbacks::connected; + opts.fetch_opts.callbacks.about_to_disconnect = + &Remote::Callbacks::about_to_disconnect; opts.fetch_opts.callbacks.sideband_progress = &Remote::Callbacks::sideband; opts.fetch_opts.callbacks.credentials = &Remote::Callbacks::credentials; opts.fetch_opts.callbacks.certificate_check = &Remote::Callbacks::certificate; opts.fetch_opts.callbacks.transfer_progress = &Remote::Callbacks::transfer; opts.fetch_opts.callbacks.update_tips = &Remote::Callbacks::update; - opts.fetch_opts.callbacks.resolve_url = &Remote::Callbacks::url; + opts.fetch_opts.callbacks.remote_ready = &Remote::Callbacks::remoteReady; opts.fetch_opts.callbacks.payload = callbacks; if (checkout_force) diff --git a/src/git/Submodule.h b/src/git/Submodule.h index 71eda035b..82531c4e6 100644 --- a/src/git/Submodule.h +++ b/src/git/Submodule.h @@ -44,14 +44,6 @@ class Submodule { Id indexId() const; Id workdirId() const; - /*! - * \brief status - * Return the status of the submodule as a combination of flags described in - * https://libgit2.org/libgit2/index.html#HEAD/type/git_submodule_status_t - * \return current status - */ - int status() const; - Result update(Remote::Callbacks *callbacks, bool init = false, bool checkout_force = false); diff --git a/src/index/CMakeLists.txt b/src/index/CMakeLists.txt index 26b911754..33500502c 100644 --- a/src/index/CMakeLists.txt +++ b/src/index/CMakeLists.txt @@ -11,12 +11,11 @@ target_link_libraries( Qt5::Concurrent) set_target_properties(index PROPERTIES AUTOMOC ON) +# if(ENABLE_TESTS) add_executable(lexer_test lexer_test.cpp) +# target_link_libraries(lexer_test index) -add_executable(lexer_test lexer_test.cpp) -target_link_libraries(lexer_test index) - -add_executable(index_test index_test.cpp) -target_link_libraries(index_test index Qt5::Widgets) +# add_executable(index_test index_test.cpp) target_link_libraries(index_test +# index Qt5::Widgets) endif() add_executable(indexer indexer.cpp) target_link_libraries(indexer index) diff --git a/src/index/Index.cpp b/src/index/Index.cpp index d48ad5d8d..efcf2543a 100644 --- a/src/index/Index.cpp +++ b/src/index/Index.cpp @@ -67,7 +67,7 @@ void Index::reset() { QFile idFile(dir.filePath(kIdFile)); if (idFile.open(QIODevice::ReadOnly)) { while (idFile.bytesAvailable() > 0) - mIds.append(idFile.read(GIT_OID_RAWSZ)); + mIds.append(idFile.read(GIT_OID_SHA1)); } // Read dictionary. @@ -140,7 +140,7 @@ bool Index::write(PostingMap map) { // Write id file. foreach (const git::Id &id, mIds) - idFile.write(id.toByteArray(), GIT_OID_RAWSZ); + idFile.write(id.toByteArray(), GIT_OID_SHA1); // Merge new entries into existing postings file. // Write dictionary and postings files in lockstep. diff --git a/src/ui/ReferenceModel.cpp b/src/ui/ReferenceModel.cpp index 5dbd29b3d..306edb35c 100644 --- a/src/ui/ReferenceModel.cpp +++ b/src/ui/ReferenceModel.cpp @@ -106,7 +106,8 @@ void ReferenceModel::update() { // Add bottom references. const bool stashOnCommit = !mCommit.isValid() || - mRepo.stashRef().annotatedCommit().commit() == mCommit; + (mRepo.stashRef().isValid() && + mRepo.stashRef().annotatedCommit().commit() == mCommit); if ((mKinds & ReferenceView::Stash) && stashOnCommit) { if (git::Reference stash = mRepo.stashRef()) branches.append(stash); @@ -180,8 +181,9 @@ QModelIndex ReferenceModel::firstBranch() { // use the first valid ref after the invalid ref but only // it is not the stash if (ref.refs.count() > 1 && - ref.refs.at(1).annotatedCommit().commit() != - mRepo.stashRef().annotatedCommit().commit()) + (!mRepo.stashRef().isValid() || + ref.refs.at(1).annotatedCommit().commit() != + mRepo.stashRef().annotatedCommit().commit())) return createIndex(1, 0, ReferenceType::Branches); } else if (ref.refs.count() > 0) return createIndex(0, 0, ReferenceType::Branches); diff --git a/src/ui/RemoteCallbacks.cpp b/src/ui/RemoteCallbacks.cpp index b5ba06069..af5c59504 100644 --- a/src/ui/RemoteCallbacks.cpp +++ b/src/ui/RemoteCallbacks.cpp @@ -14,6 +14,7 @@ #include "git/Command.h" #include "git/Id.h" #include "git/RevWalk.h" +#include "git2/sys/errors.h" #include "log/LogEntry.h" #include #include diff --git a/src/ui/RepoView.cpp b/src/ui/RepoView.cpp index ff398a5cf..204e84285 100644 --- a/src/ui/RepoView.cpp +++ b/src/ui/RepoView.cpp @@ -1051,7 +1051,8 @@ QFuture RepoView::fetch(const git::Remote &rmt, bool tags, if (result && submodules) { // Scan for unmodified submodules on the fetch thread. foreach (const git::Submodule &submodule, mRepo.submodules()) { - if (GIT_SUBMODULE_STATUS_IS_UNMODIFIED(submodule.status())) + if (GIT_SUBMODULE_STATUS_IS_UNMODIFIED( + mRepo.submoduleStatus(submodule.name()))) submodules->append(submodule.name()); } } @@ -2397,7 +2398,7 @@ RepoView::submoduleResetInfoList(const git::Repository &repo, // Only reset modified submodules QList modules; foreach (const git::Submodule &submodule, submodules) { - int status = submodule.status(); + int status = repo.submoduleStatus(submodule.name()); if (status & (GIT_SUBMODULE_STATUS_WD_MODIFIED | GIT_SUBMODULE_STATUS_WD_WD_MODIFIED | diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt index 4d039839f..55dc85568 100644 --- a/src/util/CMakeLists.txt +++ b/src/util/CMakeLists.txt @@ -1,6 +1,6 @@ -add_library(util Path.cpp Debug.h Debug.cpp) +add_library(gittyupUtil Path.cpp Debug.h Debug.cpp) -target_link_libraries(util Qt5::Core) -target_include_directories(util INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) +target_link_libraries(gittyupUtil Qt5::Core) +target_include_directories(gittyupUtil INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) -set_target_properties(util PROPERTIES AUTOMOC ON) +set_target_properties(gittyupUtil PROPERTIES AUTOMOC ON) diff --git a/test/SshConfig.cpp b/test/SshConfig.cpp index d01cfea5f..9d2528a30 100644 --- a/test/SshConfig.cpp +++ b/test/SshConfig.cpp @@ -10,6 +10,7 @@ #include "Test.h" #include "git/Remote.h" #include "git2/buffer.h" +#include "git2/remote.h" #include "qtestcase.h" class Callbacks : public git::Remote::Callbacks { @@ -39,16 +40,16 @@ private slots: private: static QString transformUrl(const QString &url, const QString config) { auto callbacks = Callbacks(url, config); - git_buf buf; - buf.asize = 0; - buf.size = 0; - buf.ptr = nullptr; - - Callbacks::url(&buf, url.toUtf8().data(), 0, &callbacks); - - QString res = QString::fromUtf8(buf.ptr, (int)buf.size); - git_buf_dispose(&buf); - return res; + git_remote *remote{nullptr}; + git_remote_create(&remote, nullptr, "test", url.toUtf8()); + + if (!remote) + return QStringLiteral("Remote nullptr"); + Callbacks::remoteReady(remote, 0, &callbacks); + const char *urlNew = git_remote_url(remote); + QString u = QString::fromUtf8(urlNew); + git_remote_free(remote); + return u; } };