Unverified Commit 8d36dc62 by Patrick Steinhardt Committed by GitHub

Merge pull request #4632 from pks-t/pks/v0.27.1

Bugfix release v0.27.2
parents b0d9952c 853ef86a
v0.27.2
---------
### Changes or improvements
* Fix builds with LibreSSL 2.7.
* Fix for `git_diff_status_char()` not returning the correct mapping for
`GIT_DELTA_TYPECHANGE`.
* Fix for the submodules API not reporting errors when parsing the ".gitmodules"
file.
* Fix for accepting a ".gitmodules" file where two submodules have the same
path.
* Fix for hiding references in a graph walk not always limiting the graph
correctly.
* Fix for directory patterns with trailing spaces in attribute files not being
handled correctly.
* Fix SSH transports not properly disconnecting from the server.
* Fix reading HEAD reflog in worktrees.
* Update our copy of SHA1DC to fix errors with endianess on some platforms.
v0.27.1 v0.27.1
--------- ---------
......
...@@ -29,7 +29,7 @@ INCLUDE(CheckFunctionExists) ...@@ -29,7 +29,7 @@ INCLUDE(CheckFunctionExists)
INCLUDE(CheckSymbolExists) INCLUDE(CheckSymbolExists)
INCLUDE(CheckStructHasMember) INCLUDE(CheckStructHasMember)
INCLUDE(AddCFlagIfSupported) INCLUDE(AddCFlagIfSupported)
INCLUDE(FindPkgConfig) INCLUDE(FindPkgLibraries)
INCLUDE(FindThreads) INCLUDE(FindThreads)
INCLUDE(FindStatNsec) INCLUDE(FindStatNsec)
INCLUDE(IdeSplitSources) INCLUDE(IdeSplitSources)
......
...@@ -43,6 +43,11 @@ build_script: ...@@ -43,6 +43,11 @@ build_script:
if "%GENERATOR%"=="MSYS Makefiles" (C:\MinGW\msys\1.0\bin\sh --login /c/projects/libgit2/script/appveyor-mingw.sh) if "%GENERATOR%"=="MSYS Makefiles" (C:\MinGW\msys\1.0\bin\sh --login /c/projects/libgit2/script/appveyor-mingw.sh)
test_script: test_script:
- ps: | - ps: |
# Disable DHE key exchange to fix intermittent build failures ("A buffer
# provided was too small") due to SChannel bug. See e.g.
# - https://github.com/aws/aws-sdk-cpp/issues/671
# - https://github.com/dotnet/corefx/issues/7812
New-Item HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\KeyExchangeAlgorithms\Diffie-Hellman -Force | New-ItemProperty -Name Enabled -Value 0 -Force
$ErrorActionPreference="Stop" $ErrorActionPreference="Stop"
Start-FileDownload https://github.com/ethomson/poxyproxy/releases/download/v0.1.0/poxyproxy-0.1.0.jar -FileName poxyproxy.jar Start-FileDownload https://github.com/ethomson/poxyproxy/releases/download/v0.1.0/poxyproxy-0.1.0.jar -FileName poxyproxy.jar
# Run this early so we know it's ready by the time we need it # Run this early so we know it's ready by the time we need it
......
INCLUDE(FindPkgConfig)
# This function will find and set up a pkg-config based module.
# If a pc-file was found, it will resolve library paths to
# absolute paths. Furthermore, the function will automatically
# fall back to use static libraries in case no dynamic libraries
# were found.
FUNCTION(FIND_PKGLIBRARIES prefix package)
PKG_CHECK_MODULES(${prefix} ${package})
IF(NOT ${prefix}_FOUND)
RETURN()
ENDIF()
FOREACH(LIBRARY ${${prefix}_LIBRARIES})
FIND_LIBRARY(${LIBRARY}_RESOLVED ${LIBRARY} PATHS ${${prefix}_LIBRARY_DIRS})
IF(${${LIBRARY}_RESOLVED} STREQUAL "${LIBRARY}_RESOLVED-NOTFOUND")
MESSAGE(FATAL_ERROR "could not resolve ${LIBRARY}")
ENDIF()
LIST(APPEND RESOLVED_LIBRARIES ${${LIBRARY}_RESOLVED})
ENDFOREACH(LIBRARY)
SET(${prefix}_FOUND 1 PARENT_SCOPE)
SET(${prefix}_LIBRARIES ${RESOLVED_LIBRARIES} PARENT_SCOPE)
SET(${prefix}_INCLUDE_DIRS ${${prefix}_INCLUDE_DIRS} PARENT_SCOPE)
SET(${prefix}_LDFLAGS ${${prefix}_LDFLAGS} PARENT_SCOPE)
MESSAGE(STATUS " Resolved libraries: ${RESOLVED_LIBRARIES}")
ENDFUNCTION()
LINK_DIRECTORIES(${LIBGIT2_LIBDIRS})
INCLUDE_DIRECTORIES(${LIBGIT2_INCLUDES}) INCLUDE_DIRECTORIES(${LIBGIT2_INCLUDES})
FILE(GLOB_RECURSE SRC_EXAMPLE_GIT2 network/*.c network/*.h common.?) FILE(GLOB_RECURSE SRC_EXAMPLE_GIT2 network/*.c network/*.h common.?)
......
...@@ -7,10 +7,10 @@ ...@@ -7,10 +7,10 @@
#ifndef INCLUDE_git_version_h__ #ifndef INCLUDE_git_version_h__
#define INCLUDE_git_version_h__ #define INCLUDE_git_version_h__
#define LIBGIT2_VERSION "0.27.1" #define LIBGIT2_VERSION "0.27.2"
#define LIBGIT2_VER_MAJOR 0 #define LIBGIT2_VER_MAJOR 0
#define LIBGIT2_VER_MINOR 27 #define LIBGIT2_VER_MINOR 27
#define LIBGIT2_VER_REVISION 1 #define LIBGIT2_VER_REVISION 2
#define LIBGIT2_VER_PATCH 0 #define LIBGIT2_VER_PATCH 0
#define LIBGIT2_SOVERSION 27 #define LIBGIT2_SOVERSION 27
......
...@@ -17,7 +17,6 @@ SET(LIBGIT2_INCLUDES ...@@ -17,7 +17,6 @@ SET(LIBGIT2_INCLUDES
"${libgit2_SOURCE_DIR}/src" "${libgit2_SOURCE_DIR}/src"
"${libgit2_SOURCE_DIR}/include") "${libgit2_SOURCE_DIR}/include")
SET(LIBGIT2_LIBS "") SET(LIBGIT2_LIBS "")
SET(LIBGIT2_LIBDIRS "")
# Installation paths # Installation paths
# #
...@@ -109,7 +108,6 @@ IF (WIN32 AND WINHTTP) ...@@ -109,7 +108,6 @@ IF (WIN32 AND WINHTTP)
ADD_SUBDIRECTORY("${libgit2_SOURCE_DIR}/deps/winhttp" "${libgit2_BINARY_DIR}/deps/winhttp") ADD_SUBDIRECTORY("${libgit2_SOURCE_DIR}/deps/winhttp" "${libgit2_BINARY_DIR}/deps/winhttp")
LIST(APPEND LIBGIT2_LIBS winhttp) LIST(APPEND LIBGIT2_LIBS winhttp)
LIST(APPEND LIBGIT2_INCLUDES "${libgit2_SOURCE_DIR}/deps/winhttp") LIST(APPEND LIBGIT2_INCLUDES "${libgit2_SOURCE_DIR}/deps/winhttp")
LIST(APPEND LIBGIT2_LIBDIRS ${LIBWINHTTP_PATH})
ELSE() ELSE()
LIST(APPEND LIBGIT2_LIBS "winhttp") LIST(APPEND LIBGIT2_LIBS "winhttp")
LIST(APPEND LIBGIT2_PC_LIBS "-lwinhttp") LIST(APPEND LIBGIT2_PC_LIBS "-lwinhttp")
...@@ -119,13 +117,11 @@ IF (WIN32 AND WINHTTP) ...@@ -119,13 +117,11 @@ IF (WIN32 AND WINHTTP)
LIST(APPEND LIBGIT2_PC_LIBS "-lrpcrt4" "-lcrypt32" "-lole32") LIST(APPEND LIBGIT2_PC_LIBS "-lrpcrt4" "-lcrypt32" "-lole32")
ELSE () ELSE ()
IF (CURL) IF (CURL)
PKG_CHECK_MODULES(CURL libcurl) FIND_PKGLIBRARIES(CURL libcurl)
ENDIF () ENDIF ()
IF (CURL_FOUND) IF (CURL_FOUND)
SET(GIT_CURL 1) SET(GIT_CURL 1)
LIST(APPEND LIBGIT2_INCLUDES ${CURL_INCLUDE_DIRS}) LIST(APPEND LIBGIT2_INCLUDES ${CURL_INCLUDE_DIRS})
LIST(APPEND LIBGIT2_LIBDIRS ${CURL_LIBRARY_DIRS})
LIST(APPEND LIBGIT2_LIBS ${CURL_LIBRARIES}) LIST(APPEND LIBGIT2_LIBS ${CURL_LIBRARIES})
LIST(APPEND LIBGIT2_PC_LIBS ${CURL_LDFLAGS}) LIST(APPEND LIBGIT2_PC_LIBS ${CURL_LDFLAGS})
ENDIF() ENDIF()
...@@ -282,15 +278,13 @@ ENDIF() ...@@ -282,15 +278,13 @@ ENDIF()
# Optional external dependency: libssh2 # Optional external dependency: libssh2
IF (USE_SSH) IF (USE_SSH)
PKG_CHECK_MODULES(LIBSSH2 libssh2) FIND_PKGLIBRARIES(LIBSSH2 libssh2)
ENDIF() ENDIF()
IF (LIBSSH2_FOUND) IF (LIBSSH2_FOUND)
SET(GIT_SSH 1) SET(GIT_SSH 1)
LIST(APPEND LIBGIT2_INCLUDES ${LIBSSH2_INCLUDE_DIRS}) LIST(APPEND LIBGIT2_INCLUDES ${LIBSSH2_INCLUDE_DIRS})
LIST(APPEND LIBGIT2_LIBS ${LIBSSH2_LIBRARIES}) LIST(APPEND LIBGIT2_LIBS ${LIBSSH2_LIBRARIES})
LIST(APPEND LIBGIT2_LIBDIRS ${LIBSSH2_LIBRARY_DIRS})
LIST(APPEND LIBGIT2_PC_LIBS ${LIBSSH2_LDFLAGS}) LIST(APPEND LIBGIT2_PC_LIBS ${LIBSSH2_LDFLAGS})
#SET(LIBGIT2_PC_LIBS "${LIBGIT2_PC_LIBS} ${LIBSSH2_LDFLAGS}")
CHECK_LIBRARY_EXISTS("${LIBSSH2_LIBRARIES}" libssh2_userauth_publickey_frommemory "${LIBSSH2_LIBRARY_DIRS}" HAVE_LIBSSH2_MEMORY_CREDENTIALS) CHECK_LIBRARY_EXISTS("${LIBSSH2_LIBRARIES}" libssh2_userauth_publickey_frommemory "${LIBSSH2_LIBRARY_DIRS}" HAVE_LIBSSH2_MEMORY_CREDENTIALS)
IF (HAVE_LIBSSH2_MEMORY_CREDENTIALS) IF (HAVE_LIBSSH2_MEMORY_CREDENTIALS)
...@@ -404,7 +398,6 @@ ENDIF() ...@@ -404,7 +398,6 @@ ENDIF()
SET(LIBGIT2_OBJECTS ${LIBGIT2_OBJECTS} PARENT_SCOPE) SET(LIBGIT2_OBJECTS ${LIBGIT2_OBJECTS} PARENT_SCOPE)
SET(LIBGIT2_INCLUDES ${LIBGIT2_INCLUDES} PARENT_SCOPE) SET(LIBGIT2_INCLUDES ${LIBGIT2_INCLUDES} PARENT_SCOPE)
SET(LIBGIT2_LIBS ${LIBGIT2_LIBS} PARENT_SCOPE) SET(LIBGIT2_LIBS ${LIBGIT2_LIBS} PARENT_SCOPE)
SET(LIBGIT2_LIBDIRS ${LIBGIT2_LIBDIRS} PARENT_SCOPE)
IF(XCODE_VERSION) IF(XCODE_VERSION)
# This is required for Xcode to actually link the libgit2 library # This is required for Xcode to actually link the libgit2 library
...@@ -414,7 +407,6 @@ IF(XCODE_VERSION) ...@@ -414,7 +407,6 @@ IF(XCODE_VERSION)
ENDIF() ENDIF()
# Compile and link libgit2 # Compile and link libgit2
LINK_DIRECTORIES(${LIBGIT2_LIBDIRS})
ADD_LIBRARY(git2 ${WIN_RC} ${LIBGIT2_OBJECTS}) ADD_LIBRARY(git2 ${WIN_RC} ${LIBGIT2_OBJECTS})
TARGET_LINK_LIBRARIES(git2 ${LIBGIT2_LIBS}) TARGET_LINK_LIBRARIES(git2 ${LIBGIT2_LIBS})
......
...@@ -633,6 +633,11 @@ int git_attr_fnmatch__parse( ...@@ -633,6 +633,11 @@ int git_attr_fnmatch__parse(
if (--spec->length == 0) if (--spec->length == 0)
return GIT_ENOTFOUND; return GIT_ENOTFOUND;
/* Remove trailing spaces. */
while (pattern[spec->length - 1] == ' ' || pattern[spec->length - 1] == '\t')
if (--spec->length == 0)
return GIT_ENOTFOUND;
if (pattern[spec->length - 1] == '/') { if (pattern[spec->length - 1] == '/') {
spec->length--; spec->length--;
spec->flags = spec->flags | GIT_ATTR_FNMATCH_DIRECTORY; spec->flags = spec->flags | GIT_ATTR_FNMATCH_DIRECTORY;
......
...@@ -130,6 +130,7 @@ char git_diff_status_char(git_delta_t status) ...@@ -130,6 +130,7 @@ char git_diff_status_char(git_delta_t status)
case GIT_DELTA_COPIED: code = 'C'; break; case GIT_DELTA_COPIED: code = 'C'; break;
case GIT_DELTA_IGNORED: code = 'I'; break; case GIT_DELTA_IGNORED: code = 'I'; break;
case GIT_DELTA_UNTRACKED: code = '?'; break; case GIT_DELTA_UNTRACKED: code = '?'; break;
case GIT_DELTA_TYPECHANGE: code = 'T'; break;
case GIT_DELTA_UNREADABLE: code = 'X'; break; case GIT_DELTA_UNREADABLE: code = 'X'; break;
default: code = ' '; break; default: code = ' '; break;
} }
......
...@@ -10,6 +10,9 @@ ...@@ -10,6 +10,9 @@
#include <memory.h> #include <memory.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#ifdef __unix__
#include <sys/types.h> /* make sure macros like _BIG_ENDIAN visible */
#endif
#endif #endif
#ifdef SHA1DC_CUSTOM_INCLUDE_SHA1_C #ifdef SHA1DC_CUSTOM_INCLUDE_SHA1_C
...@@ -23,6 +26,13 @@ ...@@ -23,6 +26,13 @@
#include "sha1.h" #include "sha1.h"
#include "ubc_check.h" #include "ubc_check.h"
#if (defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || \
defined(i386) || defined(__i386) || defined(__i386__) || defined(__i486__) || \
defined(__i586__) || defined(__i686__) || defined(_M_IX86) || defined(__X86__) || \
defined(_X86_) || defined(__THW_INTEL__) || defined(__I86__) || defined(__INTEL__) || \
defined(__386) || defined(_M_X64) || defined(_M_AMD64))
#define SHA1DC_ON_INTEL_LIKE_PROCESSOR
#endif
/* /*
Because Little-Endian architectures are most common, Because Little-Endian architectures are most common,
...@@ -32,29 +42,70 @@ ...@@ -32,29 +42,70 @@
If you are compiling on a big endian platform and your compiler does not define one of these, If you are compiling on a big endian platform and your compiler does not define one of these,
you will have to add whatever macros your tool chain defines to indicate Big-Endianness. you will have to add whatever macros your tool chain defines to indicate Big-Endianness.
*/ */
#ifdef SHA1DC_BIGENDIAN
#undef SHA1DC_BIGENDIAN
#endif
#if (defined(_BYTE_ORDER) || defined(__BYTE_ORDER) || defined(__BYTE_ORDER__)) #if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__)
/*
#if ((defined(_BYTE_ORDER) && (_BYTE_ORDER == _BIG_ENDIAN)) || \ * Should detect Big Endian under GCC since at least 4.6.0 (gcc svn
(defined(__BYTE_ORDER) && (__BYTE_ORDER == __BIG_ENDIAN)) || \ * rev #165881). See
(defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __BIG_ENDIAN__)) ) * https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html
*
* This also works under clang since 3.2, it copied the GCC-ism. See
* clang.git's 3b198a97d2 ("Preprocessor: add __BYTE_ORDER__
* predefined macro", 2012-07-27)
*/
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
#define SHA1DC_BIGENDIAN #define SHA1DC_BIGENDIAN
#endif #endif
#else /* Not under GCC-alike */
#elif defined(__BYTE_ORDER) && defined(__BIG_ENDIAN)
#if (defined(_BIG_ENDIAN) || defined(__BIG_ENDIAN) || defined(__BIG_ENDIAN__) || \ /*
defined(__ARMEB__) || defined(__THUMBEB__) || defined(__AARCH64EB__) || \ * Should detect Big Endian under glibc.git since 14245eb70e ("entered
defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || \ * into RCS", 1992-11-25). Defined in <endian.h> which will have been
defined(__sparc)) * brought in by standard headers. See glibc.git and
* https://sourceforge.net/p/predef/wiki/Endianness/
*/
#if __BYTE_ORDER == __BIG_ENDIAN
#define SHA1DC_BIGENDIAN #define SHA1DC_BIGENDIAN
#endif #endif
/* Not under GCC-alike or glibc */
#elif defined(_BYTE_ORDER) && defined(_BIG_ENDIAN) && defined(_LITTLE_ENDIAN)
/*
* *BSD and newlib (embeded linux, cygwin, etc).
* the defined(_BIG_ENDIAN) && defined(_LITTLE_ENDIAN) part prevents
* this condition from matching with Solaris/sparc.
* (Solaris defines only one endian macro)
*/
#if _BYTE_ORDER == _BIG_ENDIAN
#define SHA1DC_BIGENDIAN
#endif #endif
/* Not under GCC-alike or glibc or *BSD or newlib */
#elif (defined(__ARMEB__) || defined(__THUMBEB__) || defined(__AARCH64EB__) || \
defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || \
defined(__sparc))
/*
* Should define Big Endian for a whitelist of known processors. See
* https://sourceforge.net/p/predef/wiki/Endianness/ and
* http://www.oracle.com/technetwork/server-storage/solaris/portingtosolaris-138514.html
*/
#define SHA1DC_BIGENDIAN
/* Not under GCC-alike or glibc or *BSD or newlib or <processor whitelist> */
#elif defined(SHA1DC_ON_INTEL_LIKE_PROCESSOR)
/*
* As a last resort before we do anything else we're not 100% sure
* about below, we blacklist specific processors here. We could add
* more, see e.g. https://wiki.debian.org/ArchitectureSpecificsMemo
*/
#else /* Not under GCC-alike or glibc or *BSD or newlib or <processor whitelist> or <processor blacklist> */
/* We do nothing more here for now */
/*#error "Uncomment this to see if you fall through all the detection"*/
#endif /* Big Endian detection */
#if (defined(SHA1DC_FORCE_LITTLEENDIAN) && defined(SHA1DC_BIGENDIAN)) #if (defined(SHA1DC_FORCE_LITTLEENDIAN) && defined(SHA1DC_BIGENDIAN))
#undef SHA1DC_BIGENDIAN #undef SHA1DC_BIGENDIAN
#endif #endif
...@@ -63,15 +114,8 @@ ...@@ -63,15 +114,8 @@
#endif #endif
/*ENDIANNESS SELECTION*/ /*ENDIANNESS SELECTION*/
#if (defined SHA1DC_FORCE_UNALIGNED_ACCESS || \ #if defined(SHA1DC_FORCE_UNALIGNED_ACCESS) || defined(SHA1DC_ON_INTEL_LIKE_PROCESSOR)
defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || \
defined(i386) || defined(__i386) || defined(__i386__) || defined(__i486__) || \
defined(__i586__) || defined(__i686__) || defined(_M_IX86) || defined(__X86__) || \
defined(_X86_) || defined(__THW_INTEL__) || defined(__I86__) || defined(__INTEL__) || \
defined(__386) || defined(_M_X64) || defined(_M_AMD64))
#define SHA1DC_ALLOW_UNALIGNED_ACCESS #define SHA1DC_ALLOW_UNALIGNED_ACCESS
#endif /*UNALIGNMENT DETECTION*/ #endif /*UNALIGNMENT DETECTION*/
...@@ -918,7 +962,7 @@ static void sha1recompress_fast_ ## t (uint32_t ihvin[5], uint32_t ihvout[5], co ...@@ -918,7 +962,7 @@ static void sha1recompress_fast_ ## t (uint32_t ihvin[5], uint32_t ihvout[5], co
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning(push) #pragma warning(push)
#pragma warning(disable: 4127) /* Complier complains about the checks in the above macro being constant. */ #pragma warning(disable: 4127) /* Compiler complains about the checks in the above macro being constant. */
#endif #endif
#ifdef DOSTORESTATE0 #ifdef DOSTORESTATE0
......
...@@ -213,16 +213,6 @@ static int parse_ignore_file( ...@@ -213,16 +213,6 @@ static int parse_ignore_file(
if (ignore_case) if (ignore_case)
match->flags |= GIT_ATTR_FNMATCH_ICASE; match->flags |= GIT_ATTR_FNMATCH_ICASE;
while (match->length > 0) {
if (match->pattern[match->length - 1] == ' ' ||
match->pattern[match->length - 1] == '\t') {
match->pattern[match->length - 1] = 0;
match->length --;
} else {
break;
}
}
scan = git__next_line(scan); scan = git__next_line(scan);
/* /*
......
...@@ -157,6 +157,7 @@ static void impl__free(git_odb_backend *_backend) ...@@ -157,6 +157,7 @@ static void impl__free(git_odb_backend *_backend)
{ {
struct memory_packer_db *db = (struct memory_packer_db *)_backend; struct memory_packer_db *db = (struct memory_packer_db *)_backend;
git_mempack_reset(_backend);
git_oidmap_free(db->objects); git_oidmap_free(db->objects);
git__free(db); git__free(db);
} }
......
...@@ -1603,6 +1603,8 @@ static int create_new_reflog_file(const char *filepath) ...@@ -1603,6 +1603,8 @@ static int create_new_reflog_file(const char *filepath)
GIT_INLINE(int) retrieve_reflog_path(git_buf *path, git_repository *repo, const char *name) GIT_INLINE(int) retrieve_reflog_path(git_buf *path, git_repository *repo, const char *name)
{ {
if (strcmp(name, GIT_HEAD_FILE) == 0)
return git_buf_join3(path, '/', repo->gitdir, GIT_REFLOG_DIR, name);
return git_buf_join3(path, '/', repo->commondir, GIT_REFLOG_DIR, name); return git_buf_join3(path, '/', repo->commondir, GIT_REFLOG_DIR, name);
} }
......
...@@ -115,6 +115,9 @@ int git_reference_dup(git_reference **dest, git_reference *source) ...@@ -115,6 +115,9 @@ int git_reference_dup(git_reference **dest, git_reference *source)
GITERR_CHECK_ALLOC(*dest); GITERR_CHECK_ALLOC(*dest);
(*dest)->db = source->db;
GIT_REFCOUNT_INC((*dest)->db);
return 0; return 0;
} }
......
...@@ -116,6 +116,10 @@ int git_reference_lookup_resolved( ...@@ -116,6 +116,10 @@ int git_reference_lookup_resolved(
* with the given name pointing to the reference pointed to by * with the given name pointing to the reference pointed to by
* the file. If it is not a symbolic reference, it will return * the file. If it is not a symbolic reference, it will return
* the resolved reference. * the resolved reference.
*
* Note that because the refdb is not involved for symbolic references, they
* won't be owned, hence you should either not make the returned reference
* 'externally visible', or perform the lookup before returning it to the user.
*/ */
int git_reference__read_head( int git_reference__read_head(
git_reference **out, git_reference **out,
......
...@@ -304,6 +304,7 @@ int git_refspec__dwim_one(git_vector *out, git_refspec *spec, git_vector *refs) ...@@ -304,6 +304,7 @@ int git_refspec__dwim_one(git_vector *out, git_refspec *spec, git_vector *refs)
git_buf buf = GIT_BUF_INIT; git_buf buf = GIT_BUF_INIT;
size_t j, pos; size_t j, pos;
git_remote_head key; git_remote_head key;
git_refspec *cur;
const char* formatters[] = { const char* formatters[] = {
GIT_REFS_DIR "%s", GIT_REFS_DIR "%s",
...@@ -312,7 +313,9 @@ int git_refspec__dwim_one(git_vector *out, git_refspec *spec, git_vector *refs) ...@@ -312,7 +313,9 @@ int git_refspec__dwim_one(git_vector *out, git_refspec *spec, git_vector *refs)
NULL NULL
}; };
git_refspec *cur = git__calloc(1, sizeof(git_refspec)); assert(out && spec && refs);
cur = git__calloc(1, sizeof(git_refspec));
GITERR_CHECK_ALLOC(cur); GITERR_CHECK_ALLOC(cur);
cur->force = spec->force; cur->force = spec->force;
......
...@@ -237,7 +237,7 @@ static int create_internal(git_remote **out, git_repository *repo, const char *n ...@@ -237,7 +237,7 @@ static int create_internal(git_remote **out, git_repository *repo, const char *n
goto on_error; goto on_error;
/* only write for non-anonymous remotes */ /* only write for non-anonymous remotes */
if (name && (error = write_add_refspec(repo, name, fetch, true)) < 0) if (repo && name && (error = write_add_refspec(repo, name, fetch, true)) < 0)
goto on_error; goto on_error;
if (repo && (error = lookup_remote_prune_config(remote, config_ro, name)) < 0) if (repo && (error = lookup_remote_prune_config(remote, config_ro, name)) < 0)
......
...@@ -375,20 +375,6 @@ static int add_parents_to_list(git_revwalk *walk, git_commit_list_node *commit, ...@@ -375,20 +375,6 @@ static int add_parents_to_list(git_revwalk *walk, git_commit_list_node *commit,
return 0; return 0;
} }
static int everybody_uninteresting(git_commit_list *orig)
{
git_commit_list *list = orig;
while (list) {
git_commit_list_node *commit = list->item;
list = list->next;
if (!commit->uninteresting)
return 0;
}
return 1;
}
/* How many unintersting commits we want to look at after we run out of interesting ones */ /* How many unintersting commits we want to look at after we run out of interesting ones */
#define SLOP 5 #define SLOP 5
...@@ -398,16 +384,15 @@ static int still_interesting(git_commit_list *list, int64_t time, int slop) ...@@ -398,16 +384,15 @@ static int still_interesting(git_commit_list *list, int64_t time, int slop)
if (!list) if (!list)
return 0; return 0;
/* for (; list; list = list->next) {
* If the destination list has commits with an earlier date /*
* than our source we want to continue looking. * If the destination list has commits with an earlier date than
*/ * our source or if it still contains interesting commits we
if (time <= list->item->time) * want to continue looking.
return SLOP; */
if (!list->item->uninteresting || list->item->time > time)
/* If we find interesting commits, we reset the slop count */ return SLOP;
if (!everybody_uninteresting(list)) }
return SLOP;
/* Everything's uninteresting, reduce the count */ /* Everything's uninteresting, reduce the count */
return slop - 1; return slop - 1;
......
...@@ -104,7 +104,8 @@ int git_openssl_stream_global_init(void) ...@@ -104,7 +104,8 @@ int git_openssl_stream_global_init(void)
ssl_opts |= SSL_OP_NO_COMPRESSION; ssl_opts |= SSL_OP_NO_COMPRESSION;
#endif #endif
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) #if OPENSSL_VERSION_NUMBER < 0x10100000L || \
(defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L)
SSL_load_error_strings(); SSL_load_error_strings();
OpenSSL_add_ssl_algorithms(); OpenSSL_add_ssl_algorithms();
#else #else
......
...@@ -31,7 +31,8 @@ extern int git_openssl__set_cert_location(const char *file, const char *path); ...@@ -31,7 +31,8 @@ extern int git_openssl__set_cert_location(const char *file, const char *path);
# if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) # if OPENSSL_VERSION_NUMBER < 0x10100000L || \
(defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L)
GIT_INLINE(BIO_METHOD*) BIO_meth_new(int type, const char *name) GIT_INLINE(BIO_METHOD*) BIO_meth_new(int type, const char *name)
{ {
......
...@@ -91,7 +91,7 @@ __KHASH_IMPL( ...@@ -91,7 +91,7 @@ __KHASH_IMPL(
static int submodule_alloc(git_submodule **out, git_repository *repo, const char *name); static int submodule_alloc(git_submodule **out, git_repository *repo, const char *name);
static git_config_backend *open_gitmodules(git_repository *repo, int gitmod); static git_config_backend *open_gitmodules(git_repository *repo, int gitmod);
static git_config *gitmodules_snapshot(git_repository *repo); static int gitmodules_snapshot(git_config **snap, git_repository *repo);
static int get_url_base(git_buf *url, git_repository *repo); static int get_url_base(git_buf *url, git_repository *repo);
static int lookup_head_remote_key(git_buf *remote_key, git_repository *repo); static int lookup_head_remote_key(git_buf *remote_key, git_repository *repo);
static int lookup_default_remote(git_remote **remote, git_repository *repo); static int lookup_default_remote(git_remote **remote, git_repository *repo);
...@@ -186,6 +186,13 @@ static int load_submodule_names(git_strmap *out, git_repository *repo, git_confi ...@@ -186,6 +186,13 @@ static int load_submodule_names(git_strmap *out, git_repository *repo, git_confi
fdot = strchr(entry->name, '.'); fdot = strchr(entry->name, '.');
ldot = strrchr(entry->name, '.'); ldot = strrchr(entry->name, '.');
if (git_strmap_exists(out, entry->value)) {
giterr_set(GITERR_SUBMODULE,
"duplicated submodule path '%s'", entry->value);
error = -1;
goto out;
}
git_buf_clear(&buf); git_buf_clear(&buf);
git_buf_put(&buf, fdot + 1, ldot - fdot - 1); git_buf_put(&buf, fdot + 1, ldot - fdot - 1);
isvalid = git_submodule_name_is_valid(repo, buf.ptr, 0); isvalid = git_submodule_name_is_valid(repo, buf.ptr, 0);
...@@ -544,8 +551,11 @@ int git_submodule__map(git_repository *repo, git_strmap *map) ...@@ -544,8 +551,11 @@ int git_submodule__map(git_repository *repo, git_strmap *map)
data.map = map; data.map = map;
data.repo = repo; data.repo = repo;
if ((mods = gitmodules_snapshot(repo)) == NULL) if ((error = gitmodules_snapshot(&mods, repo)) < 0) {
if (error == GIT_ENOTFOUND)
error = 0;
goto cleanup; goto cleanup;
}
data.mods = mods; data.mods = mods;
if ((error = git_config_foreach( if ((error = git_config_foreach(
...@@ -1552,7 +1562,8 @@ int git_submodule_reload(git_submodule *sm, int force) ...@@ -1552,7 +1562,8 @@ int git_submodule_reload(git_submodule *sm, int force)
if (!git_repository_is_bare(sm->repo)) { if (!git_repository_is_bare(sm->repo)) {
/* refresh config data */ /* refresh config data */
mods = gitmodules_snapshot(sm->repo); if ((error = gitmodules_snapshot(&mods, sm->repo)) < 0 && error != GIT_ENOTFOUND)
return error;
if (mods != NULL) { if (mods != NULL) {
error = submodule_read_config(sm, mods); error = submodule_read_config(sm, mods);
git_config_free(mods); git_config_free(mods);
...@@ -1962,32 +1973,37 @@ static int submodule_load_from_wd_lite(git_submodule *sm) ...@@ -1962,32 +1973,37 @@ static int submodule_load_from_wd_lite(git_submodule *sm)
} }
/** /**
* Returns a snapshot of $WORK_TREE/.gitmodules. * Requests a snapshot of $WORK_TREE/.gitmodules.
* *
* We ignore any errors and just pretend the file isn't there. * Returns GIT_ENOTFOUND in case no .gitmodules file exist
*/ */
static git_config *gitmodules_snapshot(git_repository *repo) static int gitmodules_snapshot(git_config **snap, git_repository *repo)
{ {
const char *workdir = git_repository_workdir(repo); const char *workdir = git_repository_workdir(repo);
git_config *mods = NULL, *snap = NULL; git_config *mods = NULL;
git_buf path = GIT_BUF_INIT; git_buf path = GIT_BUF_INIT;
int error;
if (workdir != NULL) { if (!workdir)
if (git_buf_joinpath(&path, workdir, GIT_MODULES_FILE) != 0) return GIT_ENOTFOUND;
return NULL;
if (git_config_open_ondisk(&mods, path.ptr) < 0) if ((error = git_buf_joinpath(&path, workdir, GIT_MODULES_FILE)) < 0)
mods = NULL; return error;
}
git_buf_free(&path); if ((error = git_config_open_ondisk(&mods, path.ptr)) < 0)
goto cleanup;
if (mods) { if ((error = git_config_snapshot(snap, mods)) < 0)
git_config_snapshot(&snap, mods); goto cleanup;
error = 0;
cleanup:
if (mods)
git_config_free(mods); git_config_free(mods);
} git_buf_free(&path);
return snap; return error;
} }
static git_config_backend *open_gitmodules( static git_config_backend *open_gitmodules(
......
...@@ -510,8 +510,14 @@ static int local_counting(int stage, unsigned int current, unsigned int total, v ...@@ -510,8 +510,14 @@ static int local_counting(int stage, unsigned int current, unsigned int total, v
static int foreach_reference_cb(git_reference *reference, void *payload) static int foreach_reference_cb(git_reference *reference, void *payload)
{ {
git_revwalk *walk = (git_revwalk *)payload; git_revwalk *walk = (git_revwalk *)payload;
int error;
if (git_reference_type(reference) != GIT_REF_OID) {
git_reference_free(reference);
return 0;
}
int error = git_revwalk_hide(walk, git_reference_target(reference)); error = git_revwalk_hide(walk, git_reference_target(reference));
/* The reference is in the local repository, so the target may not /* The reference is in the local repository, so the target may not
* exist on the remote. It also may not be a commit. */ * exist on the remote. It also may not be a commit. */
if (error == GIT_ENOTFOUND || error == GITERR_INVALID) { if (error == GIT_ENOTFOUND || error == GITERR_INVALID) {
......
...@@ -212,6 +212,7 @@ static void ssh_stream_free(git_smart_subtransport_stream *stream) ...@@ -212,6 +212,7 @@ static void ssh_stream_free(git_smart_subtransport_stream *stream)
} }
if (s->session) { if (s->session) {
libssh2_session_disconnect(s->session, "closing transport");
libssh2_session_free(s->session); libssh2_session_free(s->session);
s->session = NULL; s->session = NULL;
} }
...@@ -489,7 +490,7 @@ static int _git_ssh_session_create( ...@@ -489,7 +490,7 @@ static int _git_ssh_session_create(
} }
do { do {
rc = libssh2_session_startup(s, socket->s); rc = libssh2_session_handshake(s, socket->s);
} while (LIBSSH2_ERROR_EAGAIN == rc || LIBSSH2_ERROR_TIMEOUT == rc); } while (LIBSSH2_ERROR_EAGAIN == rc || LIBSSH2_ERROR_TIMEOUT == rc);
if (rc != LIBSSH2_ERROR_NONE) { if (rc != LIBSSH2_ERROR_NONE) {
......
...@@ -10,7 +10,12 @@ ...@@ -10,7 +10,12 @@
#include "common.h" #include "common.h"
#ifdef GIT_WIN32 #ifdef GIT_WIN32
# include "win32/utf-conv.h"
# include "win32/w32_buffer.h" # include "win32/w32_buffer.h"
# ifdef HAVE_QSORT_S
# include <search.h>
# endif
#endif #endif
#ifdef _MSC_VER #ifdef _MSC_VER
......
...@@ -131,7 +131,7 @@ static int open_worktree_dir(git_worktree **out, const char *parent, const char ...@@ -131,7 +131,7 @@ static int open_worktree_dir(git_worktree **out, const char *parent, const char
goto out; goto out;
} }
if ((wt = git__calloc(1, sizeof(struct git_repository))) == NULL) { if ((wt = git__calloc(1, sizeof(*wt))) == NULL) {
error = -1; error = -1;
goto out; goto out;
} }
......
...@@ -9,6 +9,7 @@ SET(CLAR_FIXTURES "${CMAKE_CURRENT_SOURCE_DIR}/resources/") ...@@ -9,6 +9,7 @@ SET(CLAR_FIXTURES "${CMAKE_CURRENT_SOURCE_DIR}/resources/")
SET(CLAR_PATH "${CMAKE_CURRENT_SOURCE_DIR}") SET(CLAR_PATH "${CMAKE_CURRENT_SOURCE_DIR}")
ADD_DEFINITIONS(-DCLAR_FIXTURE_PATH=\"${CLAR_FIXTURES}\") ADD_DEFINITIONS(-DCLAR_FIXTURE_PATH=\"${CLAR_FIXTURES}\")
ADD_DEFINITIONS(-DCLAR_TMPDIR=\"libgit2_tests\") ADD_DEFINITIONS(-DCLAR_TMPDIR=\"libgit2_tests\")
ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64)
INCLUDE_DIRECTORIES(${CLAR_PATH} ${libgit2_BINARY_DIR}/src) INCLUDE_DIRECTORIES(${CLAR_PATH} ${libgit2_BINARY_DIR}/src)
FILE(GLOB_RECURSE SRC_TEST ${CLAR_PATH}/*/*.c ${CLAR_PATH}/*/*.h) FILE(GLOB_RECURSE SRC_TEST ${CLAR_PATH}/*/*.c ${CLAR_PATH}/*/*.h)
...@@ -30,7 +31,6 @@ SET_SOURCE_FILES_PROPERTIES( ...@@ -30,7 +31,6 @@ SET_SOURCE_FILES_PROPERTIES(
${CLAR_PATH}/clar.c ${CLAR_PATH}/clar.c
PROPERTIES OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/clar.suite) PROPERTIES OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/clar.suite)
LINK_DIRECTORIES(${LIBGIT2_LIBDIRS})
INCLUDE_DIRECTORIES(${LIBGIT2_INCLUDES}) INCLUDE_DIRECTORIES(${LIBGIT2_INCLUDES})
ADD_EXECUTABLE(libgit2_clar ${SRC_CLAR} ${SRC_TEST} ${LIBGIT2_OBJECTS}) ADD_EXECUTABLE(libgit2_clar ${SRC_CLAR} ${SRC_TEST} ${LIBGIT2_OBJECTS})
......
...@@ -61,6 +61,22 @@ void test_attr_ignore__ignore_space(void) ...@@ -61,6 +61,22 @@ void test_attr_ignore__ignore_space(void)
assert_is_ignored(true, "NewFolder/NewFolder/File.txt"); assert_is_ignored(true, "NewFolder/NewFolder/File.txt");
} }
void test_attr_ignore__ignore_dir(void)
{
cl_git_rewritefile("attr/.gitignore", "dir/\n");
assert_is_ignored(true, "dir");
assert_is_ignored(true, "dir/file");
}
void test_attr_ignore__ignore_dir_with_trailing_space(void)
{
cl_git_rewritefile("attr/.gitignore", "dir/ \n");
assert_is_ignored(true, "dir");
assert_is_ignored(true, "dir/file");
}
void test_attr_ignore__ignore_root(void) void test_attr_ignore__ignore_root(void)
{ {
cl_git_rewritefile("attr/.gitignore", "/\n\n/NewFolder\n/NewFolder/NewFolder"); cl_git_rewritefile("attr/.gitignore", "/\n\n/NewFolder\n/NewFolder/NewFolder");
......
#include "clar_libgit2.h" #include "clar_libgit2.h"
#include "diff_generate.h"
#include "git2/checkout.h" #include "git2/checkout.h"
#include "path.h" #include "path.h"
#include "posix.h" #include "posix.h"
...@@ -307,3 +308,28 @@ void test_checkout_typechange__checkout_with_conflicts(void) ...@@ -307,3 +308,28 @@ void test_checkout_typechange__checkout_with_conflicts(void)
git_object_free(obj); git_object_free(obj);
} }
} }
void test_checkout_typechange__status_char(void)
{
size_t i;
git_oid oid;
git_commit *commit;
git_diff *diff;
const git_diff_delta *delta;
git_diff_options diffopts = GIT_DIFF_OPTIONS_INIT;
char expected[8] = {'M', 'M', 'R', 'T', 'D', 'R', 'A', 'R'};
git_oid_fromstr(&oid, "9b19edf33a03a0c59cdfc113bfa5c06179bf9b1a");
cl_git_pass(git_commit_lookup(&commit, g_repo, &oid));
diffopts.flags |= GIT_DIFF_INCLUDE_TYPECHANGE;
cl_git_pass(git_diff__commit(&diff, g_repo, commit, &diffopts));
cl_git_pass(git_diff_find_similar(diff, NULL));
for (i = 0; i < git_diff_num_deltas(diff); i++) {
delta = git_diff_get_delta(diff, i);
cl_assert_equal_i(expected[i], git_diff_status_char(delta->status));
}
git_diff_free(diff);
git_commit_free(commit);
}
...@@ -254,7 +254,7 @@ void test_diff_stats__rename_nochanges_no_find(void) ...@@ -254,7 +254,7 @@ void test_diff_stats__rename_nochanges_no_find(void)
git_buf_free(&buf); git_buf_free(&buf);
} }
void test_diff_stats__rename_and_modifiy_no_find(void) void test_diff_stats__rename_and_modify_no_find(void)
{ {
git_buf buf = GIT_BUF_INIT; git_buf buf = GIT_BUF_INIT;
const char *stat = const char *stat =
......
...@@ -343,6 +343,29 @@ void test_fetchhead_nonetwork__unborn_with_upstream(void) ...@@ -343,6 +343,29 @@ void test_fetchhead_nonetwork__unborn_with_upstream(void)
cl_fixture_cleanup("./repowithunborn"); cl_fixture_cleanup("./repowithunborn");
} }
void test_fetchhead_nonetwork__fetch_into_repo_with_symrefs(void)
{
git_repository *repo;
git_remote *remote;
git_reference *symref;
repo = cl_git_sandbox_init("empty_standard_repo");
/*
* Testing for a specific constellation where the repository has at
* least one symbolic reference in its refdb.
*/
cl_git_pass(git_reference_symbolic_create(&symref, repo, "refs/heads/symref", "refs/heads/master", 0, NULL));
cl_git_pass(git_remote_set_url(repo, "origin", cl_fixture("testrepo.git")));
cl_git_pass(git_remote_lookup(&remote, repo, "origin"));
cl_git_pass(git_remote_fetch(remote, NULL, NULL, NULL));
git_remote_free(remote);
git_reference_free(symref);
cl_git_sandbox_cleanup();
}
void test_fetchhead_nonetwork__quote_in_branch_name(void) void test_fetchhead_nonetwork__quote_in_branch_name(void)
{ {
cl_set_cleanup(&cleanup_repository, "./test1"); cl_set_cleanup(&cleanup_repository, "./test1");
......
...@@ -21,6 +21,7 @@ void test_refs_dup__direct(void) ...@@ -21,6 +21,7 @@ void test_refs_dup__direct(void)
cl_git_pass(git_reference_dup(&b, a)); cl_git_pass(git_reference_dup(&b, a));
cl_assert(git_reference_cmp(a, b) == 0); cl_assert(git_reference_cmp(a, b) == 0);
cl_assert(git_reference_owner(b) == g_repo);
git_reference_free(b); git_reference_free(b);
git_reference_free(a); git_reference_free(a);
...@@ -34,6 +35,7 @@ void test_refs_dup__symbolic(void) ...@@ -34,6 +35,7 @@ void test_refs_dup__symbolic(void)
cl_git_pass(git_reference_dup(&b, a)); cl_git_pass(git_reference_dup(&b, a));
cl_assert(git_reference_cmp(a, b) == 0); cl_assert(git_reference_cmp(a, b) == 0);
cl_assert(git_reference_owner(b) == g_repo);
git_reference_free(b); git_reference_free(b);
git_reference_free(a); git_reference_free(a);
......
[core]
bare = true
repositoryformatversion = 0
filemode = false
symlinks = false
ignorecase = true
Unnamed repository; edit this file 'description' to name the repository.
P pack-9adacb9971981a1a3264fd473da5b800f2715959.pack
# pack-refs with: peeled fully-peeled sorted
3ae0f53011bdb7e68f99bde4943449f36c1c318a refs/heads/A
061978578d7c9ff2ba92dd36d31fd8d809871030 refs/heads/B
743398b425d6c216d6cfaae3786b5bc436393ae5 refs/heads/C
790ba0facf6fd103699a5c40cd19dad277ff49cd refs/heads/D
d3d783066cf7d95def6844b9c5118c1e7bcce7df refs/heads/E
d3d783066cf7d95def6844b9c5118c1e7bcce7df refs/heads/master
...@@ -555,3 +555,30 @@ void test_revwalk_basic__old_hidden_commit_two(void) ...@@ -555,3 +555,30 @@ void test_revwalk_basic__old_hidden_commit_two(void)
cl_git_fail_with(GIT_ITEROVER, git_revwalk_next(&oid, _walk)); cl_git_fail_with(GIT_ITEROVER, git_revwalk_next(&oid, _walk));
} }
/*
* Ensure that we correctly hide all parent commits of a newer
* commit when first hiding older commits.
*
* % git rev-list D ^B ^A ^E
* 790ba0facf6fd103699a5c40cd19dad277ff49cd
* b82cee5004151ae0c4f82b69fb71b87477664b6f
*/
void test_revwalk_basic__newer_hidden_commit_hides_old_commits(void)
{
git_oid oid;
revwalk_basic_setup_walk("revwalk.git");
cl_git_pass(git_revwalk_push_ref(_walk, "refs/heads/D"));
cl_git_pass(git_revwalk_hide_ref(_walk, "refs/heads/B"));
cl_git_pass(git_revwalk_hide_ref(_walk, "refs/heads/A"));
cl_git_pass(git_revwalk_hide_ref(_walk, "refs/heads/E"));
cl_git_pass(git_revwalk_next(&oid, _walk));
cl_assert(git_oid_streq(&oid, "b82cee5004151ae0c4f82b69fb71b87477664b6f"));
cl_git_pass(git_revwalk_next(&oid, _walk));
cl_assert(git_oid_streq(&oid, "790ba0facf6fd103699a5c40cd19dad277ff49cd"));
cl_git_fail_with(GIT_ITEROVER, git_revwalk_next(&oid, _walk));
}
...@@ -132,6 +132,27 @@ void test_submodule_lookup__foreach(void) ...@@ -132,6 +132,27 @@ void test_submodule_lookup__foreach(void)
cl_assert_equal_i(8, data.count); cl_assert_equal_i(8, data.count);
} }
static int foreach_cb(git_submodule *sm, const char *name, void *payload)
{
GIT_UNUSED(sm);
GIT_UNUSED(name);
GIT_UNUSED(payload);
return 0;
}
void test_submodule_lookup__duplicated_path(void)
{
cl_git_rewritefile("submod2/.gitmodules",
"[submodule \"sm1\"]\n"
" path = duplicated-path\n"
" url = sm1\n"
"[submodule \"sm2\"]\n"
" path = duplicated-path\n"
" url = sm2\n");
cl_git_fail(git_submodule_foreach(g_repo, foreach_cb, NULL));
}
void test_submodule_lookup__lookup_even_with_unborn_head(void) void test_submodule_lookup__lookup_even_with_unborn_head(void)
{ {
git_reference *head; git_reference *head;
...@@ -430,14 +451,6 @@ void test_submodule_lookup__lookup_in_bare_repository_fails(void) ...@@ -430,14 +451,6 @@ void test_submodule_lookup__lookup_in_bare_repository_fails(void)
cl_git_fail(git_submodule_lookup(&sm, g_repo, "nonexisting")); cl_git_fail(git_submodule_lookup(&sm, g_repo, "nonexisting"));
} }
static int foreach_cb(git_submodule *sm, const char *name, void *payload)
{
GIT_UNUSED(sm);
GIT_UNUSED(name);
GIT_UNUSED(payload);
return 0;
}
void test_submodule_lookup__foreach_in_bare_repository_fails(void) void test_submodule_lookup__foreach_in_bare_repository_fails(void)
{ {
cl_git_sandbox_cleanup(); cl_git_sandbox_cleanup();
...@@ -445,3 +458,19 @@ void test_submodule_lookup__foreach_in_bare_repository_fails(void) ...@@ -445,3 +458,19 @@ void test_submodule_lookup__foreach_in_bare_repository_fails(void)
cl_git_fail(git_submodule_foreach(g_repo, foreach_cb, NULL)); cl_git_fail(git_submodule_foreach(g_repo, foreach_cb, NULL));
} }
void test_submodule_lookup__fail_invalid_gitmodules(void)
{
git_submodule *sm;
sm_lookup_data data;
memset(&data, 0, sizeof(data));
cl_git_rewritefile("submod2/.gitmodules",
"[submodule \"Test_App\"\n"
" path = Test_App\n"
" url = ../Test_App\n");
cl_git_fail(git_submodule_lookup(&sm, g_repo, "Test_App"));
cl_git_fail(git_submodule_foreach(g_repo, sm_lookup_cb, &data));
}
...@@ -22,6 +22,32 @@ void test_worktree_reflog__cleanup(void) ...@@ -22,6 +22,32 @@ void test_worktree_reflog__cleanup(void)
cleanup_fixture_worktree(&fixture); cleanup_fixture_worktree(&fixture);
} }
void test_worktree_reflog__read_worktree_HEAD(void)
{
git_reflog *reflog;
const git_reflog_entry *entry;
cl_git_pass(git_reflog_read(&reflog, fixture.worktree, "HEAD"));
cl_assert_equal_i(1, git_reflog_entrycount(reflog));
entry = git_reflog_entry_byindex(reflog, 0);
cl_assert(entry != NULL);
cl_assert_equal_s("checkout: moving from 099fabac3a9ea935598528c27f866e34089c2eff to testrepo-worktree", git_reflog_entry_message(entry));
git_reflog_free(reflog);
}
void test_worktree_reflog__read_parent_HEAD(void)
{
git_reflog *reflog;
cl_git_pass(git_reflog_read(&reflog, fixture.repo, "HEAD"));
/* there is no logs/HEAD in the parent repo */
cl_assert_equal_i(0, git_reflog_entrycount(reflog));
git_reflog_free(reflog);
}
void test_worktree_reflog__read(void) void test_worktree_reflog__read(void)
{ {
git_reflog *reflog; git_reflog *reflog;
......
...@@ -27,6 +27,7 @@ void test_worktree_repository__head(void) ...@@ -27,6 +27,7 @@ void test_worktree_repository__head(void)
cl_git_pass(git_reference_lookup(&ref, fixture.repo, "refs/heads/testrepo-worktree")); cl_git_pass(git_reference_lookup(&ref, fixture.repo, "refs/heads/testrepo-worktree"));
cl_git_pass(git_repository_head_for_worktree(&head, fixture.repo, "testrepo-worktree")); cl_git_pass(git_repository_head_for_worktree(&head, fixture.repo, "testrepo-worktree"));
cl_assert(git_reference_cmp(ref, head) == 0); cl_assert(git_reference_cmp(ref, head) == 0);
cl_assert(git_reference_owner(ref) == fixture.repo);
git_reference_free(ref); git_reference_free(ref);
git_reference_free(head); git_reference_free(head);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment