summaryrefslogtreecommitdiff
path: root/contrib
diff options
context:
space:
mode:
Diffstat (limited to 'contrib')
-rw-r--r--contrib/buildsystems/CMakeLists.txt991
-rw-r--r--contrib/buildsystems/Generators/Vcxproj.pm1
-rwxr-xr-xcontrib/buildsystems/engine.pl4
-rw-r--r--contrib/coccinelle/array.cocci8
-rw-r--r--contrib/coccinelle/commit.cocci18
-rw-r--r--contrib/coccinelle/xcalloc.cocci10
-rw-r--r--contrib/completion/git-completion.bash539
-rw-r--r--contrib/completion/git-completion.zsh144
-rw-r--r--contrib/completion/git-prompt.sh38
-rw-r--r--contrib/diff-highlight/DiffHighlight.pm2
-rwxr-xr-xcontrib/fast-import/import-tars.perl2
-rwxr-xr-xcontrib/git-resurrect.sh13
-rwxr-xr-xcontrib/mw-to-git/git-mw.perl2
-rwxr-xr-xcontrib/mw-to-git/git-remote-mediawiki.perl80
-rw-r--r--contrib/mw-to-git/git-remote-mediawiki.txt2
-rw-r--r--contrib/mw-to-git/t/.gitignore2
-rw-r--r--contrib/mw-to-git/t/README10
-rw-r--r--contrib/mw-to-git/t/install-wiki/.gitignore1
-rw-r--r--contrib/mw-to-git/t/install-wiki/LocalSettings.php129
-rw-r--r--contrib/mw-to-git/t/install-wiki/db_install.php120
-rwxr-xr-xcontrib/mw-to-git/t/t9360-mw-to-git-clone.sh8
-rwxr-xr-xcontrib/mw-to-git/t/t9363-mw-to-git-export-import.sh9
-rwxr-xr-xcontrib/mw-to-git/t/test-gitmw-lib.sh162
-rwxr-xr-xcontrib/mw-to-git/t/test-gitmw.pl22
-rw-r--r--contrib/mw-to-git/t/test.config23
-rw-r--r--contrib/subtree/Makefile6
-rw-r--r--contrib/subtree/git-subtree.txt6
-rw-r--r--contrib/svn-fe/.gitignore4
-rw-r--r--contrib/svn-fe/Makefile105
-rw-r--r--contrib/svn-fe/svn-fe.c18
-rw-r--r--contrib/svn-fe/svn-fe.txt71
-rwxr-xr-xcontrib/svn-fe/svnrdump_sim.py68
32 files changed, 1697 insertions, 921 deletions
diff --git a/contrib/buildsystems/CMakeLists.txt b/contrib/buildsystems/CMakeLists.txt
new file mode 100644
index 0000000000..ac3dbc079a
--- /dev/null
+++ b/contrib/buildsystems/CMakeLists.txt
@@ -0,0 +1,991 @@
+#
+# Copyright (c) 2020 Sibi Siddharthan
+#
+
+#[[
+
+Instructions how to use this in Visual Studio:
+
+Open the worktree as a folder. Visual Studio 2019 and later will detect
+the CMake configuration automatically and set everything up for you,
+ready to build. You can then run the tests in `t/` via a regular Git Bash.
+
+Note: Visual Studio also has the option of opening `CMakeLists.txt`
+directly; Using this option, Visual Studio will not find the source code,
+though, therefore the `File>Open>Folder...` option is preferred.
+
+Instructions to run CMake manually:
+
+ mkdir -p contrib/buildsystems/out
+ cd contrib/buildsystems/out
+ cmake ../ -DCMAKE_BUILD_TYPE=Release
+
+This will build the git binaries in contrib/buildsystems/out
+directory (our top-level .gitignore file knows to ignore contents of
+this directory).
+
+Possible build configurations(-DCMAKE_BUILD_TYPE) with corresponding
+compiler flags
+Debug : -g
+Release: -O3
+RelWithDebInfo : -O2 -g
+MinSizeRel : -Os
+empty(default) :
+
+NOTE: -DCMAKE_BUILD_TYPE is optional. For multi-config generators like Visual Studio
+this option is ignored
+
+This process generates a Makefile(Linux/*BSD/MacOS) , Visual Studio solution(Windows) by default.
+Run `make` to build Git on Linux/*BSD/MacOS.
+Open git.sln on Windows and build Git.
+
+NOTE: By default CMake uses Makefile as the build tool on Linux and Visual Studio in Windows,
+to use another tool say `ninja` add this to the command line when configuring.
+`-G Ninja`
+
+]]
+cmake_minimum_required(VERSION 3.14)
+
+#set the source directory to root of git
+set(CMAKE_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/../..)
+if(WIN32)
+ set(VCPKG_DIR "${CMAKE_SOURCE_DIR}/compat/vcbuild/vcpkg")
+ if(MSVC AND NOT EXISTS ${VCPKG_DIR})
+ message("Initializing vcpkg and building the Git's dependencies (this will take a while...)")
+ execute_process(COMMAND ${CMAKE_SOURCE_DIR}/compat/vcbuild/vcpkg_install.bat)
+ endif()
+ list(APPEND CMAKE_PREFIX_PATH "${VCPKG_DIR}/installed/x64-windows")
+
+ # In the vcpkg edition, we need this to be able to link to libcurl
+ set(CURL_NO_CURL_CMAKE ON)
+endif()
+
+find_program(SH_EXE sh PATHS "C:/Program Files/Git/bin")
+if(NOT SH_EXE)
+ message(FATAL_ERROR "sh: shell interpreter was not found in your path, please install one."
+ "On Windows, you can get it as part of 'Git for Windows' install at https://gitforwindows.org/")
+endif()
+
+#Create GIT-VERSION-FILE using GIT-VERSION-GEN
+if(NOT EXISTS ${CMAKE_SOURCE_DIR}/GIT-VERSION-FILE)
+ message("Generating GIT-VERSION-FILE")
+ execute_process(COMMAND ${SH_EXE} ${CMAKE_SOURCE_DIR}/GIT-VERSION-GEN
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
+endif()
+
+#Parse GIT-VERSION-FILE to get the version
+file(STRINGS ${CMAKE_SOURCE_DIR}/GIT-VERSION-FILE git_version REGEX "GIT_VERSION = (.*)")
+string(REPLACE "GIT_VERSION = " "" git_version ${git_version})
+string(FIND ${git_version} "GIT" location)
+if(location EQUAL -1)
+ string(REGEX MATCH "[0-9]*\\.[0-9]*\\.[0-9]*" git_version ${git_version})
+else()
+ string(REGEX MATCH "[0-9]*\\.[0-9]*" git_version ${git_version})
+ string(APPEND git_version ".0") #for building from a snapshot
+endif()
+
+project(git
+ VERSION ${git_version}
+ LANGUAGES C)
+
+
+#TODO gitk git-gui gitweb
+#TODO Enable NLS on windows natively
+#TODO Add pcre support
+
+#macros for parsing the Makefile for sources and scripts
+macro(parse_makefile_for_sources list_var regex)
+ file(STRINGS ${CMAKE_SOURCE_DIR}/Makefile ${list_var} REGEX "^${regex} \\+=(.*)")
+ string(REPLACE "${regex} +=" "" ${list_var} ${${list_var}})
+ string(REPLACE "$(COMPAT_OBJS)" "" ${list_var} ${${list_var}}) #remove "$(COMPAT_OBJS)" This is only for libgit.
+ string(STRIP ${${list_var}} ${list_var}) #remove trailing/leading whitespaces
+ string(REPLACE ".o" ".c;" ${list_var} ${${list_var}}) #change .o to .c, ; is for converting the string into a list
+ list(TRANSFORM ${list_var} STRIP) #remove trailing/leading whitespaces for each element in list
+ list(REMOVE_ITEM ${list_var} "") #remove empty list elements
+endmacro()
+
+macro(parse_makefile_for_scripts list_var regex lang)
+ file(STRINGS ${CMAKE_SOURCE_DIR}/Makefile ${list_var} REGEX "^${regex} \\+=(.*)")
+ string(REPLACE "${regex} +=" "" ${list_var} ${${list_var}})
+ string(STRIP ${${list_var}} ${list_var}) #remove trailing/leading whitespaces
+ string(REPLACE " " ";" ${list_var} ${${list_var}}) #convert string to a list
+ if(NOT ${lang}) #exclude for SCRIPT_LIB
+ list(TRANSFORM ${list_var} REPLACE "${lang}" "") #do the replacement
+ endif()
+endmacro()
+
+macro(parse_makefile_for_executables list_var regex)
+ file(STRINGS ${CMAKE_SOURCE_DIR}/Makefile ${list_var} REGEX "^${regex} \\+= git-(.*)")
+ string(REPLACE "${regex} +=" "" ${list_var} ${${list_var}})
+ string(STRIP ${${list_var}} ${list_var}) #remove trailing/leading whitespaces
+ string(REPLACE "git-" "" ${list_var} ${${list_var}}) #strip `git-` prefix
+ string(REPLACE "\$X" ";" ${list_var} ${${list_var}}) #strip $X, ; is for converting the string into a list
+ list(TRANSFORM ${list_var} STRIP) #remove trailing/leading whitespaces for each element in list
+ list(REMOVE_ITEM ${list_var} "") #remove empty list elements
+endmacro()
+
+include(CheckTypeSize)
+include(CheckCSourceRuns)
+include(CheckCSourceCompiles)
+include(CheckIncludeFile)
+include(CheckFunctionExists)
+include(CheckSymbolExists)
+include(CheckStructHasMember)
+include(CTest)
+
+find_package(ZLIB REQUIRED)
+find_package(CURL)
+find_package(EXPAT)
+find_package(Iconv)
+
+#Don't use libintl on Windows Visual Studio and Clang builds
+if(NOT (WIN32 AND (CMAKE_C_COMPILER_ID STREQUAL "MSVC" OR CMAKE_C_COMPILER_ID STREQUAL "Clang")))
+ find_package(Intl)
+endif()
+
+if(NOT Intl_FOUND)
+ add_compile_definitions(NO_GETTEXT)
+ if(NOT Iconv_FOUND)
+ add_compile_definitions(NO_ICONV)
+ endif()
+endif()
+
+include_directories(SYSTEM ${ZLIB_INCLUDE_DIRS})
+if(CURL_FOUND)
+ include_directories(SYSTEM ${CURL_INCLUDE_DIRS})
+endif()
+if(EXPAT_FOUND)
+ include_directories(SYSTEM ${EXPAT_INCLUDE_DIRS})
+endif()
+if(Iconv_FOUND)
+ include_directories(SYSTEM ${Iconv_INCLUDE_DIRS})
+endif()
+if(Intl_FOUND)
+ include_directories(SYSTEM ${Intl_INCLUDE_DIRS})
+endif()
+
+
+if(WIN32 AND NOT MSVC)#not required for visual studio builds
+ find_program(WINDRES_EXE windres)
+ if(NOT WINDRES_EXE)
+ message(FATAL_ERROR "Install windres on Windows for resource files")
+ endif()
+endif()
+
+find_program(MSGFMT_EXE msgfmt)
+if(NOT MSGFMT_EXE)
+ set(MSGFMT_EXE ${CMAKE_SOURCE_DIR}/compat/vcbuild/vcpkg/downloads/tools/msys2/msys64/usr/bin/msgfmt.exe)
+ if(NOT EXISTS ${MSGFMT_EXE})
+ message(WARNING "Text Translations won't be built")
+ unset(MSGFMT_EXE)
+ endif()
+endif()
+
+#Force all visual studio outputs to CMAKE_BINARY_DIR
+if(CMAKE_C_COMPILER_ID STREQUAL "MSVC")
+ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR})
+ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR})
+ add_compile_options(/MP)
+endif()
+
+#default behaviour
+include_directories(${CMAKE_SOURCE_DIR})
+add_compile_definitions(GIT_HOST_CPU="${CMAKE_SYSTEM_PROCESSOR}")
+add_compile_definitions(SHA256_BLK INTERNAL_QSORT RUNTIME_PREFIX)
+add_compile_definitions(NO_OPENSSL SHA1_DC SHA1DC_NO_STANDARD_INCLUDES
+ SHA1DC_INIT_SAFE_HASH_DEFAULT=0
+ SHA1DC_CUSTOM_INCLUDE_SHA1_C="cache.h"
+ SHA1DC_CUSTOM_INCLUDE_UBC_CHECK_C="git-compat-util.h" )
+list(APPEND compat_SOURCES sha1dc_git.c sha1dc/sha1.c sha1dc/ubc_check.c block-sha1/sha1.c sha256/block/sha256.c compat/qsort_s.c)
+
+
+add_compile_definitions(PAGER_ENV="LESS=FRX LV=-c"
+ ETC_GITATTRIBUTES="etc/gitattributes"
+ ETC_GITCONFIG="etc/gitconfig"
+ GIT_EXEC_PATH="libexec/git-core"
+ GIT_LOCALE_PATH="share/locale"
+ GIT_MAN_PATH="share/man"
+ GIT_INFO_PATH="share/info"
+ GIT_HTML_PATH="share/doc/git-doc"
+ DEFAULT_HELP_FORMAT="html"
+ DEFAULT_GIT_TEMPLATE_DIR="share/git-core/templates"
+ GIT_VERSION="${PROJECT_VERSION}.GIT"
+ GIT_USER_AGENT="git/${PROJECT_VERSION}.GIT"
+ BINDIR="bin"
+ GIT_BUILT_FROM_COMMIT="")
+
+if(WIN32)
+ set(FALLBACK_RUNTIME_PREFIX /mingw64)
+ add_compile_definitions(FALLBACK_RUNTIME_PREFIX="${FALLBACK_RUNTIME_PREFIX}")
+else()
+ set(FALLBACK_RUNTIME_PREFIX /home/$ENV{USER})
+ add_compile_definitions(FALLBACK_RUNTIME_PREFIX="${FALLBACK_RUNTIME_PREFIX}")
+endif()
+
+
+#Platform Specific
+if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
+ if(CMAKE_C_COMPILER_ID STREQUAL "MSVC" OR CMAKE_C_COMPILER_ID STREQUAL "Clang")
+ include_directories(${CMAKE_SOURCE_DIR}/compat/vcbuild/include)
+ add_compile_definitions(_CRT_SECURE_NO_WARNINGS _CRT_NONSTDC_NO_DEPRECATE)
+ endif()
+ include_directories(${CMAKE_SOURCE_DIR}/compat/win32)
+ add_compile_definitions(HAVE_ALLOCA_H NO_POSIX_GOODIES NATIVE_CRLF NO_UNIX_SOCKETS WIN32
+ _CONSOLE DETECT_MSYS_TTY STRIP_EXTENSION=".exe" NO_SYMLINK_HEAD UNRELIABLE_FSTAT
+ NOGDI OBJECT_CREATION_MODE=1 __USE_MINGW_ANSI_STDIO=0
+ USE_NED_ALLOCATOR OVERRIDE_STRDUP MMAP_PREVENTS_DELETE USE_WIN32_MMAP
+ UNICODE _UNICODE HAVE_WPGMPTR ENSURE_MSYSTEM_IS_SET)
+ list(APPEND compat_SOURCES compat/mingw.c compat/winansi.c compat/win32/path-utils.c
+ compat/win32/pthread.c compat/win32mmap.c compat/win32/syslog.c
+ compat/win32/trace2_win32_process_info.c compat/win32/dirent.c
+ compat/nedmalloc/nedmalloc.c compat/strdup.c)
+ set(NO_UNIX_SOCKETS 1)
+
+elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
+ add_compile_definitions(PROCFS_EXECUTABLE_PATH="/proc/self/exe" HAVE_DEV_TTY )
+ list(APPEND compat_SOURCES unix-socket.c)
+endif()
+
+set(EXE_EXTENSION ${CMAKE_EXECUTABLE_SUFFIX})
+
+#header checks
+check_include_file(libgen.h HAVE_LIBGEN_H)
+if(NOT HAVE_LIBGEN_H)
+ add_compile_definitions(NO_LIBGEN_H)
+ list(APPEND compat_SOURCES compat/basename.c)
+endif()
+
+check_include_file(sys/sysinfo.h HAVE_SYSINFO)
+if(HAVE_SYSINFO)
+ add_compile_definitions(HAVE_SYSINFO)
+endif()
+
+check_c_source_compiles("
+#include <alloca.h>
+
+int main(void)
+{
+ char *p = (char *) alloca(2 * sizeof(int));
+
+ if (p)
+ return 0;
+ return 0;
+}"
+HAVE_ALLOCA_H)
+if(HAVE_ALLOCA_H)
+ add_compile_definitions(HAVE_ALLOCA_H)
+endif()
+
+check_include_file(strings.h HAVE_STRINGS_H)
+if(HAVE_STRINGS_H)
+ add_compile_definitions(HAVE_STRINGS_H)
+endif()
+
+check_include_file(sys/select.h HAVE_SYS_SELECT_H)
+if(NOT HAVE_SYS_SELECT_H)
+ add_compile_definitions(NO_SYS_SELECT_H)
+endif()
+
+check_include_file(sys/poll.h HAVE_SYS_POLL_H)
+if(NOT HAVE_SYS_POLL_H)
+ add_compile_definitions(NO_SYS_POLL_H)
+endif()
+
+check_include_file(poll.h HAVE_POLL_H)
+if(NOT HAVE_POLL_H)
+ add_compile_definitions(NO_POLL_H)
+endif()
+
+check_include_file(inttypes.h HAVE_INTTYPES_H)
+if(NOT HAVE_INTTYPES_H)
+ add_compile_definitions(NO_INTTYPES_H)
+endif()
+
+check_include_file(paths.h HAVE_PATHS_H)
+if(HAVE_PATHS_H)
+ add_compile_definitions(HAVE_PATHS_H)
+endif()
+
+#function checks
+set(function_checks
+ strcasestr memmem strlcpy strtoimax strtoumax strtoull
+ setenv mkdtemp poll pread memmem)
+
+#unsetenv,hstrerror are incompatible with windows build
+if(NOT WIN32)
+ list(APPEND function_checks unsetenv hstrerror)
+endif()
+
+foreach(f ${function_checks})
+ string(TOUPPER ${f} uf)
+ check_function_exists(${f} HAVE_${uf})
+ if(NOT HAVE_${uf})
+ add_compile_definitions(NO_${uf})
+ endif()
+endforeach()
+
+if(NOT HAVE_POLL_H OR NOT HAVE_SYS_POLL_H OR NOT HAVE_POLL)
+ include_directories(${CMAKE_SOURCE_DIR}/compat/poll)
+ add_compile_definitions(NO_POLL)
+ list(APPEND compat_SOURCES compat/poll/poll.c)
+endif()
+
+if(NOT HAVE_STRCASESTR)
+ list(APPEND compat_SOURCES compat/strcasestr.c)
+endif()
+
+if(NOT HAVE_STRLCPY)
+ list(APPEND compat_SOURCES compat/strlcpy.c)
+endif()
+
+if(NOT HAVE_STRTOUMAX)
+ list(APPEND compat_SOURCES compat/strtoumax.c compat/strtoimax.c)
+endif()
+
+if(NOT HAVE_SETENV)
+ list(APPEND compat_SOURCES compat/setenv.c)
+endif()
+
+if(NOT HAVE_MKDTEMP)
+ list(APPEND compat_SOURCES compat/mkdtemp.c)
+endif()
+
+if(NOT HAVE_PREAD)
+ list(APPEND compat_SOURCES compat/pread.c)
+endif()
+
+if(NOT HAVE_MEMMEM)
+ list(APPEND compat_SOURCES compat/memmem.c)
+endif()
+
+if(NOT WIN32)
+ if(NOT HAVE_UNSETENV)
+ list(APPEND compat_SOURCES compat/unsetenv.c)
+ endif()
+
+ if(NOT HAVE_HSTRERROR)
+ list(APPEND compat_SOURCES compat/hstrerror.c)
+ endif()
+endif()
+
+check_function_exists(getdelim HAVE_GETDELIM)
+if(HAVE_GETDELIM)
+ add_compile_definitions(HAVE_GETDELIM)
+endif()
+
+check_function_exists(clock_gettime HAVE_CLOCK_GETTIME)
+check_symbol_exists(CLOCK_MONOTONIC "time.h" HAVE_CLOCK_MONOTONIC)
+if(HAVE_CLOCK_GETTIME)
+ add_compile_definitions(HAVE_CLOCK_GETTIME)
+endif()
+if(HAVE_CLOCK_MONOTONIC)
+ add_compile_definitions(HAVE_CLOCK_MONOTONIC)
+endif()
+
+#check for st_blocks in struct stat
+check_struct_has_member("struct stat" st_blocks "sys/stat.h" STRUCT_STAT_HAS_ST_BLOCKS)
+if(NOT STRUCT_STAT_HAS_ST_BLOCKS)
+ add_compile_definitions(NO_ST_BLOCKS_IN_STRUCT_STAT)
+endif()
+
+#compile checks
+check_c_source_runs("
+#include<stdio.h>
+#include<stdarg.h>
+#include<string.h>
+#include<stdlib.h>
+
+int test_vsnprintf(char *str, size_t maxsize, const char *format, ...)
+{
+ int ret;
+ va_list ap;
+
+ va_start(ap, format);
+ ret = vsnprintf(str, maxsize, format, ap);
+ va_end(ap);
+ return ret;
+}
+
+int main(void)
+{
+ char buf[6];
+
+ if (test_vsnprintf(buf, 3, \"%s\", \"12345\") != 5
+ || strcmp(buf, \"12\"))
+ return 1;
+ if (snprintf(buf, 3, \"%s\", \"12345\") != 5
+ || strcmp(buf, \"12\"))
+ return 1;
+ return 0;
+}"
+SNPRINTF_OK)
+if(NOT SNPRINTF_OK)
+ add_compile_definitions(SNPRINTF_RETURNS_BOGUS)
+ list(APPEND compat_SOURCES compat/snprintf.c)
+endif()
+
+check_c_source_runs("
+#include<stdio.h>
+
+int main(void)
+{
+ FILE *f = fopen(\".\", \"r\");
+
+ return f != NULL;
+}"
+FREAD_READS_DIRECTORIES_NO)
+if(NOT FREAD_READS_DIRECTORIES_NO)
+ add_compile_definitions(FREAD_READS_DIRECTORIES)
+ list(APPEND compat_SOURCES compat/fopen.c)
+endif()
+
+check_c_source_compiles("
+#include <regex.h>
+#ifndef REG_STARTEND
+#error oops we dont have it
+#endif
+
+int main(void)
+{
+ return 0;
+}"
+HAVE_REGEX)
+if(NOT HAVE_REGEX)
+ include_directories(${CMAKE_SOURCE_DIR}/compat/regex)
+ list(APPEND compat_SOURCES compat/regex/regex.c )
+ add_compile_definitions(NO_REGEX NO_MBSUPPORT GAWK)
+endif()
+
+
+check_c_source_compiles("
+#include <stddef.h>
+#include <sys/types.h>
+#include <sys/sysctl.h>
+
+int main(void)
+{
+ int val, mib[2];
+ size_t len;
+
+ mib[0] = CTL_HW;
+ mib[1] = 1;
+ len = sizeof(val);
+ return sysctl(mib, 2, &val, &len, NULL, 0) ? 1 : 0;
+}"
+HAVE_BSD_SYSCTL)
+if(HAVE_BSD_SYSCTL)
+ add_compile_definitions(HAVE_BSD_SYSCTL)
+endif()
+
+set(CMAKE_REQUIRED_LIBRARIES ${Iconv_LIBRARIES})
+set(CMAKE_REQUIRED_INCLUDES ${Iconv_INCLUDE_DIRS})
+
+check_c_source_compiles("
+#include <iconv.h>
+
+extern size_t iconv(iconv_t cd,
+ char **inbuf, size_t *inbytesleft,
+ char **outbuf, size_t *outbytesleft);
+
+int main(void)
+{
+ return 0;
+}"
+HAVE_NEW_ICONV)
+if(HAVE_NEW_ICONV)
+ set(HAVE_OLD_ICONV 0)
+else()
+ set(HAVE_OLD_ICONV 1)
+endif()
+
+check_c_source_runs("
+#include <iconv.h>
+#if ${HAVE_OLD_ICONV}
+typedef const char *iconv_ibp;
+#else
+typedef char *iconv_ibp;
+#endif
+
+int main(void)
+{
+ int v;
+ iconv_t conv;
+ char in[] = \"a\";
+ iconv_ibp pin = in;
+ char out[20] = \"\";
+ char *pout = out;
+ size_t isz = sizeof(in);
+ size_t osz = sizeof(out);
+
+ conv = iconv_open(\"UTF-16\", \"UTF-8\");
+ iconv(conv, &pin, &isz, &pout, &osz);
+ iconv_close(conv);
+ v = (unsigned char)(out[0]) + (unsigned char)(out[1]);
+ return v != 0xfe + 0xff;
+}"
+ICONV_DOESNOT_OMIT_BOM)
+if(NOT ICONV_DOESNOT_OMIT_BOM)
+ add_compile_definitions(ICONV_OMITS_BOM)
+endif()
+
+unset(CMAKE_REQUIRED_LIBRARIES)
+unset(CMAKE_REQUIRED_INCLUDES)
+
+
+#programs
+set(PROGRAMS_BUILT
+ git git-daemon git-http-backend git-sh-i18n--envsubst
+ git-shell)
+
+if(NOT CURL_FOUND)
+ list(APPEND excluded_progs git-http-fetch git-http-push)
+ add_compile_definitions(NO_CURL)
+ message(WARNING "git-http-push and git-http-fetch will not be built")
+else()
+ list(APPEND PROGRAMS_BUILT git-http-fetch git-http-push git-imap-send git-remote-http)
+ if(CURL_VERSION_STRING VERSION_GREATER_EQUAL 7.34.0)
+ add_compile_definitions(USE_CURL_FOR_IMAP_SEND)
+ endif()
+endif()
+
+if(NOT EXPAT_FOUND)
+ list(APPEND excluded_progs git-http-push)
+ add_compile_definitions(NO_EXPAT)
+else()
+ list(APPEND PROGRAMS_BUILT git-http-push)
+ if(EXPAT_VERSION_STRING VERSION_LESS_EQUAL 1.2)
+ add_compile_definitions(EXPAT_NEEDS_XMLPARSE_H)
+ endif()
+endif()
+
+list(REMOVE_DUPLICATES excluded_progs)
+list(REMOVE_DUPLICATES PROGRAMS_BUILT)
+
+
+foreach(p ${excluded_progs})
+ list(APPEND EXCLUSION_PROGS --exclude-program ${p} )
+endforeach()
+
+#for comparing null values
+list(APPEND EXCLUSION_PROGS empty)
+set(EXCLUSION_PROGS_CACHE ${EXCLUSION_PROGS} CACHE STRING "Programs not built" FORCE)
+
+if(NOT EXISTS ${CMAKE_BINARY_DIR}/command-list.h OR NOT EXCLUSION_PROGS_CACHE STREQUAL EXCLUSION_PROGS)
+ list(REMOVE_ITEM EXCLUSION_PROGS empty)
+ message("Generating command-list.h")
+ execute_process(COMMAND ${SH_EXE} ${CMAKE_SOURCE_DIR}/generate-cmdlist.sh ${EXCLUSION_PROGS} command-list.txt
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+ OUTPUT_FILE ${CMAKE_BINARY_DIR}/command-list.h)
+endif()
+
+if(NOT EXISTS ${CMAKE_BINARY_DIR}/config-list.h)
+ message("Generating config-list.h")
+ execute_process(COMMAND ${SH_EXE} ${CMAKE_SOURCE_DIR}/generate-configlist.sh
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+ OUTPUT_FILE ${CMAKE_BINARY_DIR}/config-list.h)
+endif()
+
+include_directories(${CMAKE_BINARY_DIR})
+
+#build
+#libgit
+parse_makefile_for_sources(libgit_SOURCES "LIB_OBJS")
+
+list(TRANSFORM libgit_SOURCES PREPEND "${CMAKE_SOURCE_DIR}/")
+list(TRANSFORM compat_SOURCES PREPEND "${CMAKE_SOURCE_DIR}/")
+add_library(libgit ${libgit_SOURCES} ${compat_SOURCES})
+
+#libxdiff
+parse_makefile_for_sources(libxdiff_SOURCES "XDIFF_OBJS")
+
+list(TRANSFORM libxdiff_SOURCES PREPEND "${CMAKE_SOURCE_DIR}/")
+add_library(xdiff STATIC ${libxdiff_SOURCES})
+
+if(WIN32)
+ if(NOT MSVC)#use windres when compiling with gcc and clang
+ add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/git.res
+ COMMAND ${WINDRES_EXE} -O coff -DMAJOR=${PROJECT_VERSION_MAJOR} -DMINOR=${PROJECT_VERSION_MINOR}
+ -DMICRO=${PROJECT_VERSION_PATCH} -DPATCHLEVEL=0 -DGIT_VERSION="\\\"${PROJECT_VERSION}.GIT\\\""
+ -i ${CMAKE_SOURCE_DIR}/git.rc -o ${CMAKE_BINARY_DIR}/git.res
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+ VERBATIM)
+ else()#MSVC use rc
+ add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/git.res
+ COMMAND ${CMAKE_RC_COMPILER} /d MAJOR=${PROJECT_VERSION_MAJOR} /d MINOR=${PROJECT_VERSION_MINOR}
+ /d MICRO=${PROJECT_VERSION_PATCH} /d PATCHLEVEL=0 /d GIT_VERSION="${PROJECT_VERSION}.GIT"
+ /fo ${CMAKE_BINARY_DIR}/git.res ${CMAKE_SOURCE_DIR}/git.rc
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+ VERBATIM)
+ endif()
+ add_custom_target(git-rc DEPENDS ${CMAKE_BINARY_DIR}/git.res)
+endif()
+
+#link all required libraries to common-main
+add_library(common-main OBJECT ${CMAKE_SOURCE_DIR}/common-main.c)
+
+target_link_libraries(common-main libgit xdiff ${ZLIB_LIBRARIES})
+if(Intl_FOUND)
+ target_link_libraries(common-main ${Intl_LIBRARIES})
+endif()
+if(Iconv_FOUND)
+ target_link_libraries(common-main ${Iconv_LIBRARIES})
+endif()
+if(WIN32)
+ target_link_libraries(common-main ws2_32 ntdll ${CMAKE_BINARY_DIR}/git.res)
+ add_dependencies(common-main git-rc)
+ if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
+ target_link_options(common-main PUBLIC -municode -Wl,--nxcompat -Wl,--dynamicbase -Wl,--pic-executable,-e,mainCRTStartup)
+ elseif(CMAKE_C_COMPILER_ID STREQUAL "Clang")
+ target_link_options(common-main PUBLIC -municode -Wl,-nxcompat -Wl,-dynamicbase -Wl,-entry:wmainCRTStartup -Wl,invalidcontinue.obj)
+ elseif(CMAKE_C_COMPILER_ID STREQUAL "MSVC")
+ target_link_options(common-main PUBLIC /IGNORE:4217 /IGNORE:4049 /NOLOGO /ENTRY:wmainCRTStartup /SUBSYSTEM:CONSOLE invalidcontinue.obj)
+ else()
+ message(FATAL_ERROR "Unhandled compiler: ${CMAKE_C_COMPILER_ID}")
+ endif()
+elseif(UNIX)
+ target_link_libraries(common-main pthread rt)
+endif()
+
+#git
+parse_makefile_for_sources(git_SOURCES "BUILTIN_OBJS")
+
+list(TRANSFORM git_SOURCES PREPEND "${CMAKE_SOURCE_DIR}/")
+add_executable(git ${CMAKE_SOURCE_DIR}/git.c ${git_SOURCES})
+target_link_libraries(git common-main)
+
+add_executable(git-daemon ${CMAKE_SOURCE_DIR}/daemon.c)
+target_link_libraries(git-daemon common-main)
+
+add_executable(git-http-backend ${CMAKE_SOURCE_DIR}/http-backend.c)
+target_link_libraries(git-http-backend common-main)
+
+add_executable(git-sh-i18n--envsubst ${CMAKE_SOURCE_DIR}/sh-i18n--envsubst.c)
+target_link_libraries(git-sh-i18n--envsubst common-main)
+
+add_executable(git-shell ${CMAKE_SOURCE_DIR}/shell.c)
+target_link_libraries(git-shell common-main)
+
+if(CURL_FOUND)
+ add_library(http_obj OBJECT ${CMAKE_SOURCE_DIR}/http.c)
+
+ add_executable(git-imap-send ${CMAKE_SOURCE_DIR}/imap-send.c)
+ target_link_libraries(git-imap-send http_obj common-main ${CURL_LIBRARIES})
+
+ add_executable(git-http-fetch ${CMAKE_SOURCE_DIR}/http-walker.c ${CMAKE_SOURCE_DIR}/http-fetch.c)
+ target_link_libraries(git-http-fetch http_obj common-main ${CURL_LIBRARIES})
+
+ add_executable(git-remote-http ${CMAKE_SOURCE_DIR}/http-walker.c ${CMAKE_SOURCE_DIR}/remote-curl.c)
+ target_link_libraries(git-remote-http http_obj common-main ${CURL_LIBRARIES} )
+
+ if(EXPAT_FOUND)
+ add_executable(git-http-push ${CMAKE_SOURCE_DIR}/http-push.c)
+ target_link_libraries(git-http-push http_obj common-main ${CURL_LIBRARIES} ${EXPAT_LIBRARIES})
+ endif()
+endif()
+
+parse_makefile_for_executables(git_builtin_extra "BUILT_INS")
+
+#Creating hardlinks
+foreach(s ${git_SOURCES} ${git_builtin_extra})
+ string(REPLACE "${CMAKE_SOURCE_DIR}/builtin/" "" s ${s})
+ string(REPLACE ".c" "" s ${s})
+ file(APPEND ${CMAKE_BINARY_DIR}/CreateLinks.cmake "file(CREATE_LINK git${EXE_EXTENSION} git-${s}${EXE_EXTENSION})\n")
+ list(APPEND git_links ${CMAKE_BINARY_DIR}/git-${s}${EXE_EXTENSION})
+endforeach()
+
+if(CURL_FOUND)
+ set(remote_exes
+ git-remote-https git-remote-ftp git-remote-ftps)
+ foreach(s ${remote_exes})
+ file(APPEND ${CMAKE_BINARY_DIR}/CreateLinks.cmake "file(CREATE_LINK git-remote-http${EXE_EXTENSION} ${s}${EXE_EXTENSION})\n")
+ list(APPEND git_http_links ${CMAKE_BINARY_DIR}/${s}${EXE_EXTENSION})
+ endforeach()
+endif()
+
+add_custom_command(OUTPUT ${git_links} ${git_http_links}
+ COMMAND ${CMAKE_COMMAND} -P ${CMAKE_BINARY_DIR}/CreateLinks.cmake
+ DEPENDS git git-remote-http)
+add_custom_target(git-links ALL DEPENDS ${git_links} ${git_http_links})
+
+
+#creating required scripts
+set(SHELL_PATH /bin/sh)
+set(PERL_PATH /usr/bin/perl)
+set(LOCALEDIR ${FALLBACK_RUNTIME_PREFIX}/share/locale)
+set(GITWEBDIR ${FALLBACK_RUNTIME_PREFIX}/share/locale)
+set(INSTLIBDIR ${FALLBACK_RUNTIME_PREFIX}/share/perl5)
+
+#shell scripts
+parse_makefile_for_scripts(git_sh_scripts "SCRIPT_SH" ".sh")
+parse_makefile_for_scripts(git_shlib_scripts "SCRIPT_LIB" "")
+set(git_shell_scripts
+ ${git_sh_scripts} ${git_shlib_scripts} git-instaweb)
+
+foreach(script ${git_shell_scripts})
+ file(STRINGS ${CMAKE_SOURCE_DIR}/${script}.sh content NEWLINE_CONSUME)
+ string(REPLACE "@SHELL_PATH@" "${SHELL_PATH}" content "${content}")
+ string(REPLACE "@@DIFF@@" "diff" content "${content}")
+ string(REPLACE "@LOCALEDIR@" "${LOCALEDIR}" content "${content}")
+ string(REPLACE "@GITWEBDIR@" "${GITWEBDIR}" content "${content}")
+ string(REPLACE "@@NO_CURL@@" "" content "${content}")
+ string(REPLACE "@@USE_GETTEXT_SCHEME@@" "" content "${content}")
+ string(REPLACE "# @@BROKEN_PATH_FIX@@" "" content "${content}")
+ string(REPLACE "@@PERL@@" "${PERL_PATH}" content "${content}")
+ string(REPLACE "@@SANE_TEXT_GREP@@" "-a" content "${content}")
+ string(REPLACE "@@PAGER_ENV@@" "LESS=FRX LV=-c" content "${content}")
+ file(WRITE ${CMAKE_BINARY_DIR}/${script} ${content})
+endforeach()
+
+#perl scripts
+parse_makefile_for_scripts(git_perl_scripts "SCRIPT_PERL" ".perl")
+
+#create perl header
+file(STRINGS ${CMAKE_SOURCE_DIR}/perl/header_templates/fixed_prefix.template.pl perl_header )
+string(REPLACE "@@PATHSEP@@" ":" perl_header "${perl_header}")
+string(REPLACE "@@INSTLIBDIR@@" "${INSTLIBDIR}" perl_header "${perl_header}")
+
+foreach(script ${git_perl_scripts})
+ file(STRINGS ${CMAKE_SOURCE_DIR}/${script}.perl content NEWLINE_CONSUME)
+ string(REPLACE "#!/usr/bin/perl" "#!/usr/bin/perl\n${perl_header}\n" content "${content}")
+ string(REPLACE "@@GIT_VERSION@@" "${PROJECT_VERSION}" content "${content}")
+ file(WRITE ${CMAKE_BINARY_DIR}/${script} ${content})
+endforeach()
+
+#python script
+file(STRINGS ${CMAKE_SOURCE_DIR}/git-p4.py content NEWLINE_CONSUME)
+string(REPLACE "#!/usr/bin/env python" "#!/usr/bin/python" content "${content}")
+file(WRITE ${CMAKE_BINARY_DIR}/git-p4 ${content})
+
+#perl modules
+file(GLOB_RECURSE perl_modules "${CMAKE_SOURCE_DIR}/perl/*.pm")
+
+foreach(pm ${perl_modules})
+ string(REPLACE "${CMAKE_SOURCE_DIR}/perl/" "" file_path ${pm})
+ file(STRINGS ${pm} content NEWLINE_CONSUME)
+ string(REPLACE "@@LOCALEDIR@@" "${LOCALEDIR}" content "${content}")
+ string(REPLACE "@@NO_PERL_CPAN_FALLBACKS@@" "" content "${content}")
+ file(WRITE ${CMAKE_BINARY_DIR}/perl/build/lib/${file_path} ${content})
+#test-lib.sh requires perl/build/lib to be the build directory of perl modules
+endforeach()
+
+
+#templates
+file(GLOB templates "${CMAKE_SOURCE_DIR}/templates/*")
+list(TRANSFORM templates REPLACE "${CMAKE_SOURCE_DIR}/templates/" "")
+list(REMOVE_ITEM templates ".gitignore")
+list(REMOVE_ITEM templates "Makefile")
+list(REMOVE_ITEM templates "blt")# Prevents an error when reconfiguring for in source builds
+
+list(REMOVE_ITEM templates "branches--")
+file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/templates/blt/branches) #create branches
+
+#templates have @.*@ replacement so use configure_file instead
+foreach(tm ${templates})
+ string(REPLACE "--" "/" blt_tm ${tm})
+ string(REPLACE "this" "" blt_tm ${blt_tm})# for this--
+ configure_file(${CMAKE_SOURCE_DIR}/templates/${tm} ${CMAKE_BINARY_DIR}/templates/blt/${blt_tm} @ONLY)
+endforeach()
+
+
+#translations
+if(MSGFMT_EXE)
+ file(GLOB po_files "${CMAKE_SOURCE_DIR}/po/*.po")
+ list(TRANSFORM po_files REPLACE "${CMAKE_SOURCE_DIR}/po/" "")
+ list(TRANSFORM po_files REPLACE ".po" "")
+ foreach(po ${po_files})
+ file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/po/build/locale/${po}/LC_MESSAGES)
+ add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/po/build/locale/${po}/LC_MESSAGES/git.mo
+ COMMAND ${MSGFMT_EXE} --check --statistics -o ${CMAKE_BINARY_DIR}/po/build/locale/${po}/LC_MESSAGES/git.mo ${CMAKE_SOURCE_DIR}/po/${po}.po)
+ list(APPEND po_gen ${CMAKE_BINARY_DIR}/po/build/locale/${po}/LC_MESSAGES/git.mo)
+ endforeach()
+ add_custom_target(po-gen ALL DEPENDS ${po_gen})
+endif()
+
+
+#to help with the install
+list(TRANSFORM git_shell_scripts PREPEND "${CMAKE_BINARY_DIR}/")
+list(TRANSFORM git_perl_scripts PREPEND "${CMAKE_BINARY_DIR}/")
+
+#install
+install(TARGETS git git-shell
+ RUNTIME DESTINATION bin)
+install(PROGRAMS ${CMAKE_BINARY_DIR}/git-cvsserver
+ DESTINATION bin)
+
+list(REMOVE_ITEM PROGRAMS_BUILT git git-shell)
+install(TARGETS ${PROGRAMS_BUILT}
+ RUNTIME DESTINATION libexec/git-core)
+
+set(bin_links
+ git-receive-pack git-upload-archive git-upload-pack)
+
+foreach(b ${bin_links})
+install(CODE "file(CREATE_LINK ${CMAKE_INSTALL_PREFIX}/bin/git${EXE_EXTENSION} ${CMAKE_INSTALL_PREFIX}/bin/${b}${EXE_EXTENSION})")
+endforeach()
+
+install(CODE "file(CREATE_LINK ${CMAKE_INSTALL_PREFIX}/bin/git${EXE_EXTENSION} ${CMAKE_INSTALL_PREFIX}/libexec/git-core/git${EXE_EXTENSION})")
+install(CODE "file(CREATE_LINK ${CMAKE_INSTALL_PREFIX}/bin/git-shell${EXE_EXTENSION} ${CMAKE_INSTALL_PREFIX}/libexec/git-core/git-shell${EXE_EXTENSION})")
+
+foreach(b ${git_links})
+ string(REPLACE "${CMAKE_BINARY_DIR}" "" b ${b})
+ install(CODE "file(CREATE_LINK ${CMAKE_INSTALL_PREFIX}/bin/git${EXE_EXTENSION} ${CMAKE_INSTALL_PREFIX}/libexec/git-core/${b}${EXE_EXTENSION})")
+endforeach()
+
+foreach(b ${git_http_links})
+ string(REPLACE "${CMAKE_BINARY_DIR}" "" b ${b})
+ install(CODE "file(CREATE_LINK ${CMAKE_INSTALL_PREFIX}/libexec/git-core/git-remote-http${EXE_EXTENSION} ${CMAKE_INSTALL_PREFIX}/libexec/git-core/${b}${EXE_EXTENSION})")
+endforeach()
+
+install(PROGRAMS ${git_shell_scripts} ${git_perl_scripts} ${CMAKE_BINARY_DIR}/git-p4
+ DESTINATION libexec/git-core)
+
+install(DIRECTORY ${CMAKE_SOURCE_DIR}/mergetools DESTINATION libexec/git-core)
+install(DIRECTORY ${CMAKE_BINARY_DIR}/perl/build/lib/ DESTINATION share/perl5
+ FILES_MATCHING PATTERN "*.pm")
+install(DIRECTORY ${CMAKE_BINARY_DIR}/templates/blt/ DESTINATION share/git-core/templates)
+
+if(MSGFMT_EXE)
+ install(DIRECTORY ${CMAKE_BINARY_DIR}/po/build/locale DESTINATION share)
+endif()
+
+
+if(BUILD_TESTING)
+
+#tests-helpers
+add_executable(test-fake-ssh ${CMAKE_SOURCE_DIR}/t/helper/test-fake-ssh.c)
+target_link_libraries(test-fake-ssh common-main)
+
+#test-tool
+parse_makefile_for_sources(test-tool_SOURCES "TEST_BUILTINS_OBJS")
+
+list(TRANSFORM test-tool_SOURCES PREPEND "${CMAKE_SOURCE_DIR}/t/helper/")
+add_executable(test-tool ${CMAKE_SOURCE_DIR}/t/helper/test-tool.c ${test-tool_SOURCES})
+target_link_libraries(test-tool common-main)
+
+set_target_properties(test-fake-ssh test-tool
+ PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/t/helper)
+
+if(MSVC)
+ set_target_properties(test-fake-ssh test-tool
+ PROPERTIES RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/t/helper)
+ set_target_properties(test-fake-ssh test-tool
+ PROPERTIES RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/t/helper)
+endif()
+
+#wrapper scripts
+set(wrapper_scripts
+ git git-upload-pack git-receive-pack git-upload-archive git-shell git-remote-ext)
+
+set(wrapper_test_scripts
+ test-fake-ssh test-tool)
+
+
+foreach(script ${wrapper_scripts})
+ file(STRINGS ${CMAKE_SOURCE_DIR}/wrap-for-bin.sh content NEWLINE_CONSUME)
+ string(REPLACE "@@BUILD_DIR@@" "${CMAKE_BINARY_DIR}" content "${content}")
+ string(REPLACE "@@PROG@@" "${script}${EXE_EXTENSION}" content "${content}")
+ file(WRITE ${CMAKE_BINARY_DIR}/bin-wrappers/${script} ${content})
+endforeach()
+
+foreach(script ${wrapper_test_scripts})
+ file(STRINGS ${CMAKE_SOURCE_DIR}/wrap-for-bin.sh content NEWLINE_CONSUME)
+ string(REPLACE "@@BUILD_DIR@@" "${CMAKE_BINARY_DIR}" content "${content}")
+ string(REPLACE "@@PROG@@" "t/helper/${script}${EXE_EXTENSION}" content "${content}")
+ file(WRITE ${CMAKE_BINARY_DIR}/bin-wrappers/${script} ${content})
+endforeach()
+
+file(STRINGS ${CMAKE_SOURCE_DIR}/wrap-for-bin.sh content NEWLINE_CONSUME)
+string(REPLACE "@@BUILD_DIR@@" "${CMAKE_BINARY_DIR}" content "${content}")
+string(REPLACE "@@PROG@@" "git-cvsserver" content "${content}")
+file(WRITE ${CMAKE_BINARY_DIR}/bin-wrappers/git-cvsserver ${content})
+
+#options for configuring test options
+option(PERL_TESTS "Perform tests that use perl" ON)
+option(PYTHON_TESTS "Perform tests that use python" ON)
+
+#GIT-BUILD-OPTIONS
+set(TEST_SHELL_PATH ${SHELL_PATH})
+set(DIFF diff)
+set(PYTHON_PATH /usr/bin/python)
+set(TAR tar)
+set(NO_CURL )
+set(NO_EXPAT )
+set(USE_LIBPCRE2 )
+set(NO_PERL )
+set(NO_PTHREADS )
+set(NO_PYTHON )
+set(PAGER_ENV "LESS=FRX LV=-c")
+set(DC_SHA1 YesPlease)
+set(RUNTIME_PREFIX true)
+set(NO_GETTEXT )
+
+if(NOT CURL_FOUND)
+ set(NO_CURL 1)
+endif()
+
+if(NOT EXPAT_FOUND)
+ set(NO_EXPAT 1)
+endif()
+
+if(NOT Intl_FOUND)
+ set(NO_GETTEXT 1)
+endif()
+
+if(NOT PERL_TESTS)
+ set(NO_PERL 1)
+endif()
+
+if(NOT PYTHON_TESTS)
+ set(NO_PYTHON 1)
+endif()
+
+file(WRITE ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "SHELL_PATH='${SHELL_PATH}'\n")
+file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "TEST_SHELL_PATH='${TEST_SHELL_PATH}'\n")
+file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "PERL_PATH='${PERL_PATH}'\n")
+file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "DIFF='${DIFF}'\n")
+file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "PYTHON_PATH='${PYTHON_PATH}'\n")
+file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "TAR='${TAR}'\n")
+file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "NO_CURL='${NO_CURL}'\n")
+file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "NO_EXPAT='${NO_EXPAT}'\n")
+file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "NO_PERL='${NO_PERL}'\n")
+file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "NO_PTHREADS='${NO_PTHREADS}'\n")
+file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "NO_UNIX_SOCKETS='${NO_UNIX_SOCKETS}'\n")
+file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "PAGER_ENV='${PAGER_ENV}'\n")
+file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "DC_SHA1='${DC_SHA1}'\n")
+file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "X='${EXE_EXTENSION}'\n")
+file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "NO_GETTEXT='${NO_GETTEXT}'\n")
+file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "RUNTIME_PREFIX='${RUNTIME_PREFIX}'\n")
+file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "NO_PYTHON='${NO_PYTHON}'\n")
+if(WIN32)
+ file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "PATH=\"$PATH:$TEST_DIRECTORY/../compat/vcbuild/vcpkg/installed/x64-windows/bin\"\n")
+endif()
+
+#Make the tests work when building out of the source tree
+get_filename_component(CACHE_PATH ${CMAKE_CURRENT_LIST_DIR}/../../CMakeCache.txt ABSOLUTE)
+if(NOT ${CMAKE_BINARY_DIR}/CMakeCache.txt STREQUAL ${CACHE_PATH})
+ file(RELATIVE_PATH BUILD_DIR_RELATIVE ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR}/CMakeCache.txt)
+ string(REPLACE "/CMakeCache.txt" "" BUILD_DIR_RELATIVE ${BUILD_DIR_RELATIVE})
+ #Setting the build directory in test-lib.sh before running tests
+ file(WRITE ${CMAKE_BINARY_DIR}/CTestCustom.cmake
+ "file(STRINGS ${CMAKE_SOURCE_DIR}/t/test-lib.sh GIT_BUILD_DIR_REPL REGEX \"GIT_BUILD_DIR=(.*)\")\n"
+ "file(STRINGS ${CMAKE_SOURCE_DIR}/t/test-lib.sh content NEWLINE_CONSUME)\n"
+ "string(REPLACE \"\${GIT_BUILD_DIR_REPL}\" \"GIT_BUILD_DIR=\\\"$TEST_DIRECTORY/../${BUILD_DIR_RELATIVE}\\\"\" content \"\${content}\")\n"
+ "file(WRITE ${CMAKE_SOURCE_DIR}/t/test-lib.sh \${content})")
+ #misc copies
+ file(COPY ${CMAKE_SOURCE_DIR}/t/chainlint.sed DESTINATION ${CMAKE_BINARY_DIR}/t/)
+ file(COPY ${CMAKE_SOURCE_DIR}/po/is.po DESTINATION ${CMAKE_BINARY_DIR}/po/)
+ file(COPY ${CMAKE_SOURCE_DIR}/mergetools/tkdiff DESTINATION ${CMAKE_BINARY_DIR}/mergetools/)
+ file(COPY ${CMAKE_SOURCE_DIR}/contrib/completion/git-prompt.sh DESTINATION ${CMAKE_BINARY_DIR}/contrib/completion/)
+ file(COPY ${CMAKE_SOURCE_DIR}/contrib/completion/git-completion.bash DESTINATION ${CMAKE_BINARY_DIR}/contrib/completion/)
+endif()
+
+file(GLOB test_scipts "${CMAKE_SOURCE_DIR}/t/t[0-9]*.sh")
+
+#test
+foreach(tsh ${test_scipts})
+ add_test(NAME ${tsh}
+ COMMAND ${SH_EXE} ${tsh}
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/t)
+endforeach()
+
+endif()#BUILD_TESTING
diff --git a/contrib/buildsystems/Generators/Vcxproj.pm b/contrib/buildsystems/Generators/Vcxproj.pm
index 5c666f9ac0..d2584450ba 100644
--- a/contrib/buildsystems/Generators/Vcxproj.pm
+++ b/contrib/buildsystems/Generators/Vcxproj.pm
@@ -80,6 +80,7 @@ sub createProject {
$libs_release = join(";", sort(grep /^(?!libgit\.lib|xdiff\/lib\.lib|vcs-svn\/lib\.lib)/, @{$$build_structure{"$prefix${name}_LIBS"}}));
$libs_debug = $libs_release;
$libs_debug =~ s/zlib\.lib/zlibd\.lib/g;
+ $libs_debug =~ s/libexpat\.lib/libexpatd\.lib/g;
$libs_debug =~ s/libcurl\.lib/libcurl-d\.lib/g;
}
diff --git a/contrib/buildsystems/engine.pl b/contrib/buildsystems/engine.pl
index 070978506a..ed6c45988a 100755
--- a/contrib/buildsystems/engine.pl
+++ b/contrib/buildsystems/engine.pl
@@ -349,9 +349,9 @@ sub handleLinkLine
} elsif ("$part" eq "-lcurl") {
push(@libs, "libcurl.lib");
} elsif ("$part" eq "-lexpat") {
- push(@libs, "expat.lib");
+ push(@libs, "libexpat.lib");
} elsif ("$part" eq "-liconv") {
- push(@libs, "libiconv.lib");
+ push(@libs, "iconv.lib");
} elsif ($part =~ /^[-\/]/) {
push(@lflags, $part);
} elsif ($part =~ /\.(a|lib)$/) {
diff --git a/contrib/coccinelle/array.cocci b/contrib/coccinelle/array.cocci
index 46b8d2ee11..9a4f00cb1b 100644
--- a/contrib/coccinelle/array.cocci
+++ b/contrib/coccinelle/array.cocci
@@ -88,3 +88,11 @@ expression n;
@@
- ptr = xmalloc((n) * sizeof(T));
+ ALLOC_ARRAY(ptr, n);
+
+@@
+type T;
+T *ptr;
+expression n != 1;
+@@
+- ptr = xcalloc(n, \( sizeof(*ptr) \| sizeof(T) \) )
++ CALLOC_ARRAY(ptr, n)
diff --git a/contrib/coccinelle/commit.cocci b/contrib/coccinelle/commit.cocci
index 778e4704f6..af6dd4c20c 100644
--- a/contrib/coccinelle/commit.cocci
+++ b/contrib/coccinelle/commit.cocci
@@ -32,3 +32,21 @@ expression c;
- c->maybe_tree
+ repo_get_commit_tree(specify_the_right_repo_here, c)
...>}
+
+@@
+struct commit *c;
+expression E;
+@@
+(
+- c->generation = E;
++ commit_graph_data_at(c)->generation = E;
+|
+- c->graph_pos = E;
++ commit_graph_data_at(c)->graph_pos = E;
+|
+- c->generation
++ commit_graph_generation(c)
+|
+- c->graph_pos
++ commit_graph_position(c)
+)
diff --git a/contrib/coccinelle/xcalloc.cocci b/contrib/coccinelle/xcalloc.cocci
new file mode 100644
index 0000000000..c291011607
--- /dev/null
+++ b/contrib/coccinelle/xcalloc.cocci
@@ -0,0 +1,10 @@
+@@
+type T;
+T *ptr;
+expression n;
+@@
+ xcalloc(
++ n,
+ \( sizeof(T) \| sizeof(*ptr) \)
+- , n
+ )
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index c21786f2fd..7dc6cd8eb8 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -29,6 +29,15 @@
# tell the completion to use commit completion. This also works with aliases
# of form "!sh -c '...'". For example, "!sh -c ': git commit ; ... '".
#
+# If you have a command that is not part of git, but you would still
+# like completion, you can use __git_complete:
+#
+# __git_complete gl git_log
+#
+# Or if it's a main command (i.e. git or gitk):
+#
+# __git_complete gk gitk
+#
# Compatible with bash 3.2.57.
#
# You can set the following environment variables to influence the behavior of
@@ -39,6 +48,11 @@
# When set to "1", do not include "DWIM" suggestions in git-checkout
# and git-switch completion (e.g., completing "foo" when "origin/foo"
# exists).
+#
+# GIT_COMPLETION_SHOW_ALL
+#
+# When set to "1" suggest all options, including options which are
+# typically hidden (e.g. '--allow-empty' for 'git commit').
case "$COMP_WORDBREAKS" in
*:*) : great ;;
@@ -50,7 +64,7 @@ esac
# variable.
__git_find_repo_path ()
{
- if [ -n "$__git_repo_path" ]; then
+ if [ -n "${__git_repo_path-}" ]; then
# we already know where it is
return
fi
@@ -301,6 +315,19 @@ __gitcomp_direct ()
COMPREPLY=($1)
}
+# Similar to __gitcomp_direct, but appends to COMPREPLY instead.
+# Callers must take care of providing only words that match the current word
+# to be completed and adding any prefix and/or suffix (trailing space!), if
+# necessary.
+# 1: List of newline-separated matching completion words, complete with
+# prefix and suffix.
+__gitcomp_direct_append ()
+{
+ local IFS=$'\n'
+
+ COMPREPLY+=($1)
+}
+
__gitcompappend ()
{
local x i=${#COMPREPLY[@]}
@@ -373,7 +400,7 @@ __gitcomp ()
# Clear the variables caching builtins' options when (re-)sourcing
# the completion script.
if [[ -n ${ZSH_VERSION-} ]]; then
- unset $(set |sed -ne 's/^\(__gitcomp_builtin_[a-zA-Z0-9_][a-zA-Z0-9_]*\)=.*/\1/p') 2>/dev/null
+ unset ${(M)${(k)parameters[@]}:#__gitcomp_builtin_*} 2>/dev/null
else
unset $(compgen -v __gitcomp_builtin_)
fi
@@ -391,17 +418,23 @@ __gitcomp_builtin ()
# spaces must be replaced with underscore for multi-word
# commands, e.g. "git remote add" becomes remote_add.
local cmd="$1"
- local incl="$2"
- local excl="$3"
+ local incl="${2-}"
+ local excl="${3-}"
local var=__gitcomp_builtin_"${cmd/-/_}"
local options
- eval "options=\$$var"
+ eval "options=\${$var-}"
if [ -z "$options" ]; then
+ local completion_helper
+ if [ "$GIT_COMPLETION_SHOW_ALL" = "1" ]; then
+ completion_helper="--git-completion-helper-all"
+ else
+ completion_helper="--git-completion-helper"
+ fi
# leading and trailing spaces are significant to make
# option removal work correctly.
- options=" $incl $(__git ${cmd/_/ } --git-completion-helper) " || return
+ options=" $incl $(__git ${cmd/_/ } $completion_helper) " || return
for i in $excl; do
options="${options/ $i / }"
@@ -504,7 +537,7 @@ __git_index_files ()
{
local root="$2" match="$3"
- __git_ls_files_helper "$root" "$1" "$match" |
+ __git_ls_files_helper "$root" "$1" "${match:-?}" |
awk -F / -v pfx="${2//\\/\\\\}" '{
paths[$1] = 1
}
@@ -611,6 +644,19 @@ __git_heads ()
"refs/heads/$cur_*" "refs/heads/$cur_*/**"
}
+# Lists branches from remote repositories.
+# 1: A prefix to be added to each listed branch (optional).
+# 2: List only branches matching this word (optional; list all branches if
+# unset or empty).
+# 3: A suffix to be appended to each listed branch (optional).
+__git_remote_heads ()
+{
+ local pfx="${1-}" cur_="${2-}" sfx="${3-}"
+
+ __git for-each-ref --format="${pfx//\%/%%}%(refname:strip=2)$sfx" \
+ "refs/remotes/$cur_*" "refs/remotes/$cur_*/**"
+}
+
# Lists tags from the local repository.
# Accepts the same positional parameters as __git_heads() above.
__git_tags ()
@@ -621,6 +667,26 @@ __git_tags ()
"refs/tags/$cur_*" "refs/tags/$cur_*/**"
}
+# List unique branches from refs/remotes used for 'git checkout' and 'git
+# switch' tracking DWIMery.
+# 1: A prefix to be added to each listed branch (optional)
+# 2: List only branches matching this word (optional; list all branches if
+# unset or empty).
+# 3: A suffix to be appended to each listed branch (optional).
+__git_dwim_remote_heads ()
+{
+ local pfx="${1-}" cur_="${2-}" sfx="${3-}"
+ local fer_pfx="${pfx//\%/%%}" # "escape" for-each-ref format specifiers
+
+ # employ the heuristic used by git checkout and git switch
+ # Try to find a remote branch that cur_es the completion word
+ # but only output if the branch name is unique
+ __git for-each-ref --format="$fer_pfx%(refname:strip=3)$sfx" \
+ --sort="refname:strip=3" \
+ "refs/remotes/*/$cur_*" "refs/remotes/*/$cur_*/**" | \
+ uniq -u
+}
+
# Lists refs from the local (by default) or from a remote repository.
# It accepts 0, 1 or 2 arguments:
# 1: The remote to list refs from (optional; ignored, if set but empty).
@@ -696,13 +762,7 @@ __git_refs ()
__git_dir="$dir" __git for-each-ref --format="$fer_pfx%($format)$sfx" \
"${refs[@]}"
if [ -n "$track" ]; then
- # employ the heuristic used by git checkout
- # Try to find a remote branch that matches the completion word
- # but only output if the branch name is unique
- __git for-each-ref --format="$fer_pfx%(refname:strip=3)$sfx" \
- --sort="refname:strip=3" \
- "refs/remotes/*/$match*" "refs/remotes/*/$match*/**" | \
- uniq -u
+ __git_dwim_remote_heads "$pfx" "$match" "$sfx"
fi
return
fi
@@ -749,29 +809,51 @@ __git_refs ()
# Usage: __git_complete_refs [<option>]...
# --remote=<remote>: The remote to list refs from, can be the name of a
# configured remote, a path, or a URL.
-# --track: List unique remote branches for 'git checkout's tracking DWIMery.
+# --dwim: List unique remote branches for 'git switch's tracking DWIMery.
# --pfx=<prefix>: A prefix to be added to each ref.
# --cur=<word>: The current ref to be completed. Defaults to the current
# word to be completed.
# --sfx=<suffix>: A suffix to be appended to each ref instead of the default
# space.
+# --mode=<mode>: What set of refs to complete, one of 'refs' (the default) to
+# complete all refs, 'heads' to complete only branches, or
+# 'remote-heads' to complete only remote branches. Note that
+# --remote is only compatible with --mode=refs.
__git_complete_refs ()
{
- local remote track pfx cur_="$cur" sfx=" "
+ local remote= dwim= pfx= cur_="$cur" sfx=" " mode="refs"
while test $# != 0; do
case "$1" in
--remote=*) remote="${1##--remote=}" ;;
- --track) track="yes" ;;
+ --dwim) dwim="yes" ;;
+ # --track is an old spelling of --dwim
+ --track) dwim="yes" ;;
--pfx=*) pfx="${1##--pfx=}" ;;
--cur=*) cur_="${1##--cur=}" ;;
--sfx=*) sfx="${1##--sfx=}" ;;
+ --mode=*) mode="${1##--mode=}" ;;
*) return 1 ;;
esac
shift
done
- __gitcomp_direct "$(__git_refs "$remote" "$track" "$pfx" "$cur_" "$sfx")"
+ # complete references based on the specified mode
+ case "$mode" in
+ refs)
+ __gitcomp_direct "$(__git_refs "$remote" "" "$pfx" "$cur_" "$sfx")" ;;
+ heads)
+ __gitcomp_direct "$(__git_heads "$pfx" "$cur_" "$sfx")" ;;
+ remote-heads)
+ __gitcomp_direct "$(__git_remote_heads "$pfx" "$cur_" "$sfx")" ;;
+ *)
+ return 1 ;;
+ esac
+
+ # Append DWIM remote branch names if requested
+ if [ "$dwim" = "yes" ]; then
+ __gitcomp_direct_append "$(__git_dwim_remote_heads "$pfx" "$cur_" "$sfx")"
+ fi
}
# __git_refs2 requires 1 argument (to pass to __git_refs)
@@ -1047,26 +1129,44 @@ __git_pretty_aliases ()
# __git_aliased_command requires 1 argument
__git_aliased_command ()
{
- local word cmdline=$(__git config --get "alias.$1")
- for word in $cmdline; do
- case "$word" in
- \!gitk|gitk)
- echo "gitk"
- return
- ;;
- \!*) : shell command alias ;;
- -*) : option ;;
- *=*) : setting env ;;
- git) : git itself ;;
- \(\)) : skip parens of shell function definition ;;
- {) : skip start of shell helper function ;;
- :) : skip null command ;;
- \'*) : skip opening quote after sh -c ;;
- *)
- echo "$word"
+ local cur=$1 last list word cmdline
+
+ while [[ -n "$cur" ]]; do
+ if [[ "$list" == *" $cur "* ]]; then
+ # loop detected
return
- esac
+ fi
+
+ cmdline=$(__git config --get "alias.$cur")
+ list=" $cur $list"
+ last=$cur
+ cur=
+
+ for word in $cmdline; do
+ case "$word" in
+ \!gitk|gitk)
+ cur="gitk"
+ break
+ ;;
+ \!*) : shell command alias ;;
+ -*) : option ;;
+ *=*) : setting env ;;
+ git) : git itself ;;
+ \(\)) : skip parens of shell function definition ;;
+ {) : skip start of shell helper function ;;
+ :) : skip null command ;;
+ \'*) : skip opening quote after sh -c ;;
+ *)
+ cur="$word"
+ break
+ esac
+ done
done
+
+ cur=$last
+ if [[ "$cur" != "$1" ]]; then
+ echo "$cur"
+ fi
}
# Check whether one of the given words is present on the command line,
@@ -1090,7 +1190,7 @@ __git_find_on_cmdline ()
while [ $c -lt $cword ]; do
for word in $wordlist; do
if [ "$word" = "${words[c]}" ]; then
- if [ -n "$show_idx" ]; then
+ if [ -n "${show_idx-}" ]; then
echo "$c $word"
else
echo "$word"
@@ -1102,6 +1202,40 @@ __git_find_on_cmdline ()
done
}
+# Similar to __git_find_on_cmdline, except that it loops backwards and thus
+# prints the *last* word found. Useful for finding which of two options that
+# supersede each other came last, such as "--guess" and "--no-guess".
+#
+# Usage: __git_find_last_on_cmdline [<option>]... "<wordlist>"
+# --show-idx: Optionally show the index of the found word in the $words array.
+__git_find_last_on_cmdline ()
+{
+ local word c=$cword show_idx
+
+ while test $# -gt 1; do
+ case "$1" in
+ --show-idx) show_idx=y ;;
+ *) return 1 ;;
+ esac
+ shift
+ done
+ local wordlist="$1"
+
+ while [ $c -gt 1 ]; do
+ ((c--))
+ for word in $wordlist; do
+ if [ "$word" = "${words[c]}" ]; then
+ if [ -n "$show_idx" ]; then
+ echo "$c $word"
+ else
+ echo "$word"
+ fi
+ return
+ fi
+ done
+ done
+}
+
# Echo the value of an option set on the command line or config
#
# $1: short option name
@@ -1313,8 +1447,10 @@ _git_branch ()
while [ $c -lt $cword ]; do
i="${words[c]}"
case "$i" in
- -d|--delete|-m|--move) only_local_ref="y" ;;
- -r|--remotes) has_r="y" ;;
+ -d|-D|--delete|-m|-M|--move|-c|-C|--copy)
+ only_local_ref="y" ;;
+ -r|--remotes)
+ has_r="y" ;;
esac
((c++))
done
@@ -1356,10 +1492,73 @@ _git_bundle ()
esac
}
+# Helper function to decide whether or not we should enable DWIM logic for
+# git-switch and git-checkout.
+#
+# To decide between the following rules in decreasing priority order:
+# - the last provided of "--guess" or "--no-guess" explicitly enable or
+# disable completion of DWIM logic respectively.
+# - If checkout.guess is false, disable completion of DWIM logic.
+# - If the --no-track option is provided, take this as a hint to disable the
+# DWIM completion logic
+# - If GIT_COMPLETION_CHECKOUT_NO_GUESS is set, disable the DWIM completion
+# logic, as requested by the user.
+# - Enable DWIM logic otherwise.
+#
+__git_checkout_default_dwim_mode ()
+{
+ local last_option dwim_opt="--dwim"
+
+ if [ "${GIT_COMPLETION_CHECKOUT_NO_GUESS-}" = "1" ]; then
+ dwim_opt=""
+ fi
+
+ # --no-track disables DWIM, but with lower priority than
+ # --guess/--no-guess/checkout.guess
+ if [ -n "$(__git_find_on_cmdline "--no-track")" ]; then
+ dwim_opt=""
+ fi
+
+ # checkout.guess = false disables DWIM, but with lower priority than
+ # --guess/--no-guess
+ if [ "$(__git config --type=bool checkout.guess)" = "false" ]; then
+ dwim_opt=""
+ fi
+
+ # Find the last provided --guess or --no-guess
+ last_option="$(__git_find_last_on_cmdline "--guess --no-guess")"
+ case "$last_option" in
+ --guess)
+ dwim_opt="--dwim"
+ ;;
+ --no-guess)
+ dwim_opt=""
+ ;;
+ esac
+
+ echo "$dwim_opt"
+}
+
_git_checkout ()
{
__git_has_doubledash && return
+ local dwim_opt="$(__git_checkout_default_dwim_mode)"
+
+ case "$prev" in
+ -b|-B|--orphan)
+ # Complete local branches (and DWIM branch
+ # remote branch names) for an option argument
+ # specifying a new branch name. This is for
+ # convenience, assuming new branches are
+ # possibly based on pre-existing branch names.
+ __git_complete_refs $dwim_opt --mode="heads"
+ return
+ ;;
+ *)
+ ;;
+ esac
+
case "$cur" in
--conflict=*)
__gitcomp "diff3 merge" "" "${cur##--conflict=}"
@@ -1368,14 +1567,21 @@ _git_checkout ()
__gitcomp_builtin checkout
;;
*)
- # check if --track, --no-track, or --no-guess was specified
- # if so, disable DWIM mode
- local flags="--track --no-track --no-guess" track_opt="--track"
- if [ "$GIT_COMPLETION_CHECKOUT_NO_GUESS" = "1" ] ||
- [ -n "$(__git_find_on_cmdline "$flags")" ]; then
- track_opt=''
+ # At this point, we've already handled special completion for
+ # the arguments to -b/-B, and --orphan. There are 3 main
+ # things left we can possibly complete:
+ # 1) a start-point for -b/-B, -d/--detach, or --orphan
+ # 2) a remote head, for --track
+ # 3) an arbitrary reference, possibly including DWIM names
+ #
+
+ if [ -n "$(__git_find_on_cmdline "-b -B -d --detach --orphan")" ]; then
+ __git_complete_refs --mode="refs"
+ elif [ -n "$(__git_find_on_cmdline "--track")" ]; then
+ __git_complete_refs --mode="remote-heads"
+ else
+ __git_complete_refs $dwim_opt --mode="refs"
fi
- __git_complete_refs $track_opt
;;
esac
}
@@ -1517,8 +1723,13 @@ __git_diff_common_options="--stat --numstat --shortstat --summary
--submodule --submodule= --ignore-submodules
--indent-heuristic --no-indent-heuristic
--textconv --no-textconv
+ --patch --no-patch
"
+__git_diff_difftool_options="--cached --staged --pickaxe-all --pickaxe-regex
+ --base --ours --theirs --no-index --relative --merge-base
+ $__git_diff_common_options"
+
_git_diff ()
{
__git_has_doubledash && return
@@ -1541,10 +1752,7 @@ _git_diff ()
return
;;
--*)
- __gitcomp "--cached --staged --pickaxe-all --pickaxe-regex
- --base --ours --theirs --no-index
- $__git_diff_common_options
- "
+ __gitcomp "$__git_diff_difftool_options"
return
;;
esac
@@ -1552,8 +1760,8 @@ _git_diff ()
}
__git_mergetools_common="diffuse diffmerge ecmerge emerge kdiff3 meld opendiff
- tkdiff vimdiff gvimdiff xxdiff araxis p4merge bc
- codecompare smerge
+ tkdiff vimdiff nvimdiff gvimdiff xxdiff araxis p4merge
+ bc codecompare smerge
"
_git_difftool ()
@@ -1566,11 +1774,7 @@ _git_difftool ()
return
;;
--*)
- __gitcomp_builtin difftool "$__git_diff_common_options
- --base --cached --ours --theirs
- --pickaxe-all --pickaxe-regex
- --relative --staged
- "
+ __gitcomp_builtin difftool "$__git_diff_difftool_options"
return
;;
esac
@@ -1612,6 +1816,10 @@ _git_format_patch ()
" "" "${cur##--thread=}"
return
;;
+ --base=*|--interdiff=*|--range-diff=*)
+ __git_complete_refs --cur="${cur#--*=}"
+ return
+ ;;
--*)
__gitcomp_builtin format-patch "$__git_format_patch_extra_options"
return
@@ -1632,7 +1840,7 @@ _git_fsck ()
_git_gitk ()
{
- _gitk
+ __gitk_main
}
# Lists matching symbol names from a tag (as in ctags) file.
@@ -1856,7 +2064,6 @@ _git_log ()
--no-walk --no-walk= --do-walk
--parents --children
--expand-tabs --expand-tabs= --no-expand-tabs
- --patch
$merge
$__git_diff_common_options
--pickaxe-all --pickaxe-regex
@@ -2215,6 +2422,22 @@ _git_status ()
_git_switch ()
{
+ local dwim_opt="$(__git_checkout_default_dwim_mode)"
+
+ case "$prev" in
+ -c|-C|--orphan)
+ # Complete local branches (and DWIM branch
+ # remote branch names) for an option argument
+ # specifying a new branch name. This is for
+ # convenience, assuming new branches are
+ # possibly based on pre-existing branch names.
+ __git_complete_refs $dwim_opt --mode="heads"
+ return
+ ;;
+ *)
+ ;;
+ esac
+
case "$cur" in
--conflict=*)
__gitcomp "diff3 merge" "" "${cur##--conflict=}"
@@ -2223,29 +2446,26 @@ _git_switch ()
__gitcomp_builtin switch
;;
*)
- # check if --track, --no-track, or --no-guess was specified
- # if so, disable DWIM mode
- local track_opt="--track" only_local_ref=n
- if [ "$GIT_COMPLETION_CHECKOUT_NO_GUESS" = "1" ] ||
- [ -n "$(__git_find_on_cmdline "--track --no-track --no-guess")" ]; then
- track_opt=''
- fi
- # explicit --guess enables DWIM mode regardless of
- # $GIT_COMPLETION_CHECKOUT_NO_GUESS
- if [ -n "$(__git_find_on_cmdline "--guess")" ]; then
- track_opt='--track'
- fi
- if [ -z "$(__git_find_on_cmdline "-d --detach")" ]; then
- only_local_ref=y
- else
- # --guess --detach is invalid combination, no
- # dwim will be done when --detach is specified
- track_opt=
+ # Unlike in git checkout, git switch --orphan does not take
+ # a start point. Thus we really have nothing to complete after
+ # the branch name.
+ if [ -n "$(__git_find_on_cmdline "--orphan")" ]; then
+ return
fi
- if [ $only_local_ref = y -a -z "$track_opt" ]; then
- __gitcomp_direct "$(__git_heads "" "$cur" " ")"
+
+ # At this point, we've already handled special completion for
+ # -c/-C, and --orphan. There are 3 main things left to
+ # complete:
+ # 1) a start-point for -c/-C or -d/--detach
+ # 2) a remote head, for --track
+ # 3) a branch name, possibly including DWIM remote branches
+
+ if [ -n "$(__git_find_on_cmdline "-c -C -d --detach")" ]; then
+ __git_complete_refs --mode="refs"
+ elif [ -n "$(__git_find_on_cmdline "--track")" ]; then
+ __git_complete_refs --mode="remote-heads"
else
- __git_complete_refs $track_opt
+ __git_complete_refs $dwim_opt --mode="heads"
fi
;;
esac
@@ -2652,6 +2872,13 @@ _git_reset ()
_git_restore ()
{
+ case "$prev" in
+ -s)
+ __git_complete_refs
+ return
+ ;;
+ esac
+
case "$cur" in
--conflict=*)
__gitcomp "diff3 merge" "" "${cur##--conflict=}"
@@ -2732,9 +2959,17 @@ _git_show ()
__gitcomp "$__git_diff_submodule_formats" "" "${cur##--submodule=}"
return
;;
+ --color-moved=*)
+ __gitcomp "$__git_color_moved_opts" "" "${cur##--color-moved=}"
+ return
+ ;;
+ --color-moved-ws=*)
+ __gitcomp "$__git_color_moved_ws_opts" "" "${cur##--color-moved-ws=}"
+ return
+ ;;
--*)
__gitcomp "--pretty= --format= --abbrev-commit --no-abbrev-commit
- --oneline --show-signature --patch
+ --oneline --show-signature
--expand-tabs --expand-tabs= --no-expand-tabs
$__git_diff_common_options
"
@@ -2781,7 +3016,7 @@ _git_stash ()
local save_opts='--all --keep-index --no-keep-index --quiet --patch --include-untracked'
local subcommands='push list show apply clear drop pop create branch'
local subcommand="$(__git_find_on_cmdline "$subcommands save")"
- if [ -n "$(__git_find_on_cmdline "-p")" ]; then
+ if [ -z "$subcommand" -a -n "$(__git_find_on_cmdline "-p")" ]; then
subcommand="push"
fi
if [ -z "$subcommand" ]; then
@@ -2817,7 +3052,10 @@ _git_stash ()
list,--*)
__gitcomp "--name-status --oneline --patch-with-stat"
;;
- show,--*|branch,--*)
+ show,--*)
+ __gitcomp "$__git_diff_common_options"
+ ;;
+ branch,--*)
;;
branch,*)
if [ $cword -eq 3 ]; then
@@ -3131,15 +3369,19 @@ __git_support_parseopt_helper () {
esac
}
+__git_have_func () {
+ declare -f -- "$1" >/dev/null 2>&1
+}
+
__git_complete_command () {
local command="$1"
local completion_func="_git_${command//-/_}"
- if ! declare -f $completion_func >/dev/null 2>/dev/null &&
- declare -f _completion_loader >/dev/null 2>/dev/null
+ if ! __git_have_func $completion_func &&
+ __git_have_func _completion_loader
then
_completion_loader "git-$command"
fi
- if declare -f $completion_func >/dev/null 2>/dev/null
+ if __git_have_func $completion_func
then
$completion_func
return 0
@@ -3175,7 +3417,7 @@ __git_main ()
((c++))
done
- if [ -z "$command" ]; then
+ if [ -z "${command-}" ]; then
case "$prev" in
--git-dir|-C|--work-tree)
# these need a path argument, let's fall back to
@@ -3210,7 +3452,7 @@ __git_main ()
"
;;
*)
- if test -n "$GIT_TESTING_PORCELAIN_COMMAND_LIST"
+ if test -n "${GIT_TESTING_PORCELAIN_COMMAND_LIST-}"
then
__gitcomp "$GIT_TESTING_PORCELAIN_COMMAND_LIST"
else
@@ -3254,88 +3496,8 @@ __gitk_main ()
__git_complete_revlist
}
-if [[ -n ${ZSH_VERSION-} ]] &&
- # Don't define these functions when sourced from 'git-completion.zsh',
- # it has its own implementations.
- [[ -z ${GIT_SOURCING_ZSH_COMPLETION-} ]]; then
- echo "WARNING: this script is deprecated, please see git-completion.zsh" 1>&2
-
- autoload -U +X compinit && compinit
-
- __gitcomp ()
- {
- emulate -L zsh
-
- local cur_="${3-$cur}"
-
- case "$cur_" in
- --*=)
- ;;
- *)
- local c IFS=$' \t\n'
- local -a array
- for c in ${=1}; do
- c="$c${4-}"
- case $c in
- --*=*|*.) ;;
- *) c="$c " ;;
- esac
- array[${#array[@]}+1]="$c"
- done
- compset -P '*[=:]'
- compadd -Q -S '' -p "${2-}" -a -- array && _ret=0
- ;;
- esac
- }
-
- __gitcomp_direct ()
- {
- emulate -L zsh
-
- local IFS=$'\n'
- compset -P '*[=:]'
- compadd -Q -- ${=1} && _ret=0
- }
-
- __gitcomp_nl ()
- {
- emulate -L zsh
-
- local IFS=$'\n'
- compset -P '*[=:]'
- compadd -Q -S "${4- }" -p "${2-}" -- ${=1} && _ret=0
- }
-
- __gitcomp_file_direct ()
- {
- emulate -L zsh
-
- local IFS=$'\n'
- compset -P '*[=:]'
- compadd -f -- ${=1} && _ret=0
- }
-
- __gitcomp_file ()
- {
- emulate -L zsh
-
- local IFS=$'\n'
- compset -P '*[=:]'
- compadd -p "${2-}" -f -- ${=1} && _ret=0
- }
-
- _git ()
- {
- local _ret=1 cur cword prev
- cur=${words[CURRENT]}
- prev=${words[CURRENT-1]}
- let cword=CURRENT-1
- emulate ksh -c __${service}_main
- let _ret && _default && _ret=0
- return _ret
- }
-
- compdef _git git gitk
+if [[ -n ${ZSH_VERSION-} && -z ${GIT_SOURCING_ZSH_COMPLETION-} ]]; then
+ echo "ERROR: this script is obsolete, please see git-completion.zsh" 1>&2
return
fi
@@ -3346,10 +3508,7 @@ __git_func_wrap ()
$1
}
-# Setup completion for certain functions defined above by setting common
-# variables and workarounds.
-# This is NOT a public function; use at your own risk.
-__git_complete ()
+___git_complete ()
{
local wrapper="__git_wrap${2}"
eval "$wrapper () { __git_func_wrap $2 ; }"
@@ -3357,25 +3516,33 @@ __git_complete ()
|| complete -o default -o nospace -F $wrapper $1
}
-# wrapper for backwards compatibility
-_git ()
+# Setup the completion for git commands
+# 1: command or alias
+# 2: function to call (e.g. `git`, `gitk`, `git_fetch`)
+__git_complete ()
{
- __git_wrap__git_main
-}
+ local func
-# wrapper for backwards compatibility
-_gitk ()
-{
- __git_wrap__gitk_main
+ if __git_have_func $2; then
+ func=$2
+ elif __git_have_func __$2_main; then
+ func=__$2_main
+ elif __git_have_func _$2; then
+ func=_$2
+ else
+ echo "ERROR: could not find function '$2'" 1>&2
+ return 1
+ fi
+ ___git_complete $1 $func
}
-__git_complete git __git_main
-__git_complete gitk __gitk_main
+___git_complete git __git_main
+___git_complete gitk __gitk_main
# The following are necessary only for Cygwin, and only are needed
# when the user has tab-completed the executable name and consequently
# included the '.exe' suffix.
#
-if [ Cygwin = "$(uname -o 2>/dev/null)" ]; then
-__git_complete git.exe __git_main
+if [ "$OSTYPE" = cygwin ]; then
+ ___git_complete git.exe __git_main
fi
diff --git a/contrib/completion/git-completion.zsh b/contrib/completion/git-completion.zsh
index eef4eff53d..6c56296997 100644
--- a/contrib/completion/git-completion.zsh
+++ b/contrib/completion/git-completion.zsh
@@ -2,26 +2,24 @@
# zsh completion wrapper for git
#
-# Copyright (c) 2012-2013 Felipe Contreras <felipe.contreras@gmail.com>
+# Copyright (c) 2012-2020 Felipe Contreras <felipe.contreras@gmail.com>
#
-# You need git's bash completion script installed somewhere, by default it
-# would be the location bash-completion uses.
+# The recommended way to install this script is to make a copy of it as a
+# file named '_git' inside any directory in your fpath.
#
-# If your script is somewhere else, you can configure it on your ~/.zshrc:
+# For example, create a directory '~/.zsh/', copy this file to '~/.zsh/_git',
+# and then add the following to your ~/.zshrc file:
#
-# zstyle ':completion:*:*:git:*' script ~/.git-completion.zsh
+# fpath=(~/.zsh $fpath)
#
-# The recommended way to install this script is to make a copy of it in
-# ~/.zsh/ directory as ~/.zsh/git-completion.zsh and then add the following
-# to your ~/.zshrc file:
+# You need git's bash completion script installed. By default bash-completion's
+# location will be used (e.g. pkg-config --variable=completionsdir bash-completion).
+#
+# If your bash completion script is somewhere else, you can specify the
+# location in your ~/.zshrc:
+#
+# zstyle ':completion:*:*:git:*' script ~/.git-completion.bash
#
-# fpath=(~/.zsh $fpath)
-
-complete ()
-{
- # do nothing
- return 0
-}
zstyle -T ':completion:*:*:git:*' tag-order && \
zstyle ':completion:*:*:git:*' tag-order 'common-commands'
@@ -29,18 +27,26 @@ zstyle -T ':completion:*:*:git:*' tag-order && \
zstyle -s ":completion:*:*:git:*" script script
if [ -z "$script" ]; then
local -a locations
- local e
+ local e bash_completion
+
+ bash_completion=$(pkg-config --variable=completionsdir bash-completion 2>/dev/null) ||
+ bash_completion='/usr/share/bash-completion/completions/'
+
locations=(
- $(dirname ${funcsourcetrace[1]%:*})/git-completion.bash
- '/etc/bash_completion.d/git' # fedora, old debian
- '/usr/share/bash-completion/completions/git' # arch, ubuntu, new debian
- '/usr/share/bash-completion/git' # gentoo
+ "$(dirname ${funcsourcetrace[1]%:*})"/git-completion.bash
+ "$HOME/.local/share/bash-completion/completions/git"
+ "$bash_completion/git"
+ '/etc/bash_completion.d/git' # old debian
)
for e in $locations; do
test -f $e && script="$e" && break
done
fi
+
+local old_complete="$functions[complete]"
+functions[complete]=:
GIT_SOURCING_ZSH_COMPLETION=y . "$script"
+functions[complete]="$old_complete"
__gitcomp ()
{
@@ -51,13 +57,35 @@ __gitcomp ()
case "$cur_" in
--*=)
;;
+ --no-*)
+ local c IFS=$' \t\n'
+ local -a array
+ for c in ${=1}; do
+ if [[ $c == "--" ]]; then
+ continue
+ fi
+ c="$c${4-}"
+ case $c in
+ --*=|*.) ;;
+ *) c="$c " ;;
+ esac
+ array+=("$c")
+ done
+ compset -P '*[=:]'
+ compadd -Q -S '' -p "${2-}" -a -- array && _ret=0
+ ;;
*)
local c IFS=$' \t\n'
local -a array
for c in ${=1}; do
+ if [[ $c == "--" ]]; then
+ c="--no-...${4-}"
+ array+=("$c ")
+ break
+ fi
c="$c${4-}"
case $c in
- --*=*|*.) ;;
+ --*=|*.) ;;
*) c="$c " ;;
esac
array+=("$c")
@@ -72,44 +100,58 @@ __gitcomp_direct ()
{
emulate -L zsh
- local IFS=$'\n'
compset -P '*[=:]'
- compadd -Q -- ${=1} && _ret=0
+ compadd -Q -S '' -- ${(f)1} && _ret=0
}
__gitcomp_nl ()
{
emulate -L zsh
- local IFS=$'\n'
compset -P '*[=:]'
- compadd -Q -S "${4- }" -p "${2-}" -- ${=1} && _ret=0
+ compadd -Q -S "${4- }" -p "${2-}" -- ${(f)1} && _ret=0
}
-__gitcomp_nl_append ()
+__gitcomp_file ()
{
emulate -L zsh
- local IFS=$'\n'
- compadd -Q -S "${4- }" -p "${2-}" -- ${=1} && _ret=0
+ compset -P '*[=:]'
+ compadd -f -p "${2-}" -- ${(f)1} && _ret=0
+}
+
+__gitcomp_direct_append ()
+{
+ __gitcomp_direct "$@"
+}
+
+__gitcomp_nl_append ()
+{
+ __gitcomp_nl "$@"
}
__gitcomp_file_direct ()
{
- emulate -L zsh
+ __gitcomp_file "$1" ""
+}
- local IFS=$'\n'
- compset -P '*[=:]'
- compadd -f -- ${=1} && _ret=0
+_git_zsh ()
+{
+ __gitcomp "v1.1"
}
-__gitcomp_file ()
+__git_complete_command ()
{
emulate -L zsh
- local IFS=$'\n'
- compset -P '*[=:]'
- compadd -p "${2-}" -f -- ${=1} && _ret=0
+ local command="$1"
+ local completion_func="_git_${command//-/_}"
+ if (( $+functions[$completion_func] )); then
+ emulate ksh -c $completion_func
+ return 0
+ else
+ return 1
+ fi
}
__git_zsh_bash_func ()
@@ -118,14 +160,12 @@ __git_zsh_bash_func ()
local command=$1
- local completion_func="_git_${command//-/_}"
- declare -f $completion_func >/dev/null && $completion_func && return
+ __git_complete_command "$command" && return
local expansion=$(__git_aliased_command "$command")
if [ -n "$expansion" ]; then
words[1]=$expansion
- completion_func="_git_${expansion//-/_}"
- declare -f $completion_func >/dev/null && $completion_func
+ __git_complete_command "$expansion"
fi
}
@@ -150,9 +190,11 @@ __git_zsh_cmd_common ()
push:'update remote refs along with associated objects'
rebase:'forward-port local commits to the updated upstream head'
reset:'reset current HEAD to the specified state'
+ restore:'restore working tree files'
rm:'remove files from the working tree and from the index'
show:'show various types of objects'
status:'show the working tree status'
+ switch:'switch branches'
tag:'create, list, delete or verify a tag object signed with GPG')
_describe -t common-commands 'common commands' list && _ret=0
}
@@ -160,8 +202,9 @@ __git_zsh_cmd_common ()
__git_zsh_cmd_alias ()
{
local -a list
- list=(${${${(0)"$(git config -z --get-regexp '^alias\.')"}#alias.}%$'\n'*})
- _describe -t alias-commands 'aliases' list $* && _ret=0
+ list=(${${(0)"$(git config -z --get-regexp '^alias\.*')"}#alias.})
+ list=(${(f)"$(printf "%s:alias for '%s'\n" ${(f@)list})"})
+ _describe -t alias-commands 'aliases' list && _ret=0
}
__git_zsh_cmd_all ()
@@ -199,10 +242,13 @@ __git_zsh_main ()
case $state in
(command)
- _alternative \
- 'alias-commands:alias:__git_zsh_cmd_alias' \
- 'common-commands:common:__git_zsh_cmd_common' \
- 'all-commands:all:__git_zsh_cmd_all' && _ret=0
+ _tags common-commands alias-commands all-commands
+ while _tags; do
+ _requested common-commands && __git_zsh_cmd_common
+ _requested alias-commands && __git_zsh_cmd_alias
+ _requested all-commands && __git_zsh_cmd_all
+ let _ret || break
+ done
;;
(arg)
local command="${words[1]}" __git_dir
@@ -233,8 +279,12 @@ _git ()
if (( $+functions[__${service}_zsh_main] )); then
__${service}_zsh_main
- else
+ elif (( $+functions[__${service}_main] )); then
emulate ksh -c __${service}_main
+ elif (( $+functions[_${service}] )); then
+ emulate ksh -c _${service}
+ elif (( $+functions[_${service//-/_}] )); then
+ emulate ksh -c _${service//-/_}
fi
let _ret && _default && _ret=0
diff --git a/contrib/completion/git-prompt.sh b/contrib/completion/git-prompt.sh
index 014cd7c3cf..4640a1535d 100644
--- a/contrib/completion/git-prompt.sh
+++ b/contrib/completion/git-prompt.sh
@@ -70,6 +70,15 @@
# state symbols by setting GIT_PS1_STATESEPARATOR. The default separator
# is SP.
#
+# When there is an in-progress operation such as a merge, rebase,
+# revert, cherry-pick, or bisect, the prompt will include information
+# related to the operation, often in the form "|<OPERATION-NAME>".
+#
+# When the repository has a sparse-checkout, a notification of the form
+# "|SPARSE" will be included in the prompt. This can be shortened to a
+# single '?' character by setting GIT_PS1_COMPRESSSPARSESTATE, or omitted
+# by setting GIT_PS1_OMITSPARSESTATE.
+#
# By default, __git_ps1 will compare HEAD to your SVN upstream if it can
# find one, or @{upstream} otherwise. Once you have set
# GIT_PS1_SHOWUPSTREAM, you can override it on a per-repository basis by
@@ -88,7 +97,8 @@
# If you would like a colored hint about the current dirty state, set
# GIT_PS1_SHOWCOLORHINTS to a nonempty value. The colors are based on
# the colored output of "git status -sb" and are available only when
-# using __git_ps1 for PROMPT_COMMAND or precmd.
+# using __git_ps1 for PROMPT_COMMAND or precmd in Bash,
+# but always available in Zsh.
#
# If you would like __git_ps1 to do nothing in the case when the current
# directory is set up to be ignored by git, then set
@@ -128,6 +138,7 @@ __git_ps1_show_upstream ()
done <<< "$output"
# parse configuration values
+ local option
for option in ${GIT_PS1_SHOWUPSTREAM}; do
case "$option" in
git|svn) upstream="$option" ;;
@@ -421,6 +432,13 @@ __git_ps1 ()
return $exit
fi
+ local sparse=""
+ if [ -z "${GIT_PS1_COMPRESSSPARSESTATE}" ] &&
+ [ -z "${GIT_PS1_OMITSPARSESTATE}" ] &&
+ [ "$(git config --bool core.sparseCheckout)" = "true" ]; then
+ sparse="|SPARSE"
+ fi
+
local r=""
local b=""
local step=""
@@ -492,6 +510,7 @@ __git_ps1 ()
local i=""
local s=""
local u=""
+ local h=""
local c=""
local p=""
@@ -524,6 +543,11 @@ __git_ps1 ()
u="%${ZSH_VERSION+%}"
fi
+ if [ -n "${GIT_PS1_COMPRESSSPARSESTATE}" ] &&
+ [ "$(git config --bool core.sparseCheckout)" = "true" ]; then
+ h="?"
+ fi
+
if [ -n "${GIT_PS1_SHOWUPSTREAM-}" ]; then
__git_ps1_show_upstream
fi
@@ -531,9 +555,11 @@ __git_ps1 ()
local z="${GIT_PS1_STATESEPARATOR-" "}"
- # NO color option unless in PROMPT_COMMAND mode
- if [ $pcmode = yes ] && [ -n "${GIT_PS1_SHOWCOLORHINTS-}" ]; then
- __git_ps1_colorize_gitstring
+ # NO color option unless in PROMPT_COMMAND mode or it's Zsh
+ if [ -n "${GIT_PS1_SHOWCOLORHINTS-}" ]; then
+ if [ $pcmode = yes ] || [ -n "${ZSH_VERSION-}" ]; then
+ __git_ps1_colorize_gitstring
+ fi
fi
b=${b##refs/heads/}
@@ -542,8 +568,8 @@ __git_ps1 ()
b="\${__git_ps1_branch_name}"
fi
- local f="$w$i$s$u"
- local gitstring="$c$b${f:+$z$f}$r$p"
+ local f="$h$w$i$s$u"
+ local gitstring="$c$b${f:+$z$f}${sparse}$r$p"
if [ $pcmode = yes ]; then
if [ "${__git_printf_supports_v-}" != yes ]; then
diff --git a/contrib/diff-highlight/DiffHighlight.pm b/contrib/diff-highlight/DiffHighlight.pm
index e2589922a6..376f577737 100644
--- a/contrib/diff-highlight/DiffHighlight.pm
+++ b/contrib/diff-highlight/DiffHighlight.pm
@@ -112,7 +112,7 @@ sub handle_line {
# Since we can receive arbitrary input, there's no optimal
# place to flush. Flushing on a blank line is a heuristic that
# happens to match git-log output.
- if (!length) {
+ if (/^$/) {
$flush_cb->();
}
}
diff --git a/contrib/fast-import/import-tars.perl b/contrib/fast-import/import-tars.perl
index e800d9f5c9..d50ce26d5d 100755
--- a/contrib/fast-import/import-tars.perl
+++ b/contrib/fast-import/import-tars.perl
@@ -139,6 +139,8 @@ foreach my $tar_file (@ARGV)
print FI "\n";
}
+ next if ($typeflag eq 'g'); # ignore global header
+
my $path;
if ($prefix) {
$path = "$prefix/$name";
diff --git a/contrib/git-resurrect.sh b/contrib/git-resurrect.sh
index 8c171dd959..d843df3afd 100755
--- a/contrib/git-resurrect.sh
+++ b/contrib/git-resurrect.sh
@@ -27,7 +27,7 @@ n,dry-run don't recreate the branch"
search_reflog () {
sed -ne 's~^\([^ ]*\) .* checkout: moving from '"$1"' .*~\1~p' \
- < "$GIT_DIR"/logs/HEAD
+ < "$GIT_DIR"/logs/HEAD
}
search_reflog_merges () {
@@ -37,19 +37,18 @@ search_reflog_merges () {
)
}
-_x40="[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]"
-_x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40"
+oid_pattern=$(git hash-object --stdin </dev/null | sed -e 's/./[0-9a-f]/g')
search_merges () {
- git rev-list --all --grep="Merge branch '$1'" \
- --pretty=tformat:"%P %s" |
- sed -ne "/^$_x40 \($_x40\) Merge .*/ {s//\1/p;$early_exit}"
+ git rev-list --all --grep="Merge branch '$1'" \
+ --pretty=tformat:"%P %s" |
+ sed -ne "/^$oid_pattern \($oid_pattern\) Merge .*/ {s//\1/p;$early_exit}"
}
search_merge_targets () {
git rev-list --all --grep="Merge branch '[^']*' into $branch\$" \
--pretty=tformat:"%H %s" --all |
- sed -ne "/^\($_x40\) Merge .*/ {s//\1/p;$early_exit} "
+ sed -ne "/^\($oid_pattern\) Merge .*/ {s//\1/p;$early_exit} "
}
dry_run=
diff --git a/contrib/mw-to-git/git-mw.perl b/contrib/mw-to-git/git-mw.perl
index 28df3ee321..eb52a53d32 100755
--- a/contrib/mw-to-git/git-mw.perl
+++ b/contrib/mw-to-git/git-mw.perl
@@ -6,7 +6,7 @@
# License: GPL v2 or later
# Set of tools for git repo with a mediawiki remote.
-# Documentation & bugtracker: https://github.com/moy/Git-Mediawiki/
+# Documentation & bugtracker: https://github.com/Git-Mediawiki/Git-Mediawiki
use strict;
use warnings;
diff --git a/contrib/mw-to-git/git-remote-mediawiki.perl b/contrib/mw-to-git/git-remote-mediawiki.perl
index d8ff2e69c4..a5624413dc 100755
--- a/contrib/mw-to-git/git-remote-mediawiki.perl
+++ b/contrib/mw-to-git/git-remote-mediawiki.perl
@@ -9,7 +9,7 @@
# License: GPL v2 or later
# Gateway between Git and MediaWiki.
-# Documentation & bugtracker: https://github.com/moy/Git-Mediawiki/
+# Documentation & bugtracker: https://github.com/Git-Mediawiki/Git-Mediawiki
use strict;
use MediaWiki::API;
@@ -56,38 +56,38 @@ my $url = $ARGV[1];
# Accept both space-separated and multiple keys in config file.
# Spaces should be written as _ anyway because we'll use chomp.
-my @tracked_pages = split(/[ \n]/, run_git("config --get-all remote.${remotename}.pages"));
+my @tracked_pages = split(/[ \n]/, run_git_quoted(["config", "--get-all", "remote.${remotename}.pages"]));
chomp(@tracked_pages);
# Just like @tracked_pages, but for MediaWiki categories.
-my @tracked_categories = split(/[ \n]/, run_git("config --get-all remote.${remotename}.categories"));
+my @tracked_categories = split(/[ \n]/, run_git_quoted(["config", "--get-all", "remote.${remotename}.categories"]));
chomp(@tracked_categories);
# Just like @tracked_categories, but for MediaWiki namespaces.
-my @tracked_namespaces = split(/[ \n]/, run_git("config --get-all remote.${remotename}.namespaces"));
+my @tracked_namespaces = split(/[ \n]/, run_git_quoted(["config", "--get-all", "remote.${remotename}.namespaces"]));
for (@tracked_namespaces) { s/_/ /g; }
chomp(@tracked_namespaces);
# Import media files on pull
-my $import_media = run_git("config --get --bool remote.${remotename}.mediaimport");
+my $import_media = run_git_quoted(["config", "--get", "--bool", "remote.${remotename}.mediaimport"]);
chomp($import_media);
$import_media = ($import_media eq 'true');
# Export media files on push
-my $export_media = run_git("config --get --bool remote.${remotename}.mediaexport");
+my $export_media = run_git_quoted(["config", "--get", "--bool", "remote.${remotename}.mediaexport"]);
chomp($export_media);
$export_media = !($export_media eq 'false');
-my $wiki_login = run_git("config --get remote.${remotename}.mwLogin");
+my $wiki_login = run_git_quoted(["config", "--get", "remote.${remotename}.mwLogin"]);
# Note: mwPassword is discouraged. Use the credential system instead.
-my $wiki_passwd = run_git("config --get remote.${remotename}.mwPassword");
-my $wiki_domain = run_git("config --get remote.${remotename}.mwDomain");
+my $wiki_passwd = run_git_quoted(["config", "--get", "remote.${remotename}.mwPassword"]);
+my $wiki_domain = run_git_quoted(["config", "--get", "remote.${remotename}.mwDomain"]);
chomp($wiki_login);
chomp($wiki_passwd);
chomp($wiki_domain);
# Import only last revisions (both for clone and fetch)
-my $shallow_import = run_git("config --get --bool remote.${remotename}.shallow");
+my $shallow_import = run_git_quoted(["config", "--get", "--bool", "remote.${remotename}.shallow"]);
chomp($shallow_import);
$shallow_import = ($shallow_import eq 'true');
@@ -97,9 +97,9 @@ $shallow_import = ($shallow_import eq 'true');
# Possible values:
# - by_rev: perform one query per new revision on the remote wiki
# - by_page: query each tracked page for new revision
-my $fetch_strategy = run_git("config --get remote.${remotename}.fetchStrategy");
+my $fetch_strategy = run_git_quoted(["config", "--get", "remote.${remotename}.fetchStrategy"]);
if (!$fetch_strategy) {
- $fetch_strategy = run_git('config --get mediawiki.fetchStrategy');
+ $fetch_strategy = run_git_quoted(["config", "--get", "mediawiki.fetchStrategy"]);
}
chomp($fetch_strategy);
if (!$fetch_strategy) {
@@ -123,9 +123,9 @@ my %basetimestamps;
# will get the history with information lost). If the import is
# deterministic, this means everybody gets the same sha1 for each
# MediaWiki revision.
-my $dumb_push = run_git("config --get --bool remote.${remotename}.dumbPush");
+my $dumb_push = run_git_quoted(["config", "--get", "--bool", "remote.${remotename}.dumbPush"]);
if (!$dumb_push) {
- $dumb_push = run_git('config --get --bool mediawiki.dumbPush');
+ $dumb_push = run_git_quoted(["config", "--get", "--bool", "mediawiki.dumbPush"]);
}
chomp($dumb_push);
$dumb_push = ($dumb_push eq 'true');
@@ -369,12 +369,14 @@ sub get_mw_pages {
return %pages;
}
-# usage: $out = run_git("command args");
-# $out = run_git("command args", "raw"); # don't interpret output as UTF-8.
-sub run_git {
+# usage: $out = run_git_quoted(["command", "args", ...]);
+# $out = run_git_quoted(["command", "args", ...], "raw"); # don't interpret output as UTF-8.
+# $out = run_git_quoted_nostderr(["command", "args", ...]); # discard stderr
+# $out = run_git_quoted_nostderr(["command", "args", ...], "raw"); # ditto but raw instead of UTF-8 as above
+sub _run_git {
my $args = shift;
my $encoding = (shift || 'encoding(UTF-8)');
- open(my $git, "-|:${encoding}", "git ${args}")
+ open(my $git, "-|:${encoding}", @$args)
or die "Unable to fork: $!\n";
my $res = do {
local $/ = undef;
@@ -385,6 +387,13 @@ sub run_git {
return $res;
}
+sub run_git_quoted {
+ _run_git(["git", @{$_[0]}], $_[1]);
+}
+
+sub run_git_quoted_nostderr {
+ _run_git(['sh', '-c', 'git "$@" 2>/dev/null', '--', @{$_[0]}], $_[1]);
+}
sub get_all_mediafiles {
my $pages = shift;
@@ -511,8 +520,9 @@ sub download_mw_mediafile {
}
sub get_last_local_revision {
- # Get note regarding last mediawiki revision
- my $note = run_git("notes --ref=${remotename}/mediawiki show refs/mediawiki/${remotename}/master 2>/dev/null");
+ # Get note regarding last mediawiki revision.
+ my $note = run_git_quoted_nostderr(["notes", "--ref=${remotename}/mediawiki",
+ "show", "refs/mediawiki/${remotename}/master"]);
my @note_info = split(/ /, $note);
my $lastrevision_number;
@@ -807,7 +817,10 @@ sub get_more_refs {
sub mw_import {
# multiple import commands can follow each other.
my @refs = (shift, get_more_refs('import'));
+ my $processedRefs;
foreach my $ref (@refs) {
+ next if $processedRefs->{$ref}; # skip duplicates: "import refs/heads/master" being issued twice; TODO: why?
+ $processedRefs->{$ref} = 1;
mw_import_ref($ref);
}
print {*STDOUT} "done\n";
@@ -970,7 +983,7 @@ sub mw_import_revids {
}
sub error_non_fast_forward {
- my $advice = run_git('config --bool advice.pushNonFastForward');
+ my $advice = run_git_quoted(["config", "--bool", "advice.pushNonFastForward"]);
chomp($advice);
if ($advice ne 'false') {
# Native git-push would show this after the summary.
@@ -1014,7 +1027,7 @@ sub mw_upload_file {
}
} else {
# Don't let perl try to interpret file content as UTF-8 => use "raw"
- my $content = run_git("cat-file blob ${new_sha1}", 'raw');
+ my $content = run_git_quoted(["cat-file", "blob", $new_sha1], 'raw');
if ($content ne EMPTY) {
$mediawiki = connect_maybe($mediawiki, $remotename, $url);
$mediawiki->{config}->{upload_url} =
@@ -1084,7 +1097,7 @@ sub mw_push_file {
# with this content instead:
$file_content = DELETED_CONTENT;
} else {
- $file_content = run_git("cat-file blob ${new_sha1}");
+ $file_content = run_git_quoted(["cat-file", "blob", $new_sha1]);
}
$mediawiki = connect_maybe($mediawiki, $remotename, $url);
@@ -1174,10 +1187,10 @@ sub mw_push_revision {
my $mw_revision = $last_remote_revid;
# Get sha1 of commit pointed by local HEAD
- my $HEAD_sha1 = run_git("rev-parse ${local} 2>/dev/null");
+ my $HEAD_sha1 = run_git_quoted_nostderr(["rev-parse", $local]);
chomp($HEAD_sha1);
# Get sha1 of commit pointed by remotes/$remotename/master
- my $remoteorigin_sha1 = run_git("rev-parse refs/remotes/${remotename}/master 2>/dev/null");
+ my $remoteorigin_sha1 = run_git_quoted_nostderr(["rev-parse", "refs/remotes/${remotename}/master"]);
chomp($remoteorigin_sha1);
if ($last_local_revid > 0 &&
@@ -1197,7 +1210,7 @@ sub mw_push_revision {
my $parsed_sha1 = $remoteorigin_sha1;
# Find a path from last MediaWiki commit to pushed commit
print {*STDERR} "Computing path from local to remote ...\n";
- my @local_ancestry = split(/\n/, run_git("rev-list --boundary --parents ${local} ^${parsed_sha1}"));
+ my @local_ancestry = split(/\n/, run_git_quoted(["rev-list", "--boundary", "--parents", $local, "^${parsed_sha1}"]));
my %local_ancestry;
foreach my $line (@local_ancestry) {
if (my ($child, $parents) = $line =~ /^-?([a-f0-9]+) ([a-f0-9 ]+)/) {
@@ -1221,7 +1234,7 @@ sub mw_push_revision {
# No remote mediawiki revision. Export the whole
# history (linearized with --first-parent)
print {*STDERR} "Warning: no common ancestor, pushing complete history\n";
- my $history = run_git("rev-list --first-parent --children ${local}");
+ my $history = run_git_quoted(["rev-list", "--first-parent", "--children", $local]);
my @history = split(/\n/, $history);
@history = @history[1..$#history];
foreach my $line (reverse @history) {
@@ -1233,12 +1246,12 @@ sub mw_push_revision {
foreach my $commit_info_split (@commit_pairs) {
my $sha1_child = @{$commit_info_split}[0];
my $sha1_commit = @{$commit_info_split}[1];
- my $diff_infos = run_git("diff-tree -r --raw -z ${sha1_child} ${sha1_commit}");
+ my $diff_infos = run_git_quoted(["diff-tree", "-r", "--raw", "-z", $sha1_child, $sha1_commit]);
# TODO: we could detect rename, and encode them with a #redirect on the wiki.
# TODO: for now, it's just a delete+add
my @diff_info_list = split(/\0/, $diff_infos);
# Keep the subject line of the commit message as mediawiki comment for the revision
- my $commit_msg = run_git(qq(log --no-walk --format="%s" ${sha1_commit}));
+ my $commit_msg = run_git_quoted(["log", "--no-walk", '--format="%s"', $sha1_commit]);
chomp($commit_msg);
# Push every blob
while (@diff_info_list) {
@@ -1263,7 +1276,10 @@ sub mw_push_revision {
}
}
if (!$dumb_push) {
- run_git(qq(notes --ref=${remotename}/mediawiki add -f -m "mediawiki_revision: ${mw_revision}" ${sha1_commit}));
+ run_git_quoted(["notes", "--ref=${remotename}/mediawiki",
+ "add", "-f", "-m",
+ "mediawiki_revision: ${mw_revision}",
+ $sha1_commit]);
}
}
@@ -1304,7 +1320,7 @@ sub get_mw_namespace_id {
# already cached. Namespaces are stored in form:
# "Name_of_namespace:Id_namespace", ex.: "File:6".
my @temp = split(/\n/,
- run_git("config --get-all remote.${remotename}.namespaceCache"));
+ run_git_quoted(["config", "--get-all", "remote.${remotename}.namespaceCache"]));
chomp(@temp);
foreach my $ns (@temp) {
my ($n, $id) = split(/:/, $ns);
@@ -1358,7 +1374,7 @@ sub get_mw_namespace_id {
# Store explicitly requested namespaces on disk
if (!exists $cached_mw_namespace_id{$name}) {
- run_git(qq(config --add remote.${remotename}.namespaceCache "${name}:${store_id}"));
+ run_git_quoted(["config", "--add", "remote.${remotename}.namespaceCache", "${name}:${store_id}"]);
$cached_mw_namespace_id{$name} = 1;
}
return $id;
diff --git a/contrib/mw-to-git/git-remote-mediawiki.txt b/contrib/mw-to-git/git-remote-mediawiki.txt
index 23b7ef9f62..5da825f61e 100644
--- a/contrib/mw-to-git/git-remote-mediawiki.txt
+++ b/contrib/mw-to-git/git-remote-mediawiki.txt
@@ -4,4 +4,4 @@ objects from mediawiki just as one would do with a classic git
repository thanks to remote-helpers.
For more information, visit the wiki at
-https://github.com/moy/Git-Mediawiki/wiki
+https://github.com/Git-Mediawiki/Git-Mediawiki
diff --git a/contrib/mw-to-git/t/.gitignore b/contrib/mw-to-git/t/.gitignore
index a7a40b4964..2b8dc30c6d 100644
--- a/contrib/mw-to-git/t/.gitignore
+++ b/contrib/mw-to-git/t/.gitignore
@@ -1,4 +1,4 @@
WEB/
-wiki/
+mediawiki/
trash directory.t*/
test-results/
diff --git a/contrib/mw-to-git/t/README b/contrib/mw-to-git/t/README
index 2ee34be7e4..72c4889db7 100644
--- a/contrib/mw-to-git/t/README
+++ b/contrib/mw-to-git/t/README
@@ -14,11 +14,11 @@ install the following packages (Debian/Ubuntu names, may need to be
adapted for another distribution):
* lighttpd
-* php5
-* php5-cgi
-* php5-cli
-* php5-curl
-* php5-sqlite
+* php
+* php-cgi
+* php-cli
+* php-curl
+* php-sqlite
Principles and Technical Choices
--------------------------------
diff --git a/contrib/mw-to-git/t/install-wiki/.gitignore b/contrib/mw-to-git/t/install-wiki/.gitignore
deleted file mode 100644
index b5a2a4408c..0000000000
--- a/contrib/mw-to-git/t/install-wiki/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-wikidb.sqlite
diff --git a/contrib/mw-to-git/t/install-wiki/LocalSettings.php b/contrib/mw-to-git/t/install-wiki/LocalSettings.php
deleted file mode 100644
index 745e47e881..0000000000
--- a/contrib/mw-to-git/t/install-wiki/LocalSettings.php
+++ /dev/null
@@ -1,129 +0,0 @@
-<?php
-# This file was automatically generated by the MediaWiki 1.19.0
-# installer. If you make manual changes, please keep track in case you
-# need to recreate them later.
-#
-# See includes/DefaultSettings.php for all configurable settings
-# and their default values, but don't forget to make changes in _this_
-# file, not there.
-#
-# Further documentation for configuration settings may be found at:
-# http://www.mediawiki.org/wiki/Manual:Configuration_settings
-
-# Protect against web entry
-if ( !defined( 'MEDIAWIKI' ) ) {
- exit;
-}
-
-## Uncomment this to disable output compression
-# $wgDisableOutputCompression = true;
-
-$wgSitename = "Git-MediaWiki-Test";
-$wgMetaNamespace = "Git-MediaWiki-Test";
-
-## The URL base path to the directory containing the wiki;
-## defaults for all runtime URL paths are based off of this.
-## For more information on customizing the URLs please see:
-## http://www.mediawiki.org/wiki/Manual:Short_URL
-$wgScriptPath = "@WG_SCRIPT_PATH@";
-$wgScriptExtension = ".php";
-
-## The protocol and server name to use in fully-qualified URLs
-$wgServer = "@WG_SERVER@";
-
-## The relative URL path to the skins directory
-$wgStylePath = "$wgScriptPath/skins";
-
-## The relative URL path to the logo. Make sure you change this from the default,
-## or else you'll overwrite your logo when you upgrade!
-$wgLogo = "$wgStylePath/common/images/wiki.png";
-
-## UPO means: this is also a user preference option
-
-$wgEnableEmail = true;
-$wgEnableUserEmail = true; # UPO
-
-$wgEmergencyContact = "apache@localhost";
-$wgPasswordSender = "apache@localhost";
-
-$wgEnotifUserTalk = false; # UPO
-$wgEnotifWatchlist = false; # UPO
-$wgEmailAuthentication = true;
-
-## Database settings
-$wgDBtype = "sqlite";
-$wgDBserver = "";
-$wgDBname = "@WG_SQLITE_DATAFILE@";
-$wgDBuser = "";
-$wgDBpassword = "";
-
-# SQLite-specific settings
-$wgSQLiteDataDir = "@WG_SQLITE_DATADIR@";
-
-
-## Shared memory settings
-$wgMainCacheType = CACHE_NONE;
-$wgMemCachedServers = array();
-
-## To enable image uploads, make sure the 'images' directory
-## is writable, then set this to true:
-$wgEnableUploads = true;
-$wgUseImageMagick = true;
-$wgImageMagickConvertCommand ="@CONVERT@";
-$wgFileExtensions[] = 'txt';
-
-# InstantCommons allows wiki to use images from http://commons.wikimedia.org
-$wgUseInstantCommons = false;
-
-## If you use ImageMagick (or any other shell command) on a
-## Linux server, this will need to be set to the name of an
-## available UTF-8 locale
-$wgShellLocale = "en_US.utf8";
-
-## If you want to use image uploads under safe mode,
-## create the directories images/archive, images/thumb and
-## images/temp, and make them all writable. Then uncomment
-## this, if it's not already uncommented:
-#$wgHashedUploadDirectory = false;
-
-## Set $wgCacheDirectory to a writable directory on the web server
-## to make your wiki go slightly faster. The directory should not
-## be publicly accessible from the web.
-#$wgCacheDirectory = "$IP/cache";
-
-# Site language code, should be one of the list in ./languages/Names.php
-$wgLanguageCode = "en";
-
-$wgSecretKey = "1c912bfe3519fb70f5dc523ecc698111cd43d81a11c585b3eefb28f29c2699b7";
-#$wgSecretKey = "@SECRETKEY@";
-
-
-# Site upgrade key. Must be set to a string (default provided) to turn on the
-# web installer while LocalSettings.php is in place
-$wgUpgradeKey = "ddae7dc87cd0a645";
-
-## Default skin: you can change the default skin. Use the internal symbolic
-## names, ie 'standard', 'nostalgia', 'cologneblue', 'monobook', 'vector':
-$wgDefaultSkin = "vector";
-
-## For attaching licensing metadata to pages, and displaying an
-## appropriate copyright notice / icon. GNU Free Documentation
-## License and Creative Commons licenses are supported so far.
-$wgRightsPage = ""; # Set to the title of a wiki page that describes your license/copyright
-$wgRightsUrl = "";
-$wgRightsText = "";
-$wgRightsIcon = "";
-
-# Path to the GNU diff3 utility. Used for conflict resolution.
-$wgDiff3 = "/usr/bin/diff3";
-
-# Query string length limit for ResourceLoader. You should only set this if
-# your web server has a query string length limit (then set it to that limit),
-# or if you have suhosin.get.max_value_length set in php.ini (then set it to
-# that value)
-$wgResourceLoaderMaxQueryLength = -1;
-
-
-
-# End of automatically generated settings.
-# Add more configuration options below.
diff --git a/contrib/mw-to-git/t/install-wiki/db_install.php b/contrib/mw-to-git/t/install-wiki/db_install.php
deleted file mode 100644
index b033849800..0000000000
--- a/contrib/mw-to-git/t/install-wiki/db_install.php
+++ /dev/null
@@ -1,120 +0,0 @@
-<?php
-/**
- * This script generates a SQLite database for a MediaWiki version 1.19.0
- * You must specify the login of the admin (argument 1) and its
- * password (argument 2) and the folder where the database file
- * is located (absolute path in argument 3).
- * It is used by the script install-wiki.sh in order to make easy the
- * installation of a MediaWiki.
- *
- * In order to generate a SQLite database file, MediaWiki ask the user
- * to submit some forms in its web browser. This script simulates this
- * behavior though the functions <get> and <submit>
- *
- */
-$argc = $_SERVER['argc'];
-$argv = $_SERVER['argv'];
-
-$login = $argv[2];
-$pass = $argv[3];
-$tmp = $argv[4];
-$port = $argv[5];
-
-$url = 'http://localhost:'.$port.'/wiki/mw-config/index.php';
-$db_dir = urlencode($tmp);
-$tmp_cookie = tempnam($tmp, "COOKIE_");
-/*
- * Fetches a page with cURL.
- */
-function get($page_name = "") {
- $curl = curl_init();
- $page_name_add = "";
- if ($page_name != "") {
- $page_name_add = '?page='.$page_name;
- }
- $url = $GLOBALS['url'].$page_name_add;
- $tmp_cookie = $GLOBALS['tmp_cookie'];
- curl_setopt($curl, CURLOPT_COOKIEJAR, $tmp_cookie);
- curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
- curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
- curl_setopt($curl, CURLOPT_COOKIEFILE, $tmp_cookie);
- curl_setopt($curl, CURLOPT_HEADER, true);
- curl_setopt($curl, CURLOPT_URL, $url);
-
- $page = curl_exec($curl);
- if (!$page) {
- die("Could not get page: $url\n");
- }
- curl_close($curl);
- return $page;
-}
-
-/*
- * Submits a form with cURL.
- */
-function submit($page_name, $option = "") {
- $curl = curl_init();
- $datapost = 'submit-continue=Continue+%E2%86%92';
- if ($option != "") {
- $datapost = $option.'&'.$datapost;
- }
- $url = $GLOBALS['url'].'?page='.$page_name;
- $tmp_cookie = $GLOBALS['tmp_cookie'];
- curl_setopt($curl, CURLOPT_URL, $url);
- curl_setopt($curl, CURLOPT_POST, true);
- curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
- curl_setopt($curl, CURLOPT_POSTFIELDS, $datapost);
- curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
- curl_setopt($curl, CURLOPT_COOKIEJAR, $tmp_cookie);
- curl_setopt($curl, CURLOPT_COOKIEFILE, $tmp_cookie);
-
- $page = curl_exec($curl);
- if (!$page) {
- die("Could not get page: $url\n");
- }
- curl_close($curl);
- return "$page";
-}
-
-/*
- * Here starts this script: simulates the behavior of the user
- * submitting forms to generates the database file.
- * Note this simulation was made for the MediaWiki version 1.19.0,
- * we can't assume it works with other versions.
- *
- */
-
-$page = get();
-if (!preg_match('/input type="hidden" value="([0-9]+)" name="LanguageRequestTime"/',
- $page, $matches)) {
- echo "Unexpected content for page downloaded:\n";
- echo "$page";
- die;
-};
-$timestamp = $matches[1];
-$language = "LanguageRequestTime=$timestamp&uselang=en&ContLang=en";
-$page = submit('Language', $language);
-
-submit('Welcome');
-
-$db_config = 'DBType=sqlite';
-$db_config = $db_config.'&sqlite_wgSQLiteDataDir='.$db_dir;
-$db_config = $db_config.'&sqlite_wgDBname='.$argv[1];
-submit('DBConnect', $db_config);
-
-$wiki_config = 'config_wgSitename=TEST';
-$wiki_config = $wiki_config.'&config__NamespaceType=site-name';
-$wiki_config = $wiki_config.'&config_wgMetaNamespace=MyWiki';
-$wiki_config = $wiki_config.'&config__AdminName='.$login;
-
-$wiki_config = $wiki_config.'&config__AdminPassword='.$pass;
-$wiki_config = $wiki_config.'&config__AdminPassword2='.$pass;
-
-$wiki_config = $wiki_config.'&wiki__configEmail=email%40email.org';
-$wiki_config = $wiki_config.'&config__SkipOptional=skip';
-submit('Name', $wiki_config);
-submit('Install');
-submit('Install');
-
-unlink($tmp_cookie);
-?>
diff --git a/contrib/mw-to-git/t/t9360-mw-to-git-clone.sh b/contrib/mw-to-git/t/t9360-mw-to-git-clone.sh
index 9106833578..4c39bda7bf 100755
--- a/contrib/mw-to-git/t/t9360-mw-to-git-clone.sh
+++ b/contrib/mw-to-git/t/t9360-mw-to-git-clone.sh
@@ -28,7 +28,7 @@ test_expect_success 'Git clone creates the expected git log with one file' '
git log --format=%s HEAD^..HEAD >log.tmp
) &&
echo "this must be the same" >msg.tmp &&
- diff -b mw_dir_1/log.tmp msg.tmp
+ test_cmp msg.tmp mw_dir_1/log.tmp
'
@@ -50,8 +50,8 @@ test_expect_success 'Git clone creates the expected git log with multiple files'
echo "this must be the same" >>msgDaddy.tmp &&
echo "identical too" >msgDj.tmp &&
echo "identical" >>msgDj.tmp &&
- diff -b mw_dir_2/logDaddy.tmp msgDaddy.tmp &&
- diff -b mw_dir_2/logDj.tmp msgDj.tmp
+ test_cmp msgDaddy.tmp mw_dir_2/logDaddy.tmp &&
+ test_cmp msgDj.tmp mw_dir_2/logDj.tmp
'
@@ -135,7 +135,7 @@ test_expect_success 'Git clone works with one specific page cloned ' '
cd mw_dir_8 &&
echo "this log must stay" >msg.tmp &&
git log --format=%s >log.tmp &&
- diff -b msg.tmp log.tmp
+ test_cmp msg.tmp log.tmp
) &&
wiki_check_content mw_dir_8/Namnam.mw Namnam
'
diff --git a/contrib/mw-to-git/t/t9363-mw-to-git-export-import.sh b/contrib/mw-to-git/t/t9363-mw-to-git-export-import.sh
index 3ff3a09567..6187ec67fa 100755
--- a/contrib/mw-to-git/t/t9363-mw-to-git-export-import.sh
+++ b/contrib/mw-to-git/t/t9363-mw-to-git-export-import.sh
@@ -27,12 +27,12 @@ test_git_reimport () {
# Don't bother with permissions, be administrator by default
test_expect_success 'setup config' '
- git config --global remote.origin.mwLogin WikiAdmin &&
- git config --global remote.origin.mwPassword AdminPass &&
+ git config --global remote.origin.mwLogin "$WIKI_ADMIN" &&
+ git config --global remote.origin.mwPassword "$WIKI_PASSW" &&
test_might_fail git config --global --unset remote.origin.mediaImport
'
-test_expect_success 'git push can upload media (File:) files' '
+test_expect_failure 'git push can upload media (File:) files' '
wiki_reset &&
git clone mediawiki::'"$WIKI_URL"' mw_dir &&
(
@@ -48,13 +48,14 @@ test_expect_success 'git push can upload media (File:) files' '
)
'
-test_expect_success 'git clone works on previously created wiki with media files' '
+test_expect_failure 'git clone works on previously created wiki with media files' '
test_when_finished "rm -rf mw_dir mw_dir_clone" &&
git clone -c remote.origin.mediaimport=true \
mediawiki::'"$WIKI_URL"' mw_dir_clone &&
test_cmp mw_dir_clone/Foo.txt mw_dir/Foo.txt &&
(cd mw_dir_clone && git checkout HEAD^) &&
(cd mw_dir && git checkout HEAD^) &&
+ test_path_is_file mw_dir_clone/Foo.txt &&
test_cmp mw_dir_clone/Foo.txt mw_dir/Foo.txt
'
diff --git a/contrib/mw-to-git/t/test-gitmw-lib.sh b/contrib/mw-to-git/t/test-gitmw-lib.sh
index 3948a00282..64e46c1671 100755
--- a/contrib/mw-to-git/t/test-gitmw-lib.sh
+++ b/contrib/mw-to-git/t/test-gitmw-lib.sh
@@ -13,7 +13,8 @@
. ./test.config
-WIKI_URL=http://"$SERVER_ADDR:$PORT/$WIKI_DIR_NAME"
+WIKI_BASE_URL=http://$SERVER_ADDR:$PORT
+WIKI_URL=$WIKI_BASE_URL/$WIKI_DIR_NAME
CURR_DIR=$(pwd)
TEST_OUTPUT_DIRECTORY=$(pwd)
TEST_DIRECTORY="$CURR_DIR"/../../../t
@@ -65,7 +66,7 @@ test_check_precond () {
GIT_EXEC_PATH=$(cd "$(dirname "$0")" && cd "../.." && pwd)
PATH="$GIT_EXEC_PATH"'/bin-wrapper:'"$PATH"
- if [ ! -d "$WIKI_DIR_INST/$WIKI_DIR_NAME" ];
+ if ! test -d "$WIKI_DIR_INST/$WIKI_DIR_NAME"
then
skip_all='skipping gateway git-mw tests, no mediawiki found'
test_done
@@ -291,27 +292,59 @@ stop_lighttpd () {
test -f "$WEB_TMP/pid" && kill $(cat "$WEB_TMP/pid")
}
-# Create the SQLite database of the MediaWiki. If the database file already
-# exists, it will be deleted.
-# This script should be runned from the directory where $FILES_FOLDER is
-# located.
-create_db () {
- rm -f "$TMP/$DB_FILE"
-
- echo "Generating the SQLite database file. It can take some time ..."
- # Run the php script to generate the SQLite database file
- # with cURL calls.
- php "$FILES_FOLDER/$DB_INSTALL_SCRIPT" $(basename "$DB_FILE" .sqlite) \
- "$WIKI_ADMIN" "$WIKI_PASSW" "$TMP" "$PORT"
-
- if [ ! -f "$TMP/$DB_FILE" ] ; then
- error "Can't create database file $TMP/$DB_FILE. Try to run ./install-wiki.sh delete first."
+wiki_delete_db () {
+ rm -rf \
+ "$FILES_FOLDER_DB"/* || error "Couldn't delete $FILES_FOLDER_DB/"
+}
+
+wiki_delete_db_backup () {
+ rm -rf \
+ "$FILES_FOLDER_POST_INSTALL_DB"/* || error "Couldn't delete $FILES_FOLDER_POST_INSTALL_DB/"
+}
+
+# Install MediaWiki using its install.php script. If the database file
+# already exists, it will be deleted.
+install_mediawiki () {
+
+ localsettings="$WIKI_DIR_INST/$WIKI_DIR_NAME/LocalSettings.php"
+ if test -f "$localsettings"
+ then
+ error "We already installed the wiki, since $localsettings exists" \
+ "perhaps you wanted to run 'delete' first?"
fi
- # Copy the generated database file into the directory the
- # user indicated.
- cp "$TMP/$DB_FILE" "$FILES_FOLDER" ||
- error "Unable to copy $TMP/$DB_FILE to $FILES_FOLDER"
+ wiki_delete_db
+ wiki_delete_db_backup
+ mkdir \
+ "$FILES_FOLDER_DB/" \
+ "$FILES_FOLDER_POST_INSTALL_DB/"
+
+ install_script="$WIKI_DIR_INST/$WIKI_DIR_NAME/maintenance/install.php"
+ echo "Installing MediaWiki using $install_script. This may take some time ..."
+
+ php "$WIKI_DIR_INST/$WIKI_DIR_NAME/maintenance/install.php" \
+ --server $WIKI_BASE_URL \
+ --scriptpath /wiki \
+ --lang en \
+ --dbtype sqlite \
+ --dbpath $PWD/$FILES_FOLDER_DB/ \
+ --pass "$WIKI_PASSW" \
+ Git-MediaWiki-Test \
+ "$WIKI_ADMIN" ||
+ error "Couldn't run $install_script, see errors above. Try to run ./install-wiki.sh delete first."
+ cat <<-'EOF' >>$localsettings
+# Custom settings added by test-gitmw-lib.sh
+#
+# Uploading text files is needed for
+# t9363-mw-to-git-export-import.sh
+$wgEnableUploads = true;
+$wgFileExtensions[] = 'txt';
+EOF
+
+ # Copy the initially generated database file into our backup
+ # folder
+ cp -R "$FILES_FOLDER_DB/"* "$FILES_FOLDER_POST_INSTALL_DB/" ||
+ error "Unable to copy $FILES_FOLDER_DB/* to $FILES_FOLDER_POST_INSTALL_DB/*"
}
# Install a wiki in your web server directory.
@@ -320,30 +353,33 @@ wiki_install () {
start_lighttpd
fi
- SERVER_ADDR=$SERVER_ADDR:$PORT
# In this part, we change directory to $TMP in order to download,
# unpack and copy the files of MediaWiki
(
mkdir -p "$WIKI_DIR_INST/$WIKI_DIR_NAME"
- if [ ! -d "$WIKI_DIR_INST/$WIKI_DIR_NAME" ] ; then
+ if ! test -d "$WIKI_DIR_INST/$WIKI_DIR_NAME"
+ then
error "Folder $WIKI_DIR_INST/$WIKI_DIR_NAME doesn't exist.
Please create it and launch the script again."
fi
- # Fetch MediaWiki's archive if not already present in the TMP directory
+ # Fetch MediaWiki's archive if not already present in the
+ # download directory
+ mkdir -p "$FILES_FOLDER_DOWNLOAD"
MW_FILENAME="mediawiki-$MW_VERSION_MAJOR.$MW_VERSION_MINOR.tar.gz"
- cd "$TMP"
- if [ ! -f $MW_FILENAME ] ; then
+ cd "$FILES_FOLDER_DOWNLOAD"
+ if ! test -f $MW_FILENAME
+ then
echo "Downloading $MW_VERSION_MAJOR.$MW_VERSION_MINOR sources ..."
wget "http://download.wikimedia.org/mediawiki/$MW_VERSION_MAJOR/$MW_FILENAME" ||
error "Unable to download "\
"http://download.wikimedia.org/mediawiki/$MW_VERSION_MAJOR/"\
"$MW_FILENAME. "\
"Please fix your connection and launch the script again."
- echo "$MW_FILENAME downloaded in $(pwd). "\
- "You can delete it later if you want."
+ echo "$MW_FILENAME downloaded in $(pwd)/;" \
+ "you can delete it later if you want."
else
- echo "Reusing existing $MW_FILENAME downloaded in $(pwd)."
+ echo "Reusing existing $MW_FILENAME downloaded in $(pwd)/"
fi
archive_abs_path=$(pwd)/$MW_FILENAME
cd "$WIKI_DIR_INST/$WIKI_DIR_NAME/" ||
@@ -352,48 +388,12 @@ wiki_install () {
error "Unable to extract WikiMedia's files from $archive_abs_path to "\
"$WIKI_DIR_INST/$WIKI_DIR_NAME"
) || exit 1
+ echo Extracted in "$WIKI_DIR_INST/$WIKI_DIR_NAME"
- create_db
-
- # Copy the generic LocalSettings.php in the web server's directory
- # And modify parameters according to the ones set at the top
- # of this script.
- # Note that LocalSettings.php is never modified.
- if [ ! -f "$FILES_FOLDER/LocalSettings.php" ] ; then
- error "Can't find $FILES_FOLDER/LocalSettings.php " \
- "in the current folder. "\
- "Please run the script inside its folder."
- fi
- cp "$FILES_FOLDER/LocalSettings.php" \
- "$FILES_FOLDER/LocalSettings-tmp.php" ||
- error "Unable to copy $FILES_FOLDER/LocalSettings.php " \
- "to $FILES_FOLDER/LocalSettings-tmp.php"
-
- # Parse and set the LocalSettings file of the user according to the
- # CONFIGURATION VARIABLES section at the beginning of this script
- file_swap="$FILES_FOLDER/LocalSettings-swap.php"
- sed "s,@WG_SCRIPT_PATH@,/$WIKI_DIR_NAME," \
- "$FILES_FOLDER/LocalSettings-tmp.php" > "$file_swap"
- mv "$file_swap" "$FILES_FOLDER/LocalSettings-tmp.php"
- sed "s,@WG_SERVER@,http://$SERVER_ADDR," \
- "$FILES_FOLDER/LocalSettings-tmp.php" > "$file_swap"
- mv "$file_swap" "$FILES_FOLDER/LocalSettings-tmp.php"
- sed "s,@WG_SQLITE_DATADIR@,$TMP," \
- "$FILES_FOLDER/LocalSettings-tmp.php" > "$file_swap"
- mv "$file_swap" "$FILES_FOLDER/LocalSettings-tmp.php"
- sed "s,@WG_SQLITE_DATAFILE@,$( basename $DB_FILE .sqlite)," \
- "$FILES_FOLDER/LocalSettings-tmp.php" > "$file_swap"
- mv "$file_swap" "$FILES_FOLDER/LocalSettings-tmp.php"
-
- mv "$FILES_FOLDER/LocalSettings-tmp.php" \
- "$WIKI_DIR_INST/$WIKI_DIR_NAME/LocalSettings.php" ||
- error "Unable to move $FILES_FOLDER/LocalSettings-tmp.php" \
- "in $WIKI_DIR_INST/$WIKI_DIR_NAME"
- echo "File $FILES_FOLDER/LocalSettings.php is set in" \
- " $WIKI_DIR_INST/$WIKI_DIR_NAME"
+ install_mediawiki
echo "Your wiki has been installed. You can check it at
- http://$SERVER_ADDR/$WIKI_DIR_NAME"
+ $WIKI_URL"
}
# Reset the database of the wiki and the password of the admin
@@ -401,12 +401,18 @@ wiki_install () {
# Warning: This function must be called only in a subdirectory of t/ directory
wiki_reset () {
# Copy initial database of the wiki
- if [ ! -f "../$FILES_FOLDER/$DB_FILE" ] ; then
- error "Can't find ../$FILES_FOLDER/$DB_FILE in the current folder."
+ if ! test -d "../$FILES_FOLDER_DB"
+ then
+ error "No wiki database at ../$FILES_FOLDER_DB, not installed yet?"
+ fi
+ if ! test -d "../$FILES_FOLDER_POST_INSTALL_DB"
+ then
+ error "No wiki backup database at ../$FILES_FOLDER_POST_INSTALL_DB, failed installation?"
fi
- cp "../$FILES_FOLDER/$DB_FILE" "$TMP" ||
- error "Can't copy ../$FILES_FOLDER/$DB_FILE in $TMP"
- echo "File $FILES_FOLDER/$DB_FILE is set in $TMP"
+ wiki_delete_db
+ cp -R "../$FILES_FOLDER_POST_INSTALL_DB/"* "../$FILES_FOLDER_DB/" ||
+ error "Can't copy ../$FILES_FOLDER_POST_INSTALL_DB/* to ../$FILES_FOLDER_DB/*"
+ echo "File $FILES_FOLDER_DB/* has been reset"
}
# Delete the wiki created in the web server's directory and all its content
@@ -420,13 +426,7 @@ wiki_delete () {
rm -rf "$WIKI_DIR_INST/$WIKI_DIR_NAME" ||
error "Wiki's directory $WIKI_DIR_INST/" \
"$WIKI_DIR_NAME could not be deleted"
- # Delete the wiki's SQLite database.
- rm -f "$TMP/$DB_FILE" ||
- error "Database $TMP/$DB_FILE could not be deleted."
fi
-
- # Delete the wiki's SQLite database
- rm -f "$TMP/$DB_FILE" || error "Database $TMP/$DB_FILE could not be deleted."
- rm -f "$FILES_FOLDER/$DB_FILE"
- rm -rf "$TMP/mediawiki-$MW_VERSION_MAJOR.$MW_VERSION_MINOR.tar.gz"
+ wiki_delete_db
+ wiki_delete_db_backup
}
diff --git a/contrib/mw-to-git/t/test-gitmw.pl b/contrib/mw-to-git/t/test-gitmw.pl
index 0ff76259fa..c5d687f078 100755
--- a/contrib/mw-to-git/t/test-gitmw.pl
+++ b/contrib/mw-to-git/t/test-gitmw.pl
@@ -24,9 +24,7 @@
use MediaWiki::API;
use Getopt::Long;
-use encoding 'utf8';
use DateTime::Format::ISO8601;
-use open ':encoding(utf8)';
use constant SLASH_REPLACEMENT => "%2F";
#Parsing of the config file
@@ -87,7 +85,7 @@ sub wiki_getpage {
# Replace spaces by underscore in the page name
$pagename =~ s/ /_/g;
$pagename =~ s/\//%2F/g;
- open(my $file, ">$destdir/$pagename.mw");
+ open(my $file, ">:encoding(UTF-8)", "$destdir/$pagename.mw");
print $file "$content";
close ($file);
@@ -172,7 +170,7 @@ sub wiki_getallpagename {
cmlimit => 500 },
)
|| die $mw->{error}->{code}.": ".$mw->{error}->{details};
- open(my $file, ">all.txt");
+ open(my $file, ">:encoding(UTF-8)", "all.txt");
foreach my $page (@{$mw_pages}) {
print $file "$page->{title}\n";
}
@@ -185,7 +183,7 @@ sub wiki_getallpagename {
aplimit => 500,
})
|| die $mw->{error}->{code}.": ".$mw->{error}->{details};
- open(my $file, ">all.txt");
+ open(my $file, ">:encoding(UTF-8)", "all.txt");
foreach my $page (@{$mw_pages}) {
print $file "$page->{title}\n";
}
@@ -214,12 +212,12 @@ my $fct_to_call = shift;
wiki_login($wiki_admin, $wiki_admin_pass);
-my %functions_to_call = qw(
- upload_file wiki_upload_file
- get_page wiki_getpage
- delete_page wiki_delete_page
- edit_page wiki_editpage
- getallpagename wiki_getallpagename
+my %functions_to_call = (
+ upload_file => \&wiki_upload_file,
+ get_page => \&wiki_getpage,
+ delete_page => \&wiki_delete_page,
+ edit_page => \&wiki_editpage,
+ getallpagename => \&wiki_getallpagename,
);
die "$0 ERROR: wrong argument" unless exists $functions_to_call{$fct_to_call};
-&{$functions_to_call{$fct_to_call}}(@ARGV);
+$functions_to_call{$fct_to_call}->(map { utf8::decode($_); $_ } @ARGV);
diff --git a/contrib/mw-to-git/t/test.config b/contrib/mw-to-git/t/test.config
index 5ba0684162..ed10b3e4a4 100644
--- a/contrib/mw-to-git/t/test.config
+++ b/contrib/mw-to-git/t/test.config
@@ -3,15 +3,11 @@ WIKI_DIR_NAME=wiki
# Login and password of the wiki's admin
WIKI_ADMIN=WikiAdmin
-WIKI_PASSW=AdminPass
+WIKI_PASSW=AdminPass1
# Address of the web server
SERVER_ADDR=localhost
-# SQLite database of the wiki, named DB_FILE, is located in TMP
-TMP=/tmp
-DB_FILE=wikidb.sqlite
-
# If LIGHTTPD is not set to true, the script will use the default
# web server running in WIKI_DIR_INST.
WIKI_DIR_INST=/var/www
@@ -28,10 +24,17 @@ WEB=WEB
WEB_TMP=$WEB/tmp
WEB_WWW=$WEB/www
+# Where our configuration for the wiki is located
+FILES_FOLDER=mediawiki
+FILES_FOLDER_DOWNLOAD=$FILES_FOLDER/download
+FILES_FOLDER_DB=$FILES_FOLDER/db
+FILES_FOLDER_POST_INSTALL_DB=$FILES_FOLDER/post-install-db
+
# The variables below are used by the script to install a wiki.
# You should not modify these unless you are modifying the script itself.
-# tested versions: 1.19.X -> 1.21.1
-MW_VERSION_MAJOR=1.21
-MW_VERSION_MINOR=1
-FILES_FOLDER=install-wiki
-DB_INSTALL_SCRIPT=db_install.php
+# tested versions: 1.19.X -> 1.21.1 -> 1.34.2
+#
+# See https://www.mediawiki.org/wiki/Download for what the latest
+# version is.
+MW_VERSION_MAJOR=1.34
+MW_VERSION_MINOR=2
diff --git a/contrib/subtree/Makefile b/contrib/subtree/Makefile
index 6906aae441..6fa7496bfd 100644
--- a/contrib/subtree/Makefile
+++ b/contrib/subtree/Makefile
@@ -25,14 +25,16 @@ ASCIIDOC_HTML = xhtml11
ASCIIDOC_DOCBOOK = docbook
ASCIIDOC_EXTRA =
XMLTO = xmlto
+XMLTO_EXTRA =
ifdef USE_ASCIIDOCTOR
ASCIIDOC = asciidoctor
ASCIIDOC_CONF =
ASCIIDOC_HTML = xhtml5
-ASCIIDOC_DOCBOOK = docbook45
+ASCIIDOC_DOCBOOK = docbook
ASCIIDOC_EXTRA += -I../../Documentation -rasciidoctor-extensions
ASCIIDOC_EXTRA += -alitdd='&\#x2d;&\#x2d;'
+XMLTO_EXTRA += --skip-validation
endif
ifndef SHELL_PATH
@@ -78,7 +80,7 @@ install-html: $(GIT_SUBTREE_HTML)
$(INSTALL) -m 644 $^ $(DESTDIR)$(htmldir)
$(GIT_SUBTREE_DOC): $(GIT_SUBTREE_XML)
- $(XMLTO) -m $(MANPAGE_XSL) man $^
+ $(XMLTO) -m $(MANPAGE_XSL) $(XMLTO_EXTRA) man $^
$(GIT_SUBTREE_XML): $(GIT_SUBTREE_TXT)
$(ASCIIDOC) -b $(ASCIIDOC_DOCBOOK) -d manpage $(ASCIIDOC_CONF) \
diff --git a/contrib/subtree/git-subtree.txt b/contrib/subtree/git-subtree.txt
index 352deda69d..0db02fe3c0 100644
--- a/contrib/subtree/git-subtree.txt
+++ b/contrib/subtree/git-subtree.txt
@@ -139,12 +139,12 @@ OPTIONS
-m <message>::
--message=<message>::
- This option is only valid for add, merge and pull (unsure).
+ This option is only valid for add, merge, pull, and split --rejoin.
Specify <message> as the commit message for the merge commit.
-OPTIONS FOR add, merge, push, pull
-----------------------------------
+OPTIONS FOR add, merge, and pull
+--------------------------------
--squash::
This option is only valid for add, merge, and pull
commands.
diff --git a/contrib/svn-fe/.gitignore b/contrib/svn-fe/.gitignore
deleted file mode 100644
index 02a7791585..0000000000
--- a/contrib/svn-fe/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-/*.xml
-/*.1
-/*.html
-/svn-fe
diff --git a/contrib/svn-fe/Makefile b/contrib/svn-fe/Makefile
deleted file mode 100644
index e8651aaf4b..0000000000
--- a/contrib/svn-fe/Makefile
+++ /dev/null
@@ -1,105 +0,0 @@
-all:: svn-fe$X
-
-CC = cc
-RM = rm -f
-MV = mv
-
-CFLAGS = -g -O2 -Wall
-LDFLAGS =
-EXTLIBS = -lz
-
-include ../../config.mak.uname
--include ../../config.mak.autogen
--include ../../config.mak
-
-ifeq ($(uname_S),Darwin)
- ifndef NO_FINK
- ifeq ($(shell test -d /sw/lib && echo y),y)
- CFLAGS += -I/sw/include
- LDFLAGS += -L/sw/lib
- endif
- endif
- ifndef NO_DARWIN_PORTS
- ifeq ($(shell test -d /opt/local/lib && echo y),y)
- CFLAGS += -I/opt/local/include
- LDFLAGS += -L/opt/local/lib
- endif
- endif
-endif
-
-ifndef NO_OPENSSL
- EXTLIBS += -lssl
- ifdef NEEDS_CRYPTO_WITH_SSL
- EXTLIBS += -lcrypto
- endif
-endif
-
-ifndef NO_PTHREADS
- CFLAGS += $(PTHREADS_CFLAGS)
- EXTLIBS += $(PTHREAD_LIBS)
-endif
-
-ifdef HAVE_CLOCK_GETTIME
- CFLAGS += -DHAVE_CLOCK_GETTIME
- EXTLIBS += -lrt
-endif
-
-ifdef NEEDS_LIBICONV
- EXTLIBS += -liconv
-endif
-
-GIT_LIB = ../../libgit.a
-VCSSVN_LIB = ../../vcs-svn/lib.a
-XDIFF_LIB = ../../xdiff/lib.a
-
-LIBS = $(VCSSVN_LIB) $(GIT_LIB) $(XDIFF_LIB)
-
-QUIET_SUBDIR0 = +$(MAKE) -C # space to separate -C and subdir
-QUIET_SUBDIR1 =
-
-ifneq ($(findstring $(MAKEFLAGS),w),w)
-PRINT_DIR = --no-print-directory
-else # "make -w"
-NO_SUBDIR = :
-endif
-
-ifneq ($(findstring $(MAKEFLAGS),s),s)
-ifndef V
- QUIET_CC = @echo ' ' CC $@;
- QUIET_LINK = @echo ' ' LINK $@;
- QUIET_SUBDIR0 = +@subdir=
- QUIET_SUBDIR1 = ;$(NO_SUBDIR) echo ' ' SUBDIR $$subdir; \
- $(MAKE) $(PRINT_DIR) -C $$subdir
-endif
-endif
-
-svn-fe$X: svn-fe.o $(VCSSVN_LIB) $(XDIFF_LIB) $(GIT_LIB)
- $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $(EXTLIBS) -o $@ svn-fe.o $(LIBS)
-
-svn-fe.o: svn-fe.c ../../vcs-svn/svndump.h
- $(QUIET_CC)$(CC) $(CFLAGS) -I../../vcs-svn -o $*.o -c $<
-
-svn-fe.html: svn-fe.txt
- $(QUIET_SUBDIR0)../../Documentation $(QUIET_SUBDIR1) \
- MAN_TXT=../contrib/svn-fe/svn-fe.txt \
- ../contrib/svn-fe/$@
-
-svn-fe.1: svn-fe.txt
- $(QUIET_SUBDIR0)../../Documentation $(QUIET_SUBDIR1) \
- MAN_TXT=../contrib/svn-fe/svn-fe.txt \
- ../contrib/svn-fe/$@
- $(MV) ../../Documentation/svn-fe.1 .
-
-../../vcs-svn/lib.a: FORCE
- $(QUIET_SUBDIR0)../.. $(QUIET_SUBDIR1) vcs-svn/lib.a
-
-../../xdiff/lib.a: FORCE
- $(QUIET_SUBDIR0)../.. $(QUIET_SUBDIR1) xdiff/lib.a
-
-../../libgit.a: FORCE
- $(QUIET_SUBDIR0)../.. $(QUIET_SUBDIR1) libgit.a
-
-clean:
- $(RM) svn-fe$X svn-fe.o svn-fe.html svn-fe.xml svn-fe.1
-
-.PHONY: all clean FORCE
diff --git a/contrib/svn-fe/svn-fe.c b/contrib/svn-fe/svn-fe.c
deleted file mode 100644
index f363505abb..0000000000
--- a/contrib/svn-fe/svn-fe.c
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * This file is in the public domain.
- * You may freely use, modify, distribute, and relicense it.
- */
-
-#include <stdlib.h>
-#include "svndump.h"
-
-int main(int argc, char **argv)
-{
- if (svndump_init(NULL))
- return 1;
- svndump_read((argc > 1) ? argv[1] : NULL, "refs/heads/master",
- "refs/notes/svn/revs");
- svndump_deinit();
- svndump_reset();
- return 0;
-}
diff --git a/contrib/svn-fe/svn-fe.txt b/contrib/svn-fe/svn-fe.txt
deleted file mode 100644
index 19333fc8df..0000000000
--- a/contrib/svn-fe/svn-fe.txt
+++ /dev/null
@@ -1,71 +0,0 @@
-svn-fe(1)
-=========
-
-NAME
-----
-svn-fe - convert an SVN "dumpfile" to a fast-import stream
-
-SYNOPSIS
---------
-[verse]
-mkfifo backchannel &&
-svnadmin dump --deltas REPO |
- svn-fe [url] 3<backchannel |
- git fast-import --cat-blob-fd=3 3>backchannel
-
-DESCRIPTION
------------
-
-Converts a Subversion dumpfile into input suitable for
-git-fast-import(1) and similar importers. REPO is a path to a
-Subversion repository mirrored on the local disk. Remote Subversion
-repositories can be mirrored on local disk using the `svnsync`
-command.
-
-Note: this tool is very young. The details of its commandline
-interface may change in backward incompatible ways.
-
-INPUT FORMAT
-------------
-Subversion's repository dump format is documented in full in
-`notes/dump-load-format.txt` from the Subversion source tree.
-Files in this format can be generated using the 'svnadmin dump' or
-'svk admin dump' command.
-
-OUTPUT FORMAT
--------------
-The fast-import format is documented by the git-fast-import(1)
-manual page.
-
-NOTES
------
-Subversion dumps do not record a separate author and committer for
-each revision, nor do they record a separate display name and email
-address for each author. Like git-svn(1), 'svn-fe' will use the name
-
----------
-user <user@UUID>
----------
-
-as committer, where 'user' is the value of the `svn:author` property
-and 'UUID' the repository's identifier.
-
-To support incremental imports, 'svn-fe' puts a `git-svn-id` line at
-the end of each commit log message if passed a URL on the command
-line. This line has the form `git-svn-id: URL@REVNO UUID`.
-
-The resulting repository will generally require further processing
-to put each project in its own repository and to separate the history
-of each branch. The 'git filter-repo --subdirectory-filter' command
-may be useful for this purpose.
-
-BUGS
-----
-Empty directories and unknown properties are silently discarded.
-
-The exit status does not reflect whether an error was detected.
-
-SEE ALSO
---------
-git-svn(1), svn2git(1), svk(1), git-filter-repo(1), git-fast-import(1),
-https://svn.apache.org/repos/asf/subversion/trunk/notes/dump-load-format.txt
diff --git a/contrib/svn-fe/svnrdump_sim.py b/contrib/svn-fe/svnrdump_sim.py
deleted file mode 100755
index 8a3cee6175..0000000000
--- a/contrib/svn-fe/svnrdump_sim.py
+++ /dev/null
@@ -1,68 +0,0 @@
-#!/usr/bin/env python
-"""
-Simulates svnrdump by replaying an existing dump from a file, taking care
-of the specified revision range.
-To simulate incremental imports the environment variable SVNRMAX can be set
-to the highest revision that should be available.
-"""
-import sys
-import os
-
-if sys.hexversion < 0x02040000:
- # The limiter is the ValueError() calls. This may be too conservative
- sys.stderr.write("svnrdump-sim.py: requires Python 2.4 or later.\n")
- sys.exit(1)
-
-
-def getrevlimit():
- var = 'SVNRMAX'
- if var in os.environ:
- return os.environ[var]
- return None
-
-
-def writedump(url, lower, upper):
- if url.startswith('sim://'):
- filename = url[6:]
- if filename[-1] == '/':
- filename = filename[:-1] # remove terminating slash
- else:
- raise ValueError('sim:// url required')
- f = open(filename, 'r')
- state = 'header'
- wroterev = False
- while(True):
- l = f.readline()
- if l == '':
- break
- if state == 'header' and l.startswith('Revision-number: '):
- state = 'prefix'
- if state == 'prefix' and l == 'Revision-number: %s\n' % lower:
- state = 'selection'
- if not upper == 'HEAD' and state == 'selection' and \
- l == 'Revision-number: %s\n' % upper:
- break
-
- if state == 'header' or state == 'selection':
- if state == 'selection':
- wroterev = True
- sys.stdout.write(l)
- return wroterev
-
-if __name__ == "__main__":
- if not (len(sys.argv) in (3, 4, 5)):
- print("usage: %s dump URL -rLOWER:UPPER")
- sys.exit(1)
- if not sys.argv[1] == 'dump':
- raise NotImplementedError('only "dump" is supported.')
- url = sys.argv[2]
- r = ('0', 'HEAD')
- if len(sys.argv) == 4 and sys.argv[3][0:2] == '-r':
- r = sys.argv[3][2:].lstrip().split(':')
- if not getrevlimit() is None:
- r[1] = getrevlimit()
- if writedump(url, r[0], r[1]):
- ret = 0
- else:
- ret = 1
- sys.exit(ret)