diff options
Diffstat (limited to 'contrib')
48 files changed, 906 insertions, 49 deletions
diff --git a/contrib/buildsystems/CMakeLists.txt b/contrib/buildsystems/CMakeLists.txt index 10dc54fdcb..25b495fa73 100644 --- a/contrib/buildsystems/CMakeLists.txt +++ b/contrib/buildsystems/CMakeLists.txt @@ -1001,10 +1001,14 @@ parse_makefile_for_sources(unit-test_SOURCES ${CMAKE_SOURCE_DIR}/Makefile "UNIT_ list(TRANSFORM unit-test_SOURCES REPLACE "\\$\\(UNIT_TEST_DIR\\)/" "${CMAKE_SOURCE_DIR}/t/unit-tests/") add_library(unit-test-lib STATIC ${unit-test_SOURCES}) +parse_makefile_for_sources(clar-test_SOURCES ${CMAKE_SOURCE_DIR}/Makefile "CLAR_TEST_OBJS") +list(TRANSFORM clar-test_SOURCES REPLACE "\\$\\(UNIT_TEST_DIR\\)/" "${CMAKE_SOURCE_DIR}/t/unit-tests/") +add_library(clar-test-lib STATIC ${clar-test_SOURCES}) + parse_makefile_for_scripts(unit_test_PROGRAMS "UNIT_TEST_PROGRAMS" "") foreach(unit_test ${unit_test_PROGRAMS}) add_executable("${unit_test}" "${CMAKE_SOURCE_DIR}/t/unit-tests/${unit_test}.c") - target_link_libraries("${unit_test}" unit-test-lib common-main) + target_link_libraries("${unit_test}" unit-test-lib clar-test-lib common-main) set_target_properties("${unit_test}" PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/t/unit-tests/bin) if(MSVC) @@ -1046,13 +1050,13 @@ add_custom_command(OUTPUT "${CMAKE_BINARY_DIR}/t/unit-tests/clar.suite" VERBATIM) add_library(unit-tests-lib ${clar_test_SUITES} - "${CMAKE_SOURCE_DIR}/t/unit-tests/clar/clar.c" "${CMAKE_BINARY_DIR}/t/unit-tests/clar-decls.h" "${CMAKE_BINARY_DIR}/t/unit-tests/clar.suite" ) +target_include_directories(clar-test-lib PUBLIC "${CMAKE_BINARY_DIR}/t/unit-tests") target_include_directories(unit-tests-lib PUBLIC "${CMAKE_BINARY_DIR}/t/unit-tests") -add_executable(unit-tests "${CMAKE_SOURCE_DIR}/t/unit-tests/unit-test.c") -target_link_libraries(unit-tests unit-tests-lib common-main) +add_executable(unit-tests) +target_link_libraries(unit-tests unit-tests-lib clar-test-lib common-main) set_target_properties(unit-tests PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/t/unit-tests/bin) if(MSVC) @@ -1169,14 +1173,13 @@ string(REPLACE "@GIT_PERF_MAKE_COMMAND@" "" git_build_options "${git_build_optio string(REPLACE "@GIT_PERF_MAKE_OPTS@" "" git_build_options "${git_build_options}") string(REPLACE "@GIT_PERF_REPEAT_COUNT@" "" git_build_options "${git_build_options}") string(REPLACE "@GIT_PERF_REPO@" "" git_build_options "${git_build_options}") +string(REPLACE "@GIT_SOURCE_DIR@" "${CMAKE_SOURCE_DIR}" git_build_options "${git_build_options}") string(REPLACE "@GIT_TEST_CMP@" "" git_build_options "${git_build_options}") string(REPLACE "@GIT_TEST_CMP_USE_COPIED_CONTEXT@" "" git_build_options "${git_build_options}") string(REPLACE "@GIT_TEST_GITPERLLIB@" "'${CMAKE_BINARY_DIR}/perl/build/lib'" git_build_options "${git_build_options}") string(REPLACE "@GIT_TEST_INDEX_VERSION@" "" git_build_options "${git_build_options}") -string(REPLACE "@GIT_TEST_MERGE_TOOLS_DIR@" "'${CMAKE_BINARY_DIR}/mergetools'" git_build_options "${git_build_options}") string(REPLACE "@GIT_TEST_OPTS@" "" git_build_options "${git_build_options}") string(REPLACE "@GIT_TEST_PERL_FATAL_WARNINGS@" "" git_build_options "${git_build_options}") -string(REPLACE "@GIT_TEST_POPATH@" "'${CMAKE_BINARY_DIR}/po'" git_build_options "${git_build_options}") string(REPLACE "@GIT_TEST_TEMPLATE_DIR@" "'${CMAKE_BINARY_DIR}/templates/blt'" git_build_options "${git_build_options}") string(REPLACE "@GIT_TEST_TEXTDOMAINDIR@" "'${CMAKE_BINARY_DIR}/po/build/locale'" git_build_options "${git_build_options}") string(REPLACE "@GIT_TEST_UTF8_LOCALE@" "" git_build_options "${git_build_options}") @@ -1205,6 +1208,7 @@ string(REPLACE "@TEST_OUTPUT_DIRECTORY@" "" git_build_options "${git_build_optio string(REPLACE "@TEST_SHELL_PATH@" "'${TEST_SHELL_PATH}'" git_build_options "${git_build_options}") string(REPLACE "@USE_GETTEXT_SCHEME@" "" git_build_options "${git_build_options}") string(REPLACE "@USE_LIBPCRE2@" "" git_build_options "${git_build_options}") +string(REPLACE "@WITH_BREAKING_CHANGES@" "" git_build_options "${git_build_options}") string(REPLACE "@X@" "${EXE_EXTENSION}" git_build_options "${git_build_options}") if(USE_VCPKG) string(APPEND git_build_options "PATH=\"$PATH:$TEST_DIRECTORY/../compat/vcbuild/vcpkg/installed/x64-windows/bin\"\n") diff --git a/contrib/coccinelle/meson.build b/contrib/coccinelle/meson.build new file mode 100644 index 0000000000..ea054c924f --- /dev/null +++ b/contrib/coccinelle/meson.build @@ -0,0 +1,94 @@ +coccinelle_opt = get_option('coccinelle').require( + fs.exists(meson.project_source_root() / '.git'), + error_message: 'coccinelle can only be run from a git checkout', +) + +spatch = find_program('spatch', required: coccinelle_opt) +if not spatch.found() + subdir_done() +endif + +third_party_sources = [ + ':!contrib', + ':!compat/inet_ntop.c', + ':!compat/inet_pton.c', + ':!compat/nedmalloc', + ':!compat/obstack.*', + ':!compat/poll', + ':!compat/regex', + ':!sha1collisiondetection', + ':!sha1dc', + ':!t/unit-tests/clar', + ':!t/unit-tests/clar', + ':!t/t[0-9][0-9][0-9][0-9]*', +] + +rules = [ + 'array.cocci', + 'commit.cocci', + 'config_fn_ctx.pending.cocci', + 'equals-null.cocci', + 'flex_alloc.cocci', + 'free.cocci', + 'git_config_number.cocci', + 'hashmap.cocci', + 'index-compatibility.cocci', + 'object_id.cocci', + 'preincr.cocci', + 'qsort.cocci', + 'refs.cocci', + 'strbuf.cocci', + 'swap.cocci', + 'the_repository.cocci', + 'xcalloc.cocci', + 'xopen.cocci', + 'xstrdup_or_null.cocci', + 'xstrncmpz.cocci', +] + +concatenated_rules = custom_target( + command: [ + 'cat', '@INPUT@', + ], + input: rules, + output: 'rules.cocci', + capture: true, +) + +sources = [ ] +foreach source : run_command(git, '-C', meson.project_source_root(), 'ls-files', '--deduplicate', '*.c', third_party_sources, check: true).stdout().split() + sources += source +endforeach + +headers = [ ] +foreach header : run_command(git, '-C', meson.project_source_root(), 'ls-files', '--deduplicate', '*.h', third_party_sources, check: true).stdout().split() + headers += meson.project_source_root() / header +endforeach + +patches = [ ] +foreach source : sources + patches += custom_target( + command: [ + spatch, + '--all-includes', + '--sp-file', concatenated_rules, + '--patch', meson.project_source_root(), + '@INPUT@', + ], + input: meson.project_source_root() / source, + output: source.underscorify() + '.patch', + capture: true, + depend_files: headers, + ) +endforeach + +concatenated_patch = custom_target( + command: [ + 'cat', '@INPUT@', + ], + input: patches, + output: 'cocci.patch', + capture: true, +) + +alias_target('coccicheck', concatenated_patch) diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index b3b6aa3bae..e3d88b0672 100644 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -234,6 +234,17 @@ __git_dequote () done } +# Prints the number of slash-separated components in a path. +# 1: Path to count components of. +__git_count_path_components () +{ + local path="$1" + local relative="${path#/}" + relative="${relative%/}" + local slashes="/${relative//[^\/]}" + echo "${#slashes}" +} + # The following function is based on code from: # # bash_completion - programmable completion functions for bash 3.2+ @@ -779,16 +790,39 @@ __git_tags () __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" \ - ${GIT_COMPLETION_IGNORE_CASE+--ignore-case} \ - "refs/remotes/*/$cur_*" "refs/remotes/*/$cur_*/**" | \ - uniq -u + local awk_script=' + function casemap(s) { + if (ENVIRON["IGNORE_CASE"]) + return tolower(s) + else + return s + } + BEGIN { + split(ENVIRON["REMOTES"], remotes, /\n/) + for (i in remotes) + remotes[i] = "refs/remotes/" casemap(remotes[i]) + cur_ = casemap(ENVIRON["CUR_"]) + } + { + ref_case = casemap($0) + for (i in remotes) { + if (index(ref_case, remotes[i] "/" cur_) == 1) { + branch = substr($0, length(remotes[i] "/") + 1) + print ENVIRON["PFX"] branch ENVIRON["SFX"] + break + } + } + } + ' + __git for-each-ref --format='%(refname)' refs/remotes/ | + PFX="$pfx" SFX="$sfx" CUR_="$cur_" \ + IGNORE_CASE=${GIT_COMPLETION_IGNORE_CASE+1} \ + REMOTES="$(__git_remotes | sort -r)" awk "$awk_script" | + sort | uniq -u } # Lists refs from the local (by default) or from a remote repository. @@ -894,7 +928,8 @@ __git_refs () case "HEAD" in $match*|$umatch*) echo "${pfx}HEAD$sfx" ;; esac - __git for-each-ref --format="$fer_pfx%(refname:strip=3)$sfx" \ + local strip="$(__git_count_path_components "refs/remotes/$remote")" + __git for-each-ref --format="$fer_pfx%(refname:strip=$strip)$sfx" \ ${GIT_COMPLETION_IGNORE_CASE+--ignore-case} \ "refs/remotes/$remote/$match*" \ "refs/remotes/$remote/$match*/**" @@ -2737,12 +2772,17 @@ __git_compute_config_vars_all () __git_config_vars_all="$(git --no-pager help --config)" } +__git_indirect() +{ + eval printf '%s' "\"\$$1\"" +} + __git_compute_first_level_config_vars_for_section () { local section="$1" __git_compute_config_vars local this_section="__git_first_level_config_vars_for_section_${section}" - test -n "${!this_section}" || + test -n "$(__git_indirect "${this_section}")" || printf -v "__git_first_level_config_vars_for_section_${section}" %s \ "$(echo "$__git_config_vars" | awk -F. "/^${section}\.[a-z]/ { print \$2 }")" } @@ -2752,7 +2792,7 @@ __git_compute_second_level_config_vars_for_section () local section="$1" __git_compute_config_vars_all local this_section="__git_second_level_config_vars_for_section_${section}" - test -n "${!this_section}" || + test -n "$(__git_indirect "${this_section}")" || printf -v "__git_second_level_config_vars_for_section_${section}" %s \ "$(echo "$__git_config_vars_all" | awk -F. "/^${section}\.</ { print \$3 }")" } @@ -2907,7 +2947,7 @@ __git_complete_config_variable_name () local section="${pfx%.*.}" __git_compute_second_level_config_vars_for_section "${section}" local this_section="__git_second_level_config_vars_for_section_${section}" - __gitcomp "${!this_section}" "$pfx" "$cur_" "$sfx" + __gitcomp "$(__git_indirect "${this_section}")" "$pfx" "$cur_" "$sfx" return ;; branch.*) @@ -2917,7 +2957,7 @@ __git_complete_config_variable_name () __gitcomp_direct "$(__git_heads "$pfx" "$cur_" ".")" __git_compute_first_level_config_vars_for_section "${section}" local this_section="__git_first_level_config_vars_for_section_${section}" - __gitcomp_nl_append "${!this_section}" "$pfx" "$cur_" "${sfx:- }" + __gitcomp_nl_append "$(__git_indirect "${this_section}")" "$pfx" "$cur_" "${sfx:- }" return ;; pager.*) @@ -2934,7 +2974,7 @@ __git_complete_config_variable_name () __gitcomp_nl "$(__git_remotes)" "$pfx" "$cur_" "." __git_compute_first_level_config_vars_for_section "${section}" local this_section="__git_first_level_config_vars_for_section_${section}" - __gitcomp_nl_append "${!this_section}" "$pfx" "$cur_" "${sfx:- }" + __gitcomp_nl_append "$(__git_indirect "${this_section}")" "$pfx" "$cur_" "${sfx:- }" return ;; submodule.*) @@ -2944,7 +2984,7 @@ __git_complete_config_variable_name () __gitcomp_nl "$(__git config -f "$(__git rev-parse --show-toplevel)/.gitmodules" --get-regexp 'submodule.*.path' | awk -F. '{print $2}')" "$pfx" "$cur_" "." __git_compute_first_level_config_vars_for_section "${section}" local this_section="__git_first_level_config_vars_for_section_${section}" - __gitcomp_nl_append "${!this_section}" "$pfx" "$cur_" "${sfx:- }" + __gitcomp_nl_append "$(__git_indirect "${this_section}")" "$pfx" "$cur_" "${sfx:- }" return ;; *.*) diff --git a/contrib/contacts/Makefile b/contrib/contacts/Makefile index a2990f0dcb..9c4ca4f3bc 100644 --- a/contrib/contacts/Makefile +++ b/contrib/contacts/Makefile @@ -34,7 +34,7 @@ GIT_CONTACTS := git-contacts GIT_CONTACTS_DOC := git-contacts.1 GIT_CONTACTS_XML := git-contacts.xml -GIT_CONTACTS_TXT := git-contacts.txt +GIT_CONTACTS_TXT := git-contacts.adoc GIT_CONTACTS_HTML := git-contacts.html doc: $(GIT_CONTACTS_DOC) $(GIT_CONTACTS_HTML) diff --git a/contrib/contacts/git-contacts.txt b/contrib/contacts/git-contacts.adoc index dd914d1261..dd914d1261 100644 --- a/contrib/contacts/git-contacts.txt +++ b/contrib/contacts/git-contacts.adoc diff --git a/contrib/contacts/meson.build b/contrib/contacts/meson.build new file mode 100644 index 0000000000..73d82dfe52 --- /dev/null +++ b/contrib/contacts/meson.build @@ -0,0 +1,55 @@ +custom_target( + input: 'git-contacts', + output: 'git-contacts', + command: generate_perl_command, + depends: [git_version_file], + install: true, + install_dir: get_option('libexecdir') / 'git-core', +) + +if get_option('docs').contains('man') + contacts_xml = custom_target( + command: asciidoc_common_options + [ + '--backend=' + asciidoc_docbook, + '--doctype=manpage', + '--out-file=@OUTPUT@', + '@INPUT@', + ], + depends: documentation_deps, + input: 'git-contacts.adoc', + output: 'git-contacts.xml', + ) + + custom_target( + command: [ + xmlto, + '-m', '@INPUT@', + 'man', + contacts_xml, + '-o', + meson.current_build_dir(), + ] + xmlto_extra, + input: [ + '../../Documentation/manpage-normal.xsl', + ], + output: 'git-contacts.1', + install: true, + install_dir: get_option('mandir') / 'man1', + ) +endif + +if get_option('docs').contains('html') + custom_target( + command: asciidoc_common_options + [ + '--backend=' + asciidoc_html, + '--doctype=manpage', + '--out-file=@OUTPUT@', + '@INPUT@', + ], + depends: documentation_deps, + input: 'git-contacts.adoc', + output: 'git-contacts.html', + install: true, + install_dir: get_option('datadir') / 'doc/git-doc', + ) +endif diff --git a/contrib/credential/libsecret/Makefile b/contrib/credential/libsecret/Makefile index 3e67552cc5..97ce9c92fb 100644 --- a/contrib/credential/libsecret/Makefile +++ b/contrib/credential/libsecret/Makefile @@ -1,3 +1,6 @@ +# The default target of this Makefile is... +all:: + MAIN:=git-credential-libsecret all:: $(MAIN) diff --git a/contrib/credential/libsecret/git-credential-libsecret.c b/contrib/credential/libsecret/git-credential-libsecret.c index 90034d0cf1..941b2afd5e 100644 --- a/contrib/credential/libsecret/git-credential-libsecret.c +++ b/contrib/credential/libsecret/git-credential-libsecret.c @@ -59,10 +59,10 @@ static void credential_clear(struct credential *c); /* ----------------- Secret Service functions ----------------- */ static const SecretSchema schema = { - "org.git.Password", + .name = "org.git.Password", /* Ignore schema name during search for backwards compatibility */ - SECRET_SCHEMA_DONT_MATCH_NAME, - { + .flags = SECRET_SCHEMA_DONT_MATCH_NAME, + .attributes = { /* * libsecret assumes attribute values are non-confidential and * unchanging, so we can't include oauth_refresh_token or @@ -168,7 +168,7 @@ static int keyring_get(struct credential *c) g_free(c->password); c->password = g_strdup(""); } - for (int i = 1; i < g_strv_length(parts); i++) { + for (guint i = 1; i < g_strv_length(parts); i++) { if (g_str_has_prefix(parts[i], "password_expiry_utc=")) { g_free(c->password_expiry_utc); c->password_expiry_utc = g_strdup(&parts[i][20]); @@ -424,7 +424,7 @@ int main(int argc, char *argv[]) struct credential_operation const *try_op = credential_helper_ops; struct credential cred = CREDENTIAL_INIT; - if (!argv[1]) { + if (argc < 2 || !*argv[1]) { usage(argv[0]); exit(EXIT_FAILURE); } diff --git a/contrib/credential/libsecret/meson.build b/contrib/credential/libsecret/meson.build new file mode 100644 index 0000000000..0137660fe0 --- /dev/null +++ b/contrib/credential/libsecret/meson.build @@ -0,0 +1,9 @@ +executable('git-credential-libsecret', + sources: 'git-credential-libsecret.c', + dependencies: [ + dependency('glib-2.0'), + dependency('libsecret-1'), + ], + install: true, + install_dir: get_option('libexecdir') / 'git-core', +) diff --git a/contrib/credential/meson.build b/contrib/credential/meson.build new file mode 100644 index 0000000000..4216296ae0 --- /dev/null +++ b/contrib/credential/meson.build @@ -0,0 +1,3 @@ +foreach helper : get_option('credential_helpers') + subdir(helper) +endforeach diff --git a/contrib/credential/netrc/meson.build b/contrib/credential/netrc/meson.build new file mode 100644 index 0000000000..3d74547c8a --- /dev/null +++ b/contrib/credential/netrc/meson.build @@ -0,0 +1,22 @@ +credential_netrc = custom_target( + input: 'git-credential-netrc.perl', + output: 'git-credential-netrc', + command: generate_perl_command, + depends: [git_version_file], + install: true, + install_dir: get_option('libexecdir') / 'git-core', +) + +if get_option('tests') + credential_netrc_testenv = test_environment + credential_netrc_testenv.set('CREDENTIAL_NETRC_PATH', credential_netrc.full_path()) + + test('t-git-credential-netrc', + shell, + args: [ meson.current_source_dir() / 't-git-credential-netrc.sh' ], + workdir: meson.current_source_dir(), + env: credential_netrc_testenv, + depends: test_dependencies + bin_wrappers + [credential_netrc], + timeout: 0, + ) +endif diff --git a/contrib/credential/netrc/t-git-credential-netrc.sh b/contrib/credential/netrc/t-git-credential-netrc.sh index bf2777308a..1b7b8b3a9a 100755 --- a/contrib/credential/netrc/t-git-credential-netrc.sh +++ b/contrib/credential/netrc/t-git-credential-netrc.sh @@ -15,7 +15,7 @@ export PERL5LIB="$GITPERLLIB" test_expect_success 'git-credential-netrc' ' - perl "$GIT_BUILD_DIR"/contrib/credential/netrc/test.pl + perl "$GIT_SOURCE_DIR"/contrib/credential/netrc/test.pl ' test_done diff --git a/contrib/credential/netrc/test.pl b/contrib/credential/netrc/test.pl index c0fb3718b2..67a0ede564 100755 --- a/contrib/credential/netrc/test.pl +++ b/contrib/credential/netrc/test.pl @@ -15,10 +15,11 @@ BEGIN { my @global_credential_args = @ARGV; my $scriptDir = dirname rel2abs $0; -my ($netrc, $netrcGpg, $gcNetrc) = map { catfile $scriptDir, $_; } +my ($netrc, $netrcGpg) = map { catfile $scriptDir, $_; } qw(test.netrc - test.netrc.gpg - git-credential-netrc); + test.netrc.gpg); +my $gcNetrc = $ENV{CREDENTIAL_NETRC_PATH} || catfile $scriptDir, qw(git-credential-netrc); + local $ENV{PATH} = join ':' , $scriptDir , $ENV{PATH} diff --git a/contrib/credential/osxkeychain/Makefile b/contrib/credential/osxkeychain/Makefile index 238f5f8c36..0948297e20 100644 --- a/contrib/credential/osxkeychain/Makefile +++ b/contrib/credential/osxkeychain/Makefile @@ -1,3 +1,4 @@ +# The default target of this Makefile is... all:: git-credential-osxkeychain CC = gcc diff --git a/contrib/credential/osxkeychain/git-credential-osxkeychain.c b/contrib/credential/osxkeychain/git-credential-osxkeychain.c index 1c8310d7fe..611c9798b3 100644 --- a/contrib/credential/osxkeychain/git-credential-osxkeychain.c +++ b/contrib/credential/osxkeychain/git-credential-osxkeychain.c @@ -422,7 +422,7 @@ int main(int argc, const char **argv) const char *usage = "usage: git credential-osxkeychain <get|store|erase>"; - if (!argv[1]) + if (argc < 2 || !*argv[1]) die("%s", usage); if (open(argv[0], O_RDONLY | O_EXLOCK) == -1) diff --git a/contrib/credential/osxkeychain/meson.build b/contrib/credential/osxkeychain/meson.build new file mode 100644 index 0000000000..3c7677f736 --- /dev/null +++ b/contrib/credential/osxkeychain/meson.build @@ -0,0 +1,9 @@ +executable('git-credential-osxkeychain', + sources: 'git-credential-osxkeychain.c', + dependencies: [ + dependency('CoreFoundation'), + dependency('Security'), + ], + install: true, + install_dir: get_option('libexecdir') / 'git-core', +) diff --git a/contrib/credential/wincred/Makefile b/contrib/credential/wincred/Makefile index 6e992c0866..5b795fc9fe 100644 --- a/contrib/credential/wincred/Makefile +++ b/contrib/credential/wincred/Makefile @@ -1,4 +1,5 @@ -all: git-credential-wincred.exe +# The default target of this Makefile is... +all:: git-credential-wincred.exe -include ../../../config.mak.autogen -include ../../../config.mak diff --git a/contrib/credential/wincred/git-credential-wincred.c b/contrib/credential/wincred/git-credential-wincred.c index 4be0d58cd8..04145b5118 100644 --- a/contrib/credential/wincred/git-credential-wincred.c +++ b/contrib/credential/wincred/git-credential-wincred.c @@ -12,7 +12,9 @@ #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) +#ifndef _MSC_VER __attribute__((format (printf, 1, 2))) +#endif static void die(const char *err, ...) { char msg[4096]; diff --git a/contrib/credential/wincred/meson.build b/contrib/credential/wincred/meson.build new file mode 100644 index 0000000000..6de23ca17d --- /dev/null +++ b/contrib/credential/wincred/meson.build @@ -0,0 +1,5 @@ +executable('git-credential-wincred', + sources: 'git-credential-wincred.c', + install: true, + install_dir: get_option('libexecdir') / 'git-core', +) diff --git a/contrib/diff-highlight/Makefile b/contrib/diff-highlight/Makefile index f2be7cc924..33c2ccc9f7 100644 --- a/contrib/diff-highlight/Makefile +++ b/contrib/diff-highlight/Makefile @@ -1,4 +1,5 @@ -all: diff-highlight +# The default target of this Makefile is... +all:: diff-highlight PERL_PATH = /usr/bin/perl -include ../../config.mak diff --git a/contrib/diff-highlight/t/Makefile b/contrib/diff-highlight/t/Makefile index 5ff5275496..2a98541477 100644 --- a/contrib/diff-highlight/t/Makefile +++ b/contrib/diff-highlight/t/Makefile @@ -1,3 +1,6 @@ +# The default target of this Makefile is... +all:: + -include ../../../config.mak.autogen -include ../../../config.mak @@ -6,7 +9,7 @@ SHELL_PATH ?= $(SHELL) SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH)) T = $(wildcard t[0-9][0-9][0-9][0-9]-*.sh) -all: test +all:: test test: $(T) .PHONY: help clean all test $(T) diff --git a/contrib/libgit-rs/Cargo.lock b/contrib/libgit-rs/Cargo.lock new file mode 100644 index 0000000000..a30c7c8d33 --- /dev/null +++ b/contrib/libgit-rs/Cargo.lock @@ -0,0 +1,77 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "cc" +version = "1.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57b6a275aa2903740dc87da01c62040406b8812552e97129a63ea8850a17c6e6" +dependencies = [ + "shlex", +] + +[[package]] +name = "libc" +version = "0.2.158" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" + +[[package]] +name = "libgit" +version = "0.1.0" +dependencies = [ + "autocfg", + "libgit-sys", +] + +[[package]] +name = "libgit-sys" +version = "0.1.0" +dependencies = [ + "autocfg", + "libz-sys", + "make-cmd", +] + +[[package]] +name = "libz-sys" +version = "1.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2d16453e800a8cf6dd2fc3eb4bc99b786a9b90c663b8559a5b1a041bf89e472" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "make-cmd" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8ca8afbe8af1785e09636acb5a41e08a765f5f0340568716c18a8700ba3c0d3" + +[[package]] +name = "pkg-config" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" diff --git a/contrib/libgit-rs/Cargo.toml b/contrib/libgit-rs/Cargo.toml new file mode 100644 index 0000000000..c3289e69db --- /dev/null +++ b/contrib/libgit-rs/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "libgit" +version = "0.1.0" +edition = "2021" +build = "build.rs" +rust-version = "1.63" # TODO: Once we hit 1.84 or newer, we may want to remove Cargo.lock from + # version control. See https://lore.kernel.org/git/Z47jgK-oMjFRSslr@tapette.crustytoothpaste.net/ + + +[lib] +path = "src/lib.rs" + +[dependencies] +libgit-sys = { version = "0.1.0", path = "../libgit-sys" } + +[build-dependencies] +autocfg = "1.4.0" diff --git a/contrib/libgit-rs/README.md b/contrib/libgit-rs/README.md new file mode 100644 index 0000000000..ff945e1ce2 --- /dev/null +++ b/contrib/libgit-rs/README.md @@ -0,0 +1,13 @@ +# libgit-rs + +Proof-of-concept Git bindings for Rust. + +```toml +[dependencies] +libgit = "0.1.0" +``` + +## Rust version requirements + +libgit-rs should support Rust versions at least as old as the version included +in Debian stable (currently 1.63). diff --git a/contrib/libgit-rs/build.rs b/contrib/libgit-rs/build.rs new file mode 100644 index 0000000000..f8bd01a690 --- /dev/null +++ b/contrib/libgit-rs/build.rs @@ -0,0 +1,4 @@ +pub fn main() { + let ac = autocfg::new(); + ac.emit_has_path("std::ffi::c_char"); +} diff --git a/contrib/libgit-rs/src/config.rs b/contrib/libgit-rs/src/config.rs new file mode 100644 index 0000000000..6bf04845c8 --- /dev/null +++ b/contrib/libgit-rs/src/config.rs @@ -0,0 +1,106 @@ +use std::ffi::{c_void, CStr, CString}; +use std::path::Path; + +#[cfg(has_std__ffi__c_char)] +use std::ffi::{c_char, c_int}; + +#[cfg(not(has_std__ffi__c_char))] +#[allow(non_camel_case_types)] +type c_char = i8; + +#[cfg(not(has_std__ffi__c_char))] +#[allow(non_camel_case_types)] +type c_int = i32; + +use libgit_sys::*; + +/// A ConfigSet is an in-memory cache for config-like files such as `.gitmodules` or `.gitconfig`. +/// It does not support all config directives; notably, it will not process `include` or +/// `includeIf` directives (but it will store them so that callers can choose whether and how to +/// handle them). +pub struct ConfigSet(*mut libgit_config_set); +impl ConfigSet { + /// Allocate a new ConfigSet + pub fn new() -> Self { + unsafe { ConfigSet(libgit_configset_alloc()) } + } + + /// Load the given files into the ConfigSet; conflicting directives in later files will + /// override those given in earlier files. + pub fn add_files(&mut self, files: &[&Path]) { + for file in files { + let pstr = file.to_str().expect("Invalid UTF-8"); + let rs = CString::new(pstr).expect("Couldn't convert to CString"); + unsafe { + libgit_configset_add_file(self.0, rs.as_ptr()); + } + } + } + + /// Load the value for the given key and attempt to parse it as an i32. Dies with a fatal error + /// if the value cannot be parsed. Returns None if the key is not present. + pub fn get_int(&mut self, key: &str) -> Option<i32> { + let key = CString::new(key).expect("Couldn't convert to CString"); + let mut val: c_int = 0; + unsafe { + if libgit_configset_get_int(self.0, key.as_ptr(), &mut val as *mut c_int) != 0 { + return None; + } + } + + Some(val.into()) + } + + /// Clones the value for the given key. Dies with a fatal error if the value cannot be + /// converted to a String. Returns None if the key is not present. + pub fn get_string(&mut self, key: &str) -> Option<String> { + let key = CString::new(key).expect("Couldn't convert key to CString"); + let mut val: *mut c_char = std::ptr::null_mut(); + unsafe { + if libgit_configset_get_string(self.0, key.as_ptr(), &mut val as *mut *mut c_char) != 0 + { + return None; + } + let borrowed_str = CStr::from_ptr(val); + let owned_str = + String::from(borrowed_str.to_str().expect("Couldn't convert val to str")); + free(val as *mut c_void); // Free the xstrdup()ed pointer from the C side + Some(owned_str) + } + } +} + +impl Default for ConfigSet { + fn default() -> Self { + Self::new() + } +} + +impl Drop for ConfigSet { + fn drop(&mut self) { + unsafe { + libgit_configset_free(self.0); + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn load_configs_via_configset() { + let mut cs = ConfigSet::new(); + cs.add_files(&[ + Path::new("testdata/config1"), + Path::new("testdata/config2"), + Path::new("testdata/config3"), + ]); + // ConfigSet retrieves correct value + assert_eq!(cs.get_int("trace2.eventTarget"), Some(1)); + // ConfigSet respects last config value set + assert_eq!(cs.get_int("trace2.eventNesting"), Some(3)); + // ConfigSet returns None for missing key + assert_eq!(cs.get_string("foo.bar"), None); + } +} diff --git a/contrib/libgit-rs/src/lib.rs b/contrib/libgit-rs/src/lib.rs new file mode 100644 index 0000000000..ef68c36943 --- /dev/null +++ b/contrib/libgit-rs/src/lib.rs @@ -0,0 +1 @@ +pub mod config; diff --git a/contrib/libgit-rs/testdata/config1 b/contrib/libgit-rs/testdata/config1 new file mode 100644 index 0000000000..4e9a9d25d1 --- /dev/null +++ b/contrib/libgit-rs/testdata/config1 @@ -0,0 +1,2 @@ +[trace2] + eventNesting = 1 diff --git a/contrib/libgit-rs/testdata/config2 b/contrib/libgit-rs/testdata/config2 new file mode 100644 index 0000000000..b8d1eca423 --- /dev/null +++ b/contrib/libgit-rs/testdata/config2 @@ -0,0 +1,2 @@ +[trace2] + eventTarget = 1 diff --git a/contrib/libgit-rs/testdata/config3 b/contrib/libgit-rs/testdata/config3 new file mode 100644 index 0000000000..ca7b9a7c38 --- /dev/null +++ b/contrib/libgit-rs/testdata/config3 @@ -0,0 +1,2 @@ +[trace2] + eventNesting = 3 diff --git a/contrib/libgit-sys/Cargo.lock b/contrib/libgit-sys/Cargo.lock new file mode 100644 index 0000000000..427a4c66b7 --- /dev/null +++ b/contrib/libgit-sys/Cargo.lock @@ -0,0 +1,69 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "cc" +version = "1.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57b6a275aa2903740dc87da01c62040406b8812552e97129a63ea8850a17c6e6" +dependencies = [ + "shlex", +] + +[[package]] +name = "libc" +version = "0.2.158" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" + +[[package]] +name = "libgit-sys" +version = "0.1.0" +dependencies = [ + "autocfg", + "libz-sys", + "make-cmd", +] + +[[package]] +name = "libz-sys" +version = "1.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2d16453e800a8cf6dd2fc3eb4bc99b786a9b90c663b8559a5b1a041bf89e472" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "make-cmd" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8ca8afbe8af1785e09636acb5a41e08a765f5f0340568716c18a8700ba3c0d3" + +[[package]] +name = "pkg-config" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" diff --git a/contrib/libgit-sys/Cargo.toml b/contrib/libgit-sys/Cargo.toml new file mode 100644 index 0000000000..e0623022c3 --- /dev/null +++ b/contrib/libgit-sys/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "libgit-sys" +version = "0.1.0" +edition = "2021" +build = "build.rs" +links = "gitpub" +rust-version = "1.63" # TODO: Once we hit 1.84 or newer, we may want to remove Cargo.lock from + # version control. See https://lore.kernel.org/git/Z47jgK-oMjFRSslr@tapette.crustytoothpaste.net/ +description = "Native bindings to a portion of libgit" + +[lib] +path = "src/lib.rs" + +[dependencies] +libz-sys = "1.1.19" + +[build-dependencies] +autocfg = "1.4.0" +make-cmd = "0.1.0" diff --git a/contrib/libgit-sys/README.md b/contrib/libgit-sys/README.md new file mode 100644 index 0000000000..c061cfcaf5 --- /dev/null +++ b/contrib/libgit-sys/README.md @@ -0,0 +1,4 @@ +# libgit-sys + +A small proof-of-concept crate showing how to provide a Rust FFI to Git +internals. diff --git a/contrib/libgit-sys/build.rs b/contrib/libgit-sys/build.rs new file mode 100644 index 0000000000..3ffd80ad91 --- /dev/null +++ b/contrib/libgit-sys/build.rs @@ -0,0 +1,35 @@ +use std::env; +use std::path::PathBuf; + +pub fn main() -> std::io::Result<()> { + let ac = autocfg::new(); + ac.emit_has_path("std::ffi::c_char"); + + let crate_root = PathBuf::from(env::var_os("CARGO_MANIFEST_DIR").unwrap()); + let git_root = crate_root.join("../.."); + let dst = PathBuf::from(env::var_os("OUT_DIR").unwrap()); + + let make_output = make_cmd::gnu_make() + .env("DEVELOPER", "1") + .env_remove("PROFILE") + .current_dir(git_root.clone()) + .args([ + "INCLUDE_LIBGIT_RS=YesPlease", + "contrib/libgit-sys/libgitpub.a", + ]) + .output() + .expect("Make failed to run"); + if !make_output.status.success() { + panic!( + "Make failed:\n stdout = {}\n stderr = {}\n", + String::from_utf8(make_output.stdout).unwrap(), + String::from_utf8(make_output.stderr).unwrap() + ); + } + std::fs::copy(crate_root.join("libgitpub.a"), dst.join("libgitpub.a"))?; + println!("cargo:rustc-link-search=native={}", dst.display()); + println!("cargo:rustc-link-lib=gitpub"); + println!("cargo:rerun-if-changed={}", git_root.display()); + + Ok(()) +} diff --git a/contrib/libgit-sys/public_symbol_export.c b/contrib/libgit-sys/public_symbol_export.c new file mode 100644 index 0000000000..dfbb257115 --- /dev/null +++ b/contrib/libgit-sys/public_symbol_export.c @@ -0,0 +1,59 @@ +/* + * Shim to publicly export Git symbols. These must be renamed so that the + * original symbols can be hidden. Renaming these with a "libgit_" prefix also + * avoids conflicts with other libraries such as libgit2. + */ + +#include "git-compat-util.h" +#include "config.h" +#include "contrib/libgit-sys/public_symbol_export.h" +#include "version.h" + +#pragma GCC visibility push(default) + +struct libgit_config_set { + struct config_set cs; +}; + +struct libgit_config_set *libgit_configset_alloc(void) +{ + struct libgit_config_set *cs = + xmalloc(sizeof(struct libgit_config_set)); + git_configset_init(&cs->cs); + return cs; +} + +void libgit_configset_free(struct libgit_config_set *cs) +{ + git_configset_clear(&cs->cs); + free(cs); +} + +int libgit_configset_add_file(struct libgit_config_set *cs, const char *filename) +{ + return git_configset_add_file(&cs->cs, filename); +} + +int libgit_configset_get_int(struct libgit_config_set *cs, const char *key, + int *dest) +{ + return git_configset_get_int(&cs->cs, key, dest); +} + +int libgit_configset_get_string(struct libgit_config_set *cs, const char *key, + char **dest) +{ + return git_configset_get_string(&cs->cs, key, dest); +} + +const char *libgit_user_agent(void) +{ + return git_user_agent(); +} + +const char *libgit_user_agent_sanitized(void) +{ + return git_user_agent_sanitized(); +} + +#pragma GCC visibility pop diff --git a/contrib/libgit-sys/public_symbol_export.h b/contrib/libgit-sys/public_symbol_export.h new file mode 100644 index 0000000000..701db92d53 --- /dev/null +++ b/contrib/libgit-sys/public_symbol_export.h @@ -0,0 +1,18 @@ +#ifndef PUBLIC_SYMBOL_EXPORT_H +#define PUBLIC_SYMBOL_EXPORT_H + +struct libgit_config_set *libgit_configset_alloc(void); + +void libgit_configset_free(struct libgit_config_set *cs); + +int libgit_configset_add_file(struct libgit_config_set *cs, const char *filename); + +int libgit_configset_get_int(struct libgit_config_set *cs, const char *key, int *dest); + +int libgit_configset_get_string(struct libgit_config_set *cs, const char *key, char **dest); + +const char *libgit_user_agent(void); + +const char *libgit_user_agent_sanitized(void); + +#endif /* PUBLIC_SYMBOL_EXPORT_H */ diff --git a/contrib/libgit-sys/src/lib.rs b/contrib/libgit-sys/src/lib.rs new file mode 100644 index 0000000000..4bfc650450 --- /dev/null +++ b/contrib/libgit-sys/src/lib.rs @@ -0,0 +1,79 @@ +use std::ffi::c_void; + +#[cfg(has_std__ffi__c_char)] +use std::ffi::{c_char, c_int}; + +#[cfg(not(has_std__ffi__c_char))] +#[allow(non_camel_case_types)] +pub type c_char = i8; + +#[cfg(not(has_std__ffi__c_char))] +#[allow(non_camel_case_types)] +pub type c_int = i32; + +extern crate libz_sys; + +#[allow(non_camel_case_types)] +#[repr(C)] +pub struct libgit_config_set { + _data: [u8; 0], + _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>, +} + +extern "C" { + pub fn free(ptr: *mut c_void); + + pub fn libgit_user_agent() -> *const c_char; + pub fn libgit_user_agent_sanitized() -> *const c_char; + + pub fn libgit_configset_alloc() -> *mut libgit_config_set; + pub fn libgit_configset_free(cs: *mut libgit_config_set); + + pub fn libgit_configset_add_file(cs: *mut libgit_config_set, filename: *const c_char) -> c_int; + + pub fn libgit_configset_get_int( + cs: *mut libgit_config_set, + key: *const c_char, + int: *mut c_int, + ) -> c_int; + + pub fn libgit_configset_get_string( + cs: *mut libgit_config_set, + key: *const c_char, + dest: *mut *mut c_char, + ) -> c_int; + +} + +#[cfg(test)] +mod tests { + use std::ffi::CStr; + + use super::*; + + #[test] + fn user_agent_starts_with_git() { + let c_str = unsafe { CStr::from_ptr(libgit_user_agent()) }; + let agent = c_str + .to_str() + .expect("User agent contains invalid UTF-8 data"); + assert!( + agent.starts_with("git/"), + r#"Expected user agent to start with "git/", got: {}"#, + agent + ); + } + + #[test] + fn sanitized_user_agent_starts_with_git() { + let c_str = unsafe { CStr::from_ptr(libgit_user_agent_sanitized()) }; + let agent = c_str + .to_str() + .expect("Sanitized user agent contains invalid UTF-8 data"); + assert!( + agent.starts_with("git/"), + r#"Expected user agent to start with "git/", got: {}"#, + agent + ); + } +} diff --git a/contrib/long-running-filter/example.pl b/contrib/long-running-filter/example.pl index a677569ddd..4b83e4c5e8 100755 --- a/contrib/long-running-filter/example.pl +++ b/contrib/long-running-filter/example.pl @@ -1,7 +1,7 @@ #!/usr/bin/perl # # Example implementation for the Git filter protocol version 2 -# See Documentation/gitattributes.txt, section "Filter Protocol" +# See Documentation/gitattributes.adoc, section "Filter Protocol" # # Please note, this pass-thru filter is a minimal skeleton. No proper # error handling was implemented. diff --git a/contrib/meson.build b/contrib/meson.build index a7b77b87c2..a88c5dfe09 100644 --- a/contrib/meson.build +++ b/contrib/meson.build @@ -1 +1,6 @@ -subdir('completion') +foreach feature : get_option('contrib') + subdir(feature) +endforeach + +subdir('coccinelle') +subdir('credential') diff --git a/contrib/mw-to-git/Makefile b/contrib/mw-to-git/Makefile index 4e603512a3..497ac434d6 100644 --- a/contrib/mw-to-git/Makefile +++ b/contrib/mw-to-git/Makefile @@ -12,6 +12,9 @@ # # make install +# The default target of this Makefile is... +all:: + GIT_MEDIAWIKI_PM=Git/Mediawiki.pm SCRIPT_PERL=git-remote-mediawiki.perl SCRIPT_PERL+=git-mw.perl @@ -27,7 +30,7 @@ INSTLIBDIR=$(shell $(MAKE) -C $(GIT_ROOT_DIR)/ \ DESTDIR_SQ = $(subst ','\'',$(DESTDIR)) INSTLIBDIR_SQ = $(subst ','\'',$(INSTLIBDIR)) -all: build +all:: build test: all $(MAKE) -C t diff --git a/contrib/mw-to-git/t/Makefile b/contrib/mw-to-git/t/Makefile index f422203fa0..6c9f377caa 100644 --- a/contrib/mw-to-git/t/Makefile +++ b/contrib/mw-to-git/t/Makefile @@ -8,7 +8,8 @@ # ## Test git-remote-mediawiki -all: test +# The default target of this Makefile is... +all:: test -include ../../../config.mak.autogen -include ../../../config.mak diff --git a/contrib/persistent-https/Makefile b/contrib/persistent-https/Makefile index 52b84ba3d4..691737e76b 100644 --- a/contrib/persistent-https/Makefile +++ b/contrib/persistent-https/Makefile @@ -12,10 +12,13 @@ # See the License for the specific language governing permissions and # limitations under the License. +# The default target of this Makefile is... +all:: + BUILD_LABEL=$(shell cut -d" " -f3 ../../GIT-VERSION-FILE) TAR_OUT=$(shell go env GOOS)_$(shell go env GOARCH).tar.gz -all: git-remote-persistent-https git-remote-persistent-https--proxy \ +all:: git-remote-persistent-https git-remote-persistent-https--proxy \ git-remote-persistent-http git-remote-persistent-https--proxy: git-remote-persistent-https diff --git a/contrib/subtree/.gitignore b/contrib/subtree/.gitignore index 0b9381abca..6deaf177c7 100644 --- a/contrib/subtree/.gitignore +++ b/contrib/subtree/.gitignore @@ -1,4 +1,6 @@ *~ +asciidoc.conf +asciidoctor-extensions.rb git-subtree git-subtree.1 git-subtree.html diff --git a/contrib/subtree/Makefile b/contrib/subtree/Makefile index 6fa7496bfd..c0c9f21cb7 100644 --- a/contrib/subtree/Makefile +++ b/contrib/subtree/Makefile @@ -1,6 +1,7 @@ # The default target of this Makefile is... all:: +-include ../../shared.mak -include ../../config.mak.autogen -include ../../config.mak @@ -13,17 +14,16 @@ htmldir ?= $(prefix)/share/doc/git-doc ../../GIT-VERSION-FILE: FORCE $(MAKE) -C ../../ GIT-VERSION-FILE --include ../../GIT-VERSION-FILE - # this should be set to a 'standard' bsd-type install program INSTALL ?= install RM ?= rm -f ASCIIDOC = asciidoc -ASCIIDOC_CONF = -f ../../Documentation/asciidoc.conf +ASCIIDOC_CONF = -f asciidoc.conf ASCIIDOC_HTML = xhtml11 ASCIIDOC_DOCBOOK = docbook ASCIIDOC_EXTRA = +ASCIIDOC_DEPS = asciidoc.conf XMLTO = xmlto XMLTO_EXTRA = @@ -32,8 +32,9 @@ ASCIIDOC = asciidoctor ASCIIDOC_CONF = ASCIIDOC_HTML = xhtml5 ASCIIDOC_DOCBOOK = docbook -ASCIIDOC_EXTRA += -I../../Documentation -rasciidoctor-extensions +ASCIIDOC_EXTRA += -I. -rasciidoctor-extensions ASCIIDOC_EXTRA += -alitdd='&\#x2d;&\#x2d;' +ASCIIDOC_DEPS = asciidoctor-extensions.rb XMLTO_EXTRA += --skip-validation endif @@ -49,7 +50,7 @@ GIT_SUBTREE := git-subtree GIT_SUBTREE_DOC := git-subtree.1 GIT_SUBTREE_XML := git-subtree.xml -GIT_SUBTREE_TXT := git-subtree.txt +GIT_SUBTREE_TXT := git-subtree.adoc GIT_SUBTREE_HTML := git-subtree.html GIT_SUBTREE_TEST := ../../git-subtree @@ -82,13 +83,13 @@ install-html: $(GIT_SUBTREE_HTML) $(GIT_SUBTREE_DOC): $(GIT_SUBTREE_XML) $(XMLTO) -m $(MANPAGE_XSL) $(XMLTO_EXTRA) man $^ -$(GIT_SUBTREE_XML): $(GIT_SUBTREE_TXT) +$(GIT_SUBTREE_XML): $(GIT_SUBTREE_TXT) $(ASCIIDOC_DEPS) $(ASCIIDOC) -b $(ASCIIDOC_DOCBOOK) -d manpage $(ASCIIDOC_CONF) \ - -agit_version=$(GIT_VERSION) $(ASCIIDOC_EXTRA) $^ + $(ASCIIDOC_EXTRA) $< -$(GIT_SUBTREE_HTML): $(GIT_SUBTREE_TXT) +$(GIT_SUBTREE_HTML): $(GIT_SUBTREE_TXT) $(ASCIIDOC_DEPS) $(ASCIIDOC) -b $(ASCIIDOC_HTML) -d manpage $(ASCIIDOC_CONF) \ - -agit_version=$(GIT_VERSION) $(ASCIIDOC_EXTRA) $^ + $(ASCIIDOC_EXTRA) $< $(GIT_SUBTREE_TEST): $(GIT_SUBTREE) cp $< $@ @@ -98,6 +99,12 @@ test: $(GIT_SUBTREE_TEST) clean: $(RM) $(GIT_SUBTREE) + $(RM) asciidoc.conf asciidoctor-extensions.rb $(RM) *.xml *.html *.1 +asciidoc.conf: ../../Documentation/asciidoc.conf.in ../../GIT-VERSION-FILE + $(QUIET_GEN)$(call version_gen,"$(shell pwd)/../..",$<,$@) +asciidoctor-extensions.rb: ../../Documentation/asciidoctor-extensions.rb.in ../../GIT-VERSION-FILE + $(QUIET_GEN)$(call version_gen,"$(shell pwd)/../..",$<,$@) + .PHONY: FORCE diff --git a/contrib/subtree/git-subtree.txt b/contrib/subtree/git-subtree.adoc index 004abf415b..004abf415b 100644 --- a/contrib/subtree/git-subtree.txt +++ b/contrib/subtree/git-subtree.adoc diff --git a/contrib/subtree/meson.build b/contrib/subtree/meson.build new file mode 100644 index 0000000000..63714166a6 --- /dev/null +++ b/contrib/subtree/meson.build @@ -0,0 +1,73 @@ +git_subtree = custom_target( + input: 'git-subtree.sh', + output: 'git-subtree', + command: [ + shell, + meson.project_source_root() / 'generate-script.sh', + '@INPUT@', + '@OUTPUT@', + meson.project_build_root() / 'GIT-BUILD-OPTIONS', + ], + install: true, + install_dir: get_option('libexecdir') / 'git-core', +) + +if get_option('tests') + subtree_test_environment = test_environment + subtree_test_environment.prepend('PATH', meson.current_build_dir()) + + test('t7900-subtree', shell, + args: [ 't7900-subtree.sh' ], + env: subtree_test_environment, + workdir: meson.current_source_dir() / 't', + depends: test_dependencies + bin_wrappers + [ git_subtree ], + timeout: 0, + ) +endif + +if get_option('docs').contains('man') + subtree_xml = custom_target( + command: asciidoc_common_options + [ + '--backend=' + asciidoc_docbook, + '--doctype=manpage', + '--out-file=@OUTPUT@', + '@INPUT@', + ], + depends: documentation_deps, + input: 'git-subtree.adoc', + output: 'git-subtree.xml', + ) + + custom_target( + command: [ + xmlto, + '-m', '@INPUT@', + 'man', + subtree_xml, + '-o', + meson.current_build_dir(), + ] + xmlto_extra, + input: [ + '../../Documentation/manpage-normal.xsl', + ], + output: 'git-subtree.1', + install: true, + install_dir: get_option('mandir') / 'man1', + ) +endif + +if get_option('docs').contains('html') + custom_target( + command: asciidoc_common_options + [ + '--backend=' + asciidoc_html, + '--doctype=manpage', + '--out-file=@OUTPUT@', + '@INPUT@', + ], + depends: documentation_deps, + input: 'git-subtree.adoc', + output: 'git-subtree.html', + install: true, + install_dir: get_option('datadir') / 'doc/git-doc', + ) +endif diff --git a/contrib/subtree/t/Makefile b/contrib/subtree/t/Makefile index 093399c788..2a85f5ee84 100644 --- a/contrib/subtree/t/Makefile +++ b/contrib/subtree/t/Makefile @@ -3,6 +3,9 @@ # Copyright (c) 2005 Junio C Hamano # +# The default target of this Makefile is... +all:: + -include ../../../config.mak.autogen -include ../../../config.mak @@ -31,7 +34,7 @@ TSVN = $(sort $(wildcard t91[0-9][0-9]-*.sh)) TGITWEB = $(sort $(wildcard t95[0-9][0-9]-*.sh)) THELPERS = $(sort $(filter-out $(T),$(wildcard *.sh))) -all: $(DEFAULT_TEST_TARGET) +all:: $(DEFAULT_TEST_TARGET) test: pre-clean $(TEST_LINT) $(MAKE) aggregate-results-and-cleanup diff --git a/contrib/thunderbird-patch-inline/appp.sh b/contrib/thunderbird-patch-inline/appp.sh index 1053872eea..fdcc948352 100755 --- a/contrib/thunderbird-patch-inline/appp.sh +++ b/contrib/thunderbird-patch-inline/appp.sh @@ -31,7 +31,7 @@ BODY=$(sed -e "1,/${SEP}/d" $1) CMT_MSG=$(sed -e '1,/^$/d' -e '/^---$/,$d' "${PATCH}") DIFF=$(sed -e '1,/^---$/d' "${PATCH}") -CCS=$(echo -e "$CMT_MSG\n$HEADERS" | sed -n -e 's/^Cc: \(.*\)$/\1,/gp' \ +CCS=$(printf '%s\n%s\n' "$CMT_MSG" "$HEADERS" | sed -n -e 's/^Cc: \(.*\)$/\1,/gp' \ -e 's/^Signed-off-by: \(.*\)/\1,/gp') echo "$SUBJECT" > $1 |
