diff --git a/Documentation/RelNotes/2.30.5.txt b/Documentation/RelNotes/2.30.5.txt new file mode 100644 index 00000000000000..5191cab3aea017 --- /dev/null +++ b/Documentation/RelNotes/2.30.5.txt @@ -0,0 +1,12 @@ +Git v2.30.5 Release Notes +========================= + +This release contains minor fix-ups for the changes that went into +Git 2.30.3 and 2.30.4, addressing CVE-2022-29187. + + * The safety check that verifies a safe ownership of the Git + worktree is now extended to also cover the ownership of the Git + directory (and the `.git` file, if there is any). + +Carlo Marcelo Arenas Belón (1): + setup: tighten ownership checks post CVE-2022-24765 diff --git a/Documentation/RelNotes/2.31.4.txt b/Documentation/RelNotes/2.31.4.txt new file mode 100644 index 00000000000000..97a91fd07aaa15 --- /dev/null +++ b/Documentation/RelNotes/2.31.4.txt @@ -0,0 +1,6 @@ +Git v2.31.4 Release Notes +========================= + +This release merges up the fixes that appear in v2.30.5 to address +the security issue CVE-2022-29187; see the release notes for that +version for details. diff --git a/Documentation/RelNotes/2.32.3.txt b/Documentation/RelNotes/2.32.3.txt new file mode 100644 index 00000000000000..583fabe68498c9 --- /dev/null +++ b/Documentation/RelNotes/2.32.3.txt @@ -0,0 +1,6 @@ +Git v2.32.3 Release Notes +========================= + +This release merges up the fixes that appear in v2.30.5 and +v2.31.4 to address the security issue CVE-2022-29187; see the +release notes for these versions for details. diff --git a/Documentation/RelNotes/2.33.4.txt b/Documentation/RelNotes/2.33.4.txt new file mode 100644 index 00000000000000..a145cc25de6bab --- /dev/null +++ b/Documentation/RelNotes/2.33.4.txt @@ -0,0 +1,6 @@ +Git v2.33.4 Release Notes +========================= + +This release merges up the fixes that appear in v2.30.5, v2.31.4 +and v2.32.3 to address the security issue CVE-2022-29187; see +the release notes for these versions for details. diff --git a/Documentation/RelNotes/2.34.4.txt b/Documentation/RelNotes/2.34.4.txt new file mode 100644 index 00000000000000..2a6b223403abbe --- /dev/null +++ b/Documentation/RelNotes/2.34.4.txt @@ -0,0 +1,6 @@ +Git v2.34.4 Release Notes +========================= + +This release merges up the fixes that appear in v2.30.5, v2.31.4, +v2.32.3 and v2.33.4 to address the security issue CVE-2022-29187; +see the release notes for these versions for details. diff --git a/Documentation/RelNotes/2.35.4.txt b/Documentation/RelNotes/2.35.4.txt new file mode 100644 index 00000000000000..47abd5ad4528b5 --- /dev/null +++ b/Documentation/RelNotes/2.35.4.txt @@ -0,0 +1,7 @@ +Git v2.35.4 Release Notes +========================= + +This release merges up the fixes that appear in v2.30.5, +v2.31.4, v2.32.3, v2.33.4 and v2.34.4 to address the security +issue CVE-2022-29187; see the release notes for these versions +for details. diff --git a/Documentation/RelNotes/2.36.2.txt b/Documentation/RelNotes/2.36.2.txt index ba5d5acd078528..958f5b4102baf9 100644 --- a/Documentation/RelNotes/2.36.2.txt +++ b/Documentation/RelNotes/2.36.2.txt @@ -1,10 +1,16 @@ Git v2.36.2 Release Notes ========================= -This maintenance release is primarily to merge down updates to the -build and CI procedures from the 'master' front, in order to ensure -that we can cut healthy maintenance releases in the future. It also -contains a handful of small and trivially-correct bugfixes. +This release merges up the fixes that appear in v2.30.5, v2.31.4, +v2.32.3, v2.33.4, v2.34.4 and v2.35.4 to address the security +issue CVE-2022-29187; see the release notes for these versions +for details. + +Apart from that, this maintenance release is primarily to merge down +updates to the build and CI procedures from the 'master' front, in +order to ensure that we can cut healthy maintenance releases in the +future. It also contains a handful of small and trivially-correct +bugfixes. Fixes since v2.36.1 ------------------- diff --git a/Documentation/RelNotes/2.37.1.txt b/Documentation/RelNotes/2.37.1.txt new file mode 100644 index 00000000000000..84609327d1d2a7 --- /dev/null +++ b/Documentation/RelNotes/2.37.1.txt @@ -0,0 +1,17 @@ +Git 2.37.1 Release Notes +======================== + +This release merges up the fixes that appear in v2.30.5, v2.31.4, +v2.32.3, v2.33.4, v2.34.4, v2.35.4, and v2.36.2 to address the +security issue CVE-2022-29187; see the release notes for these +versions for details. + +Fixes since Git 2.37 +-------------------- + + * Rewrite of "git add -i" in C that appeared in Git 2.25 didn't + correctly record a removed file to the index, which is an old + regression but has become widely known because the C version has + become the default in the latest release. + + * Fix for CVS-2022-29187. diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index b210b306b7554f..1b2c580ecc439f 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,7 +1,7 @@ #!/bin/sh GVF=GIT-VERSION-FILE -DEF_VER=v2.37.0 +DEF_VER=v2.37.1 LF=' ' diff --git a/RelNotes b/RelNotes index 51144b6e83418a..a55e1d4eefb54a 120000 --- a/RelNotes +++ b/RelNotes @@ -1 +1 @@ -Documentation/RelNotes/2.37.0.txt \ No newline at end of file +Documentation/RelNotes/2.37.1.txt \ No newline at end of file diff --git a/add-interactive.c b/add-interactive.c index 6047e8f6489fa3..22fcd3412ca5d8 100644 --- a/add-interactive.c +++ b/add-interactive.c @@ -697,8 +697,16 @@ static int run_update(struct add_i_state *s, const struct pathspec *ps, for (i = 0; i < files->items.nr; i++) { const char *name = files->items.items[i].string; - if (files->selected[i] && - add_file_to_index(s->r->index, name, 0) < 0) { + struct stat st; + + if (!files->selected[i]) + continue; + if (lstat(name, &st) && is_missing_file_error(errno)) { + if (remove_file_from_index(s->r->index, name) < 0) { + res = error(_("could not stage '%s'"), name); + break; + } + } else if (add_file_to_index(s->r->index, name, 0) < 0) { res = error(_("could not stage '%s'"), name); break; } diff --git a/azure-pipelines.yml b/azure-pipelines.yml new file mode 100644 index 00000000000000..e7200599fbda28 --- /dev/null +++ b/azure-pipelines.yml @@ -0,0 +1,393 @@ +variables: + Agent.Source.Git.ShallowFetchDepth: 1 + GIT_CONFIG_PARAMETERS: "'checkout.workers=56' 'user.name=CI' 'user.email=ci@git'" + +jobs: +- job: windows_build + displayName: Windows Build + condition: succeeded() + pool: + vmImage: windows-latest + timeoutInMinutes: 240 + steps: + - bash: git clone --bare --depth=1 --filter=blob:none --single-branch -b main https://github.com/git-for-windows/git-sdk-64 + displayName: 'clone git-sdk-64' + - bash: git clone --depth=1 --single-branch -b main https://github.com/git-for-windows/build-extra + displayName: 'clone build-extra' + - bash: sh -x ./build-extra/please.sh create-sdk-artifact --sdk=git-sdk-64.git --out=git-sdk-64-minimal minimal-sdk + displayName: 'build git-sdk-64-minimal-sdk' + - bash: | + # Let Git ignore the SDK and the test-cache + printf "%s\n" /git-sdk-64.git/ /build-extra/ /git-sdk-64-minimal/ /test-cache/ >>'.git/info/exclude' + displayName: 'Ignore untracked directories' + - bash: ci/make-test-artifacts.sh artifacts + displayName: Build + env: + HOME: $(Build.SourcesDirectory) + MSYSTEM: MINGW64 + DEVELOPER: 1 + NO_PERL: 1 + PATH: "$(Build.SourcesDirectory)\\git-sdk-64-minimal\\mingw64\\bin;$(Build.SourcesDirectory)\\git-sdk-64-minimal\\usr\\bin;C:\\Windows\\system32;C:\\Windows;C:\\Windows\\system32\\wbem" + - task: PublishPipelineArtifact@0 + displayName: 'Publish Pipeline Artifact: test artifacts' + inputs: + artifactName: 'windows-artifacts' + targetPath: '$(Build.SourcesDirectory)\artifacts' + - task: PublishPipelineArtifact@0 + displayName: 'Publish Pipeline Artifact: git-sdk-64-minimal' + inputs: + artifactName: 'git-sdk-64-minimal' + targetPath: '$(Build.SourcesDirectory)\git-sdk-64-minimal' + +- job: windows_test + displayName: Windows Test + dependsOn: windows_build + condition: succeeded() + pool: + vmImage: windows-latest + timeoutInMinutes: 240 + strategy: + parallel: 10 + steps: + - task: DownloadPipelineArtifact@0 + displayName: 'Download Pipeline Artifact: test artifacts' + inputs: + artifactName: 'windows-artifacts' + targetPath: '$(Build.SourcesDirectory)' + - task: DownloadPipelineArtifact@0 + displayName: 'Download Pipeline Artifact: git-sdk-64-minimal' + inputs: + artifactName: 'git-sdk-64-minimal' + targetPath: '$(Build.SourcesDirectory)\git-sdk-64-minimal' + - bash: | + test -f artifacts.tar.gz || { + echo No test artifacts found\; skipping >&2 + exit 0 + } + tar xf artifacts.tar.gz || exit 1 + + # Let Git ignore the SDK and the test-cache + printf '%s\n' /git-sdk-64.git/ /build-extra/ /git-sdk-64-minimal/ /test-cache/ >>.git/info/exclude + + ci/run-test-slice.sh $SYSTEM_JOBPOSITIONINPHASE $SYSTEM_TOTALJOBSINPHASE || { + ci/print-test-failures.sh + exit 1 + } + displayName: 'Test (parallel)' + env: + HOME: $(Build.SourcesDirectory) + MSYSTEM: MINGW64 + NO_SVN_TESTS: 1 + GIT_TEST_SKIP_REBASE_P: 1 + PATH: "$(Build.SourcesDirectory)\\git-sdk-64-minimal\\mingw64\\bin;$(Build.SourcesDirectory)\\git-sdk-64-minimal\\usr\\bin\\core_perl;$(Build.SourcesDirectory)\\git-sdk-64-minimal\\usr\\bin;C:\\Windows\\system32;C:\\Windows;C:\\Windows\\system32\\wbem" + - task: PublishTestResults@2 + displayName: 'Publish Test Results **/TEST-*.xml' + inputs: + mergeTestResults: true + testRunTitle: 'windows' + platform: Windows + publishRunAttachments: false + condition: succeededOrFailed() + - task: PublishBuildArtifacts@1 + displayName: 'Publish trash directories of failed tests' + condition: failed() + inputs: + PathtoPublish: t/failed-test-artifacts + ArtifactName: failed-test-artifacts + +- job: vs_build + displayName: Visual Studio Build + condition: succeeded() + pool: + vmImage: windows-latest + timeoutInMinutes: 240 + steps: + - bash: git clone --bare --depth=1 --filter=blob:none --single-branch -b main https://github.com/git-for-windows/git-sdk-64 + displayName: 'clone git-sdk-64' + - bash: git clone --depth=1 --single-branch -b main https://github.com/git-for-windows/build-extra + displayName: 'clone build-extra' + - bash: sh -x ./build-extra/please.sh create-sdk-artifact --sdk=git-sdk-64.git --out=git-sdk-64-minimal minimal-sdk + displayName: 'build git-sdk-64-minimal-sdk' + - bash: | + # Let Git ignore the SDK and the test-cache + printf "%s\n" /git-sdk-64-minimal/ /test-cache/ >>'.git/info/exclude' + displayName: 'Ignore untracked directories' + - bash: make NDEBUG=1 DEVELOPER=1 vcxproj + displayName: Generate Visual Studio Solution + env: + HOME: $(Build.SourcesDirectory) + MSYSTEM: MINGW64 + DEVELOPER: 1 + NO_PERL: 1 + PATH: "$(Build.SourcesDirectory)\\git-sdk-64-minimal\\mingw64\\bin;$(Build.SourcesDirectory)\\git-sdk-64-minimal\\usr\\bin;C:\\Windows\\system32;C:\\Windows;C:\\Windows\\system32\\wbem" + - powershell: | + $urlbase = "https://dev.azure.com/git/git/_apis/build/builds" + $id = ((Invoke-WebRequest -UseBasicParsing "${urlbase}?definitions=9&statusFilter=completed&resultFilter=succeeded&`$top=1").content | ConvertFrom-JSON).value[0].id + $downloadUrl = ((Invoke-WebRequest -UseBasicParsing "${urlbase}/$id/artifacts").content | ConvertFrom-JSON).value[0].resource.downloadUrl + (New-Object Net.WebClient).DownloadFile($downloadUrl, "compat.zip") + Expand-Archive compat.zip -DestinationPath . -Force + Remove-Item compat.zip + displayName: 'Download vcpkg artifacts' + - task: MSBuild@1 + inputs: + solution: git.sln + platform: x64 + configuration: Release + maximumCpuCount: 4 + msbuildArguments: /p:PlatformToolset=v142 + - bash: | + ./compat/vcbuild/vcpkg_copy_dlls.bat release && + mkdir -p artifacts && + eval "$(make -n artifacts-tar INCLUDE_DLLS_IN_ARTIFACTS=YesPlease ARTIFACTS_DIRECTORY=artifacts | grep ^tar)" + displayName: Bundle artifact tar + env: + HOME: $(Build.SourcesDirectory) + MSYSTEM: MINGW64 + DEVELOPER: 1 + NO_PERL: 1 + MSVC: 1 + VCPKG_ROOT: $(Build.SourcesDirectory)\compat\vcbuild\vcpkg + PATH: "$(Build.SourcesDirectory)\\git-sdk-64-minimal\\mingw64\\bin;$(Build.SourcesDirectory)\\git-sdk-64-minimal\\usr\\bin;C:\\Windows\\system32;C:\\Windows;C:\\Windows\\system32\\wbem" + - powershell: | + $tag = (Invoke-WebRequest -UseBasicParsing "https://gitforwindows.org/latest-tag.txt").content + $version = (Invoke-WebRequest -UseBasicParsing "https://gitforwindows.org/latest-version.txt").content + $url = "https://github.com/git-for-windows/git/releases/download/${tag}/PortableGit-${version}-64-bit.7z.exe" + (New-Object Net.WebClient).DownloadFile($url,"PortableGit.exe") + & .\PortableGit.exe -y -oartifacts\PortableGit + # Wait until it is unpacked + while (-not @(Remove-Item -ErrorAction SilentlyContinue PortableGit.exe; $?)) { sleep 1 } + displayName: Download & extract portable Git + - task: PublishPipelineArtifact@0 + displayName: 'Publish Pipeline Artifact: MSVC test artifacts' + inputs: + artifactName: 'vs-artifacts' + targetPath: '$(Build.SourcesDirectory)\artifacts' + +- job: vs_test + displayName: Visual Studio Test + dependsOn: vs_build + condition: succeeded() + pool: + vmImage: windows-latest + timeoutInMinutes: 240 + strategy: + parallel: 10 + steps: + - task: DownloadPipelineArtifact@0 + displayName: 'Download Pipeline Artifact: VS test artifacts' + inputs: + artifactName: 'vs-artifacts' + targetPath: '$(Build.SourcesDirectory)' + - bash: | + test -f artifacts.tar.gz || { + echo No test artifacts found\; skipping >&2 + exit 0 + } + tar xf artifacts.tar.gz || exit 1 + + # Let Git ignore the SDK and the test-cache + printf '%s\n' /PortableGit/ /test-cache/ >>.git/info/exclude + + cd t && + PATH="$PWD/helper:$PATH" && + test-tool.exe run-command testsuite --jobs=10 -V -x --write-junit-xml \ + $(test-tool.exe path-utils slice-tests \ + $SYSTEM_JOBPOSITIONINPHASE $SYSTEM_TOTALJOBSINPHASE t[0-9]*.sh) + displayName: 'Test (parallel)' + env: + HOME: $(Build.SourcesDirectory) + MSYSTEM: MINGW64 + NO_SVN_TESTS: 1 + GIT_TEST_SKIP_REBASE_P: 1 + PATH: "$(Build.SourcesDirectory)\\PortableGit\\mingw64\\bin;$(Build.SourcesDirectory)\\PortableGit\\usr\\bin;C:\\Windows\\system32;C:\\Windows;C:\\Windows\\system32\\wbem" + - task: PublishTestResults@2 + displayName: 'Publish Test Results **/TEST-*.xml' + inputs: + mergeTestResults: true + testRunTitle: 'vs' + platform: Windows + publishRunAttachments: false + condition: succeededOrFailed() + - task: PublishBuildArtifacts@1 + displayName: 'Publish trash directories of failed tests' + condition: failed() + inputs: + PathtoPublish: t/failed-test-artifacts + ArtifactName: failed-vs-test-artifacts + +- job: linux_clang + displayName: linux-clang + condition: succeeded() + pool: + vmImage: ubuntu-latest + steps: + - bash: | + export CC=clang || exit 1 + + ci/install-dependencies.sh || exit 1 + ci/run-build-and-tests.sh || { + ci/print-test-failures.sh + exit 1 + } + displayName: 'ci/run-build-and-tests.sh' + - task: PublishTestResults@2 + displayName: 'Publish Test Results **/TEST-*.xml' + inputs: + mergeTestResults: true + testRunTitle: 'linux-clang' + platform: Linux + publishRunAttachments: false + condition: succeededOrFailed() + - task: PublishBuildArtifacts@1 + displayName: 'Publish trash directories of failed tests' + condition: failed() + inputs: + PathtoPublish: t/failed-test-artifacts + ArtifactName: failed-test-artifacts + +- job: linux_gcc + displayName: linux-gcc + condition: succeeded() + pool: + vmImage: ubuntu-latest + steps: + - bash: | + ci/install-dependencies.sh || exit 1 + ci/run-build-and-tests.sh || { + ci/print-test-failures.sh + exit 1 + } + displayName: 'ci/run-build-and-tests.sh' + - task: PublishTestResults@2 + displayName: 'Publish Test Results **/TEST-*.xml' + inputs: + mergeTestResults: true + testRunTitle: 'linux-gcc' + platform: Linux + publishRunAttachments: false + condition: succeededOrFailed() + - task: PublishBuildArtifacts@1 + displayName: 'Publish trash directories of failed tests' + condition: failed() + inputs: + PathtoPublish: t/failed-test-artifacts + ArtifactName: failed-test-artifacts + +- job: osx_clang + displayName: osx-clang + condition: succeeded() + pool: + vmImage: macOS-latest + steps: + - bash: | + export CC=clang + + ci/install-dependencies.sh || exit 1 + ci/run-build-and-tests.sh || { + ci/print-test-failures.sh + exit 1 + } + displayName: 'ci/run-build-and-tests.sh' + - task: PublishTestResults@2 + displayName: 'Publish Test Results **/TEST-*.xml' + inputs: + mergeTestResults: true + testRunTitle: 'osx-clang' + platform: macOS + publishRunAttachments: false + condition: succeededOrFailed() + - task: PublishBuildArtifacts@1 + displayName: 'Publish trash directories of failed tests' + condition: failed() + inputs: + PathtoPublish: t/failed-test-artifacts + ArtifactName: failed-test-artifacts + +- job: osx_gcc + displayName: osx-gcc + condition: succeeded() + pool: + vmImage: macOS-latest + steps: + - bash: | + ci/install-dependencies.sh || exit 1 + ci/run-build-and-tests.sh || { + ci/print-test-failures.sh + exit 1 + } + displayName: 'ci/run-build-and-tests.sh' + - task: PublishTestResults@2 + displayName: 'Publish Test Results **/TEST-*.xml' + inputs: + mergeTestResults: true + testRunTitle: 'osx-gcc' + platform: macOS + publishRunAttachments: false + condition: succeededOrFailed() + - task: PublishBuildArtifacts@1 + displayName: 'Publish trash directories of failed tests' + condition: failed() + inputs: + PathtoPublish: t/failed-test-artifacts + ArtifactName: failed-test-artifacts + +- job: linux32 + displayName: Linux32 + condition: succeeded() + pool: + vmImage: ubuntu-latest + steps: + - bash: | + res=0 + sudo AGENT_OS="$AGENT_OS" BUILD_BUILDNUMBER="$BUILD_BUILDNUMBER" BUILD_REPOSITORY_URI="$BUILD_REPOSITORY_URI" BUILD_SOURCEBRANCH="$BUILD_SOURCEBRANCH" BUILD_SOURCEVERSION="$BUILD_SOURCEVERSION" SYSTEM_PHASENAME="$SYSTEM_PHASENAME" SYSTEM_TASKDEFINITIONSURI="$SYSTEM_TASKDEFINITIONSURI" SYSTEM_TEAMPROJECT="$SYSTEM_TEAMPROJECT" CC=$CC MAKEFLAGS="$MAKEFLAGS" jobname=linux32 bash -lxc ci/run-docker.sh || res=1 + + sudo chmod a+r t/out/TEST-*.xml + test ! -d t/failed-test-artifacts || sudo chmod a+r t/failed-test-artifacts + + exit $res + displayName: 'jobname=linux32 ci/run-docker.sh' + - task: PublishTestResults@2 + displayName: 'Publish Test Results **/TEST-*.xml' + inputs: + mergeTestResults: true + testRunTitle: 'linux32' + platform: Linux + publishRunAttachments: false + condition: succeededOrFailed() + - task: PublishBuildArtifacts@1 + displayName: 'Publish trash directories of failed tests' + condition: failed() + inputs: + PathtoPublish: t/failed-test-artifacts + ArtifactName: failed-test-artifacts + +- job: static_analysis + displayName: StaticAnalysis + condition: succeeded() + pool: + vmImage: ubuntu-18.04 + steps: + - bash: | + sudo apt-get update && + sudo apt-get install -y coccinelle libcurl4-openssl-dev libssl-dev libexpat-dev gettext && + + export jobname=StaticAnalysis && + + ci/run-static-analysis.sh || exit 1 + displayName: 'ci/run-static-analysis.sh' + +- job: documentation + displayName: Documentation + condition: succeeded() + pool: + vmImage: ubuntu-latest + steps: + - bash: | + sudo apt-get update && + sudo apt-get install -y asciidoc xmlto asciidoctor docbook-xsl-ns && + + export ALREADY_HAVE_ASCIIDOCTOR=yes. && + export jobname=Documentation && + + ci/test-documentation.sh || exit 1 + displayName: 'ci/test-documentation.sh' diff --git a/builtin/shortlog.c b/builtin/shortlog.c index 35825f075e3b21..086dfee45aa8be 100644 --- a/builtin/shortlog.c +++ b/builtin/shortlog.c @@ -443,7 +443,7 @@ void shortlog_output(struct shortlog *log) struct strbuf sb = STRBUF_INIT; if (log->sort_by_number) - QSORT(log->list.items, log->list.nr, + STABLE_QSORT(log->list.items, log->list.nr, log->summary ? compare_by_counter : compare_by_list); for (i = 0; i < log->list.nr; i++) { const struct string_list_item *item = &log->list.items[i]; diff --git a/ci/lib.sh b/ci/lib.sh index f095519f8dba96..6ab5a107883d4f 100755 --- a/ci/lib.sh +++ b/ci/lib.sh @@ -161,6 +161,12 @@ then MAKEFLAGS="$MAKEFLAGS --jobs=10" test windows_nt != "$CI_OS_NAME" || GIT_TEST_OPTS="--no-chain-lint --no-bin-wrappers $GIT_TEST_OPTS" + case "$CI_OS_NAME" in + linux) runs_on_pool=ubuntu-latest;; + macos|osx) runs_on_pool=macos-latest;; + windows_nt) runs_on_pool=windows-latest;; + *) echo "Unhandled OS: $CI_OS_NAME" >&2; exit 1;; + esac elif test true = "$GITHUB_ACTIONS" then CI_TYPE=github-actions diff --git a/ci/run-build-and-tests.sh b/ci/run-build-and-tests.sh index 1ea8909c6f8449..f3195eb265f37b 100755 --- a/ci/run-build-and-tests.sh +++ b/ci/run-build-and-tests.sh @@ -5,11 +5,6 @@ . ${0%/*}/lib.sh -case "$CI_OS_NAME" in -windows*) cmd //c mklink //j t\\.prove "$(cygpath -aw "$cache_dir/.prove")";; -*) ln -s "$cache_dir/.prove" t/.prove;; -esac - run_tests=t case "$jobname" in diff --git a/ci/run-test-slice.sh b/ci/run-test-slice.sh index 2f2dbea25b48f2..279aff4da9e4db 100755 --- a/ci/run-test-slice.sh +++ b/ci/run-test-slice.sh @@ -5,11 +5,6 @@ . ${0%/*}/lib.sh -case "$CI_OS_NAME" in -windows*) cmd //c mklink //j t\\.prove "$(cygpath -aw "$cache_dir/.prove")";; -*) ln -s "$cache_dir/.prove" t/.prove;; -esac - group "Run tests" make --quiet -C t T="$(cd t && ./helper/test-tool path-utils slice-tests "$1" "$2" t[0-9]*.sh | tr '\n' ' ')" || diff --git a/config.mak.uname b/config.mak.uname index 9fb11fcfff3d0d..0a59a3b037be31 100644 --- a/config.mak.uname +++ b/config.mak.uname @@ -818,7 +818,7 @@ vcxproj: # Make .vcxproj files and add them perl contrib/buildsystems/generate -g Vcxproj - git add -f git.sln {*,*/lib.proj,t/helper/*}/*.vcxproj + git add -f git.sln {*,*/lib.proj,t/helper/*,reftable/libreftable{,_test}.proj}/*.vcxproj # Generate the LinkOrCopyBuiltins.targets and LinkOrCopyRemoteHttp.targets file (echo '' && \ @@ -850,9 +850,11 @@ vcxproj: sed -i '/^git_broken_path_fix ".*/d' git-sh-setup git add -f $(SCRIPT_LIB) $(SCRIPTS) +ifndef NO_PERL # Add Perl module $(MAKE) $(LIB_PERL_GEN) git add -f perl/build +endif # Add bin-wrappers, for testing rm -rf bin-wrappers/ diff --git a/contrib/buildsystems/Generators/Vcxproj.pm b/contrib/buildsystems/Generators/Vcxproj.pm index 7dd07ea4615082..52355932d28b9c 100644 --- a/contrib/buildsystems/Generators/Vcxproj.pm +++ b/contrib/buildsystems/Generators/Vcxproj.pm @@ -77,7 +77,7 @@ sub createProject { my $libs_release = "\n "; my $libs_debug = "\n "; if (!$static_library && $name ne 'headless-git') { - $libs_release = join(";", sort(grep /^(?!libgit\.lib|xdiff\/lib\.lib|vcs-svn\/lib\.lib|reftable\/libreftable\.lib)/, @{$$build_structure{"$prefix${name}_LIBS"}})); + $libs_release = join(";", sort(grep /^(?!libgit\.lib|xdiff\/lib\.lib|vcs-svn\/lib\.lib|reftable\/libreftable(_test)?\.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; @@ -88,6 +88,7 @@ sub createProject { $defines =~ s//>/g; $defines =~ s/\'//g; + $defines =~ s/\\"/"/g; my $rcdefines = $defines; $rcdefines =~ s/(?OnlyExplicitInline ProgramDatabase + stdc11 true @@ -266,6 +268,7 @@ EOM if ((!$static_library || $target =~ 'vcs-svn' || $target =~ 'xdiff') && !($name =~ /headless-git/)) { my $uuid_libgit = $$build_structure{"LIBS_libgit_GUID"}; my $uuid_libreftable = $$build_structure{"LIBS_reftable/libreftable_GUID"}; + my $uuid_libreftable_test = $$build_structure{"LIBS_reftable/libreftable_test_GUID"}; my $uuid_xdiff_lib = $$build_structure{"LIBS_xdiff/lib_GUID"}; print F << "EOM"; @@ -277,10 +280,14 @@ EOM EOM if (!($name =~ /xdiff|libreftable/)) { print F << "EOM"; - + $uuid_libreftable false + + $uuid_libreftable_test + false + EOM } if (!($name =~ 'xdiff')) { diff --git a/contrib/buildsystems/engine.pl b/contrib/buildsystems/engine.pl index 417ae71d44ccab..ee4fca200cc506 100755 --- a/contrib/buildsystems/engine.pl +++ b/contrib/buildsystems/engine.pl @@ -263,7 +263,7 @@ sub handleCompileLine if ("$part" eq "-o") { # ignore object file shift @parts; - } elsif ("$part" eq "-c" || "$part" eq "-i" || "$part" =~ /^-fno-/) { + } elsif ("$part" eq "-c" || "$part" eq "-i" || "$part" =~ /^-fno-/ || "$part" eq '-pedantic') { # ignore compile flag } elsif ($part =~ /^.?-I/) { push(@incpaths, $part); diff --git a/setup.c b/setup.c index e9d04a42562720..870bbf2409a90c 100644 --- a/setup.c +++ b/setup.c @@ -1129,14 +1129,32 @@ static int safe_directory_cb(const char *key, const char *value, void *d) return 0; } -static int ensure_valid_ownership(const char *path) +/* + * Check if a repository is safe, by verifying the ownership of the + * worktree (if any), the git directory, and the gitfile (if any). + * + * Exemptions for known-safe repositories can be added via `safe.directory` + * config settings; for non-bare repositories, their worktree needs to be + * added, for bare ones their git directory. + */ +static int ensure_valid_ownership(const char *gitfile, + const char *worktree, const char *gitdir) { - struct safe_directory_data data = { .path = path }; + struct safe_directory_data data = { + .path = worktree ? worktree : gitdir + }; if (!git_env_bool("GIT_TEST_ASSUME_DIFFERENT_OWNER", 0) && - is_path_owned_by_current_user(path)) + (!gitfile || is_path_owned_by_current_user(gitfile)) && + (!worktree || is_path_owned_by_current_user(worktree)) && + (!gitdir || is_path_owned_by_current_user(gitdir))) return 1; + /* + * data.path is the "path" that identifies the repository and it is + * constant regardless of what failed above. data.is_safe should be + * initialized to false, and might be changed by the callback. + */ read_very_early_config(safe_directory_cb, &data); return data.is_safe; @@ -1224,6 +1242,8 @@ static enum discovery_result setup_git_directory_gently_1(struct strbuf *dir, current_device = get_device_or_die(dir->buf, NULL, 0); for (;;) { int offset = dir->len, error_code = 0; + char *gitdir_path = NULL; + char *gitfile = NULL; if (offset > min_offset) strbuf_addch(dir, '/'); @@ -1234,21 +1254,50 @@ static enum discovery_result setup_git_directory_gently_1(struct strbuf *dir, if (die_on_error || error_code == READ_GITFILE_ERR_NOT_A_FILE) { /* NEEDSWORK: fail if .git is not file nor dir */ - if (is_git_directory(dir->buf)) + if (is_git_directory(dir->buf)) { gitdirenv = DEFAULT_GIT_DIR_ENVIRONMENT; + gitdir_path = xstrdup(dir->buf); + } } else if (error_code != READ_GITFILE_ERR_STAT_FAILED) return GIT_DIR_INVALID_GITFILE; - } + } else + gitfile = xstrdup(dir->buf); + /* + * Earlier, we tentatively added DEFAULT_GIT_DIR_ENVIRONMENT + * to check that directory for a repository. + * Now trim that tentative addition away, because we want to + * focus on the real directory we are in. + */ strbuf_setlen(dir, offset); if (gitdirenv) { - if (!ensure_valid_ownership(dir->buf)) - return GIT_DIR_INVALID_OWNERSHIP; - strbuf_addstr(gitdir, gitdirenv); - return GIT_DIR_DISCOVERED; + enum discovery_result ret; + + if (ensure_valid_ownership(gitfile, + dir->buf, + (gitdir_path ? gitdir_path : gitdirenv))) { + strbuf_addstr(gitdir, gitdirenv); + ret = GIT_DIR_DISCOVERED; + } else + ret = GIT_DIR_INVALID_OWNERSHIP; + + /* + * Earlier, during discovery, we might have allocated + * string copies for gitdir_path or gitfile so make + * sure we don't leak by freeing them now, before + * leaving the loop and function. + * + * Note: gitdirenv will be non-NULL whenever these are + * allocated, therefore we need not take care of releasing + * them outside of this conditional block. + */ + free(gitdir_path); + free(gitfile); + + return ret; } if (is_git_directory(dir->buf)) { - if (!ensure_valid_ownership(dir->buf)) + if (!ensure_valid_ownership(NULL, NULL, dir->buf)) return GIT_DIR_INVALID_OWNERSHIP; strbuf_addstr(gitdir, "."); return GIT_DIR_BARE; @@ -1388,8 +1437,6 @@ const char *setup_git_directory_gently(int *nongit_ok) struct strbuf hint = STRBUF_INIT; #ifdef __MINGW32__ - if (dir.buf[0] == '/') - strbuf_addstr(&prequoted, "%(prefix)/"); if (!git_env_bool("GIT_TEST_DEBUG_UNSAFE_DIRECTORIES", 0)) strbuf_addstr(&hint, _("\n\nSet the environment variable " @@ -1398,10 +1445,15 @@ const char *setup_git_directory_gently(int *nongit_ok) "again for more information.")); #endif +#ifdef __MINGW32__ + if (dir.buf[0] == '/') + strbuf_addstr(&prequoted, "%(prefix)/"); +#endif + strbuf_add(&prequoted, dir.buf, dir.len); sq_quote_buf_pretty("ed, prequoted.buf); - die(_("unsafe repository ('%s' is owned by someone else)\n" + die(_("detected dubious ownership in repository at '%s'\n" "To add an exception for this directory, call:\n" "\n" "\tgit config --global --add safe.directory %s%s"), diff --git a/t/t0033-safe-directory.sh b/t/t0033-safe-directory.sh index 238b25f91a34d7..3908597d42d705 100755 --- a/t/t0033-safe-directory.sh +++ b/t/t0033-safe-directory.sh @@ -9,7 +9,7 @@ export GIT_TEST_ASSUME_DIFFERENT_OWNER expect_rejected_dir () { test_must_fail git status 2>err && - grep "unsafe repository" err + grep "dubious ownership" err } test_expect_success 'safe.directory is not set' ' @@ -18,7 +18,7 @@ test_expect_success 'safe.directory is not set' ' test_expect_success 'ignoring safe.directory on the command line' ' test_must_fail git -c safe.directory="$(pwd)" status 2>err && - grep "unsafe repository" err + grep "dubious ownership" err ' test_expect_success 'ignoring safe.directory in the environment' ' @@ -26,14 +26,14 @@ test_expect_success 'ignoring safe.directory in the environment' ' GIT_CONFIG_KEY_0="safe.directory" \ GIT_CONFIG_VALUE_0="$(pwd)" \ git status 2>err && - grep "unsafe repository" err + grep "dubious ownership" err ' test_expect_success 'ignoring safe.directory in GIT_CONFIG_PARAMETERS' ' test_must_fail env \ GIT_CONFIG_PARAMETERS="${SQ}safe.directory${SQ}=${SQ}$(pwd)${SQ}" \ git status 2>err && - grep "unsafe repository" err + grep "dubious ownership" err ' test_expect_success 'ignoring safe.directory in repo config' ' diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh index 3fdfd3d0960d8f..5cfdddcc2f9fbd 100755 --- a/t/t3701-add-interactive.sh +++ b/t/t3701-add-interactive.sh @@ -103,6 +103,15 @@ test_expect_success 'status works (commit)' ' grep "+1/-0 *+2/-0 file" output ' +test_expect_success 'update can stage deletions' ' + >to-delete && + git add to-delete && + rm to-delete && + test_write_lines u t "" | git add -i && + git ls-files to-delete >output && + test_must_be_empty output +' + test_expect_success 'setup expected' ' cat >expected <<-\EOF index 180b47c..b6f2c08 100644 diff --git a/t/test-lib-junit.sh b/t/test-lib-junit.sh index c959183c7e2c84..79c31c788b921b 100644 --- a/t/test-lib-junit.sh +++ b/t/test-lib-junit.sh @@ -46,7 +46,7 @@ finalize_test_case_output () { shift case "$test_case_result" in ok) - set "$*" + set -- "$*" ;; failure) junit_insert="" fi - set "$1" " $junit_insert" + set -- "$1" " $junit_insert" ;; fixed) - set "$* (breakage fixed)" + set -- "$* (breakage fixed)" ;; broken) - set "$* (known breakage)" + set -- "$* (known breakage)" ;; skip) message="$(xml_attr_encode --no-lf "$skipped_reason")" - set "$1" " " + set -- "$1" " " ;; esac