From 9346a71579aa6992032e973fef8d7c14845ec7ae Mon Sep 17 00:00:00 2001 From: deepin-ci-robot Date: Fri, 17 Apr 2026 05:56:22 +0800 Subject: [PATCH] feat: update git to 1:2.53.0-1 New upstream release with security updates and bug fixes. CVE fixes included (already in 2.50.1): - CVE-2025-27613: gitk file creation/truncation vulnerability - CVE-2025-27614: gitk script execution vulnerability - CVE-2025-46835: git-gui file creation/overwriting vulnerability - CVE-2025-48384: script execution after cloning - CVE-2025-48385: protocol injection when fetching Upstream: https://github.com/git/git/releases/tag/v2.53.0 --- .github/CONTRIBUTING.md | 22 + .github/PULL_REQUEST_TEMPLATE.md | 10 + .github/workflows/check-style.yml | 34 + .github/workflows/check-whitespace.yml | 32 + .github/workflows/coverity.yml | 167 + .github/workflows/l10n.yml | 111 + .github/workflows/main.yml | 515 ++ Cargo.toml | 10 + Documentation/RelNotes/2.51.1.adoc | 99 + Documentation/RelNotes/2.51.2.adoc | 45 + Documentation/RelNotes/2.52.0.adoc | 454 ++ Documentation/RelNotes/2.53.0.adoc | 336 ++ Documentation/config/replay.adoc | 11 + Documentation/diff-algorithm-option.adoc | 20 + Documentation/for-each-ref-options.adoc | 85 + Documentation/git-last-modified.adoc | 54 + Documentation/git-repo.adoc | 122 + Documentation/gitdatamodel.adoc | 305 ++ Documentation/gitformat-loose.adoc | 53 + Documentation/lint-delimited-sections.perl | 48 + Documentation/lint-documentation-style.perl | 33 + Documentation/pack-refs-options.adoc | 52 + .../technical/unambiguous-types.adoc | 224 + builtin/last-modified.c | 548 ++ builtin/repo.c | 703 +++ ci/run-rust-checks.sh | 22 + ci/run-test-slice-meson.sh | 13 + debian/changelog | 4487 +---------------- debian/changelog.upstream | 1643 +++++- debian/control | 2 +- debian/copyright | 2 +- debian/versions.upstream | 10 + for-each-ref.h | 26 + git-gui/git-gui--askyesno | 63 + gitk-git/README.md | 93 + odb/streaming.c | 292 ++ odb/streaming.h | 67 + pack-refs.c | 56 + pack-refs.h | 23 + reftable/fsck.c | 100 + reftable/reftable-fsck.h | 40 + repack-cruft.c | 98 + repack-filtered.c | 51 + repack-geometry.c | 261 + repack-midx.c | 370 ++ repack-promisor.c | 139 + repack.c | 359 ++ repack.h | 156 + src/cargo-meson.sh | 39 + src/lib.rs | 1 + src/meson.build | 41 + src/varint.rs | 107 + t/for-each-ref-tests.sh | 2143 ++++++++ t/pack-refs-tests.sh | 461 ++ t/perf/p6010-merge-base.sh | 105 + t/perf/p8020-last-modified.sh | 22 + t/show-ref-exists-tests.sh | 77 + t/t0450/adoc-missing | 9 + t/t0614-reftable-fsck.sh | 102 + t/t1311-config-optional.sh | 38 + t/t1421-reflog-write.sh | 162 + t/t1422-show-ref-exists.sh | 9 + t/t1461-refs-list.sh | 8 + t/t1462-refs-exists.sh | 10 + t/t1463-refs-optimize.sh | 19 + t/t1900-repo.sh | 134 + t/t1901-repo-structure.sh | 184 + ...tree_--cc_--patch-with-stat_--summary_main | 34 + ...diff.diff-tree_--cc_--patch-with-stat_main | 34 + t/t4013/diff.diff-tree_--cc_--shortstat_main | 4 + .../diff.diff-tree_--cc_--stat_--summary_main | 6 + t/t4013/diff.diff-tree_--cc_--stat_main | 6 + t/t4013/diff.diff-tree_--cc_main | 30 + t/t4013/diff.diff-tree_-c_--abbrev_main | 5 + .../diff.diff-tree_-c_--stat_--summary_main | 6 + t/t4013/diff.diff-tree_-c_--stat_main | 6 + t/t4013/diff.diff-tree_-c_main | 5 + t/t4013/diff.diff-tree_-m_main | 11 + t/t4013/diff.diff-tree_-p_-m_main | 80 + t/t4013/diff.diff-tree_-p_main | 2 + t/t4013/diff.diff-tree_main | 2 + t/t4013/diff.diff_--dirstat_--cc_main~1_main | 3 + t/t4013/diff.diff_--dirstat_main~1_main~2 | 3 + ...iff.diff_--line-prefix=abc_main_main^_side | 29 + t/t4013/diff.diff_main_main^_side | 29 + ...rmat-patch_--attach_--stdout_initial..main | 170 + ...mat-patch_--attach_--stdout_initial..main^ | 110 + ...ne_--stdout_--numbered-files_initial..main | 170 + ...ut_--subject-prefix=TESTCASE_initial..main | 170 + ...rmat-patch_--inline_--stdout_initial..main | 170 + ...mat-patch_--inline_--stdout_initial..main^ | 110 + ...at-patch_--inline_--stdout_initial..main^^ | 62 + ..._--stdout_--cover-letter_-n_initial..main^ | 103 + ...patch_--stdout_--no-numbered_initial..main | 127 + ...at-patch_--stdout_--numbered_initial..main | 127 + .../diff.format-patch_--stdout_initial..main | 127 + .../diff.format-patch_--stdout_initial..main^ | 81 + t/t4013/diff.log_--cc_-m_-p_main | 200 + .../diff.log_--diff-merges=first-parent_main | 56 + ...g_--diff-merges=off_-p_--first-parent_main | 78 + ...g_--first-parent_--diff-merges=off_-p_main | 78 + ...og_--no-diff-merges_-p_--first-parent_main | 78 + ...g_--patch-with-stat_--summary_main_--_dir_ | 74 + t/t4013/diff.log_--patch-with-stat_main | 129 + .../diff.log_--patch-with-stat_main_--_dir_ | 74 + ...root_--cc_--patch-with-stat_--summary_main | 199 + ...og_--root_--patch-with-stat_--summary_main | 167 + .../diff.log_--root_--patch-with-stat_main | 161 + ...--root_-c_--patch-with-stat_--summary_main | 199 + t/t4013/diff.log_--root_-p_main | 142 + t/t4013/diff.log_--root_main | 34 + t/t4013/diff.log_-GF_-p_--pickaxe-all_main | 27 + t/t4013/diff.log_-GF_-p_main | 18 + t/t4013/diff.log_-GF_main | 7 + t/t4013/diff.log_-IA_-IB_-I1_-I2_-p_main | 99 + t/t4013/diff.log_-SF_-p_main | 18 + t/t4013/diff.log_-SF_main | 7 + t/t4013/diff.log_-SF_main_--max-count=0 | 2 + t/t4013/diff.log_-SF_main_--max-count=1 | 7 + t/t4013/diff.log_-SF_main_--max-count=2 | 7 + t/t4013/diff.log_-S_F_main | 7 + t/t4013/diff.log_-c_-m_-p_main | 200 + t/t4013/diff.log_-m_--raw_main | 61 + t/t4013/diff.log_-m_--stat_main | 66 + t/t4013/diff.log_-m_-p_--first-parent_main | 100 + t/t4013/diff.log_-m_-p_main | 200 + ...iff.log_-p_--diff-merges=first-parent_main | 137 + t/t4013/diff.log_-p_--first-parent_main | 100 + t/t4013/diff.log_-p_main | 115 + t/t4013/diff.log_main | 34 + ...diff.noellipses-diff-tree_-c_--abbrev_main | 5 + .../diff.noellipses-whatchanged_--root_main | 42 + t/t4013/diff.noellipses-whatchanged_-SF_main | 9 + t/t4013/diff.noellipses-whatchanged_main | 32 + t/t4013/diff.show_--first-parent_main | 30 + t/t4013/diff.show_-c_main | 36 + t/t4013/diff.show_-m_main | 93 + t/t4013/diff.show_main | 36 + ...d_--patch-with-stat_--summary_main_--_dir_ | 61 + .../diff.whatchanged_--patch-with-stat_main | 116 + ...whatchanged_--patch-with-stat_main_--_dir_ | 61 + ...root_--cc_--patch-with-stat_--summary_main | 199 + ...ed_--root_--patch-with-stat_--summary_main | 160 + ....whatchanged_--root_--patch-with-stat_main | 154 + ...--root_-c_--patch-with-stat_--summary_main | 199 + t/t4013/diff.whatchanged_--root_-p_main | 135 + t/t4013/diff.whatchanged_--root_main | 42 + t/t4013/diff.whatchanged_-SF_-p_main | 18 + t/t4013/diff.whatchanged_-SF_main | 9 + t/t4013/diff.whatchanged_-p_main | 102 + t/t4013/diff.whatchanged_main | 32 + t/t4072-diff-max-depth.sh | 116 + t/t4211/sha1/expect.no-assertion-error | 90 + t/t4211/sha256/expect.no-assertion-error | 90 + t/t5565-push-multiple.sh | 39 + t/t8015-blame-diff-algorithm.sh | 203 + t/t8020-last-modified.sh | 238 + t/t9305-fast-import-signatures.sh | 173 + t/t9306-fast-import-signed-tags.sh | 80 + t/unit-tests/clar/example/CMakeLists.txt | 28 + t/unit-tests/clar/example/example.c | 6 + t/unit-tests/clar/example/main.c | 27 + t/unit-tests/clar/test/expected/help | 12 + t/unit-tests/clar/test/expected/quiet | 74 + t/unit-tests/clar/test/expected/specific_test | 9 + .../clar/test/expected/stop_on_failure | 8 + t/unit-tests/clar/test/expected/suite_names | 2 + t/unit-tests/clar/test/expected/summary.xml | 41 + .../clar/test/expected/summary_with_filename | 79 + .../test/expected/summary_without_filename | 79 + t/unit-tests/clar/test/expected/tap | 152 + .../clar/test/expected/without_arguments | 78 + t/unit-tests/clar/test/selftest.c | 370 ++ t/unit-tests/clar/test/selftest.h | 3 + t/unit-tests/clar/test/suites/CMakeLists.txt | 53 + t/unit-tests/clar/test/suites/combined.c | 148 + t/unit-tests/clar/test/suites/main.c | 27 + t/unit-tests/clar/test/suites/pointer.c | 13 + .../clar/test/suites/resources/test/file | 1 + t/unit-tests/u-dir.c | 47 + t/unit-tests/u-utf8-width.c | 134 + 181 files changed, 20300 insertions(+), 4531 deletions(-) create mode 100644 .github/CONTRIBUTING.md create mode 100644 .github/PULL_REQUEST_TEMPLATE.md create mode 100644 .github/workflows/check-style.yml create mode 100644 .github/workflows/check-whitespace.yml create mode 100644 .github/workflows/coverity.yml create mode 100644 .github/workflows/l10n.yml create mode 100644 .github/workflows/main.yml create mode 100644 Cargo.toml create mode 100644 Documentation/RelNotes/2.51.1.adoc create mode 100644 Documentation/RelNotes/2.51.2.adoc create mode 100644 Documentation/RelNotes/2.52.0.adoc create mode 100644 Documentation/RelNotes/2.53.0.adoc create mode 100644 Documentation/config/replay.adoc create mode 100644 Documentation/diff-algorithm-option.adoc create mode 100644 Documentation/for-each-ref-options.adoc create mode 100644 Documentation/git-last-modified.adoc create mode 100644 Documentation/git-repo.adoc create mode 100644 Documentation/gitdatamodel.adoc create mode 100644 Documentation/gitformat-loose.adoc create mode 100755 Documentation/lint-delimited-sections.perl create mode 100755 Documentation/lint-documentation-style.perl create mode 100644 Documentation/pack-refs-options.adoc create mode 100644 Documentation/technical/unambiguous-types.adoc create mode 100644 builtin/last-modified.c create mode 100644 builtin/repo.c create mode 100755 ci/run-rust-checks.sh create mode 100755 ci/run-test-slice-meson.sh create mode 100644 for-each-ref.h create mode 100755 git-gui/git-gui--askyesno create mode 100644 gitk-git/README.md create mode 100644 odb/streaming.c create mode 100644 odb/streaming.h create mode 100644 pack-refs.c create mode 100644 pack-refs.h create mode 100644 reftable/fsck.c create mode 100644 reftable/reftable-fsck.h create mode 100644 repack-cruft.c create mode 100644 repack-filtered.c create mode 100644 repack-geometry.c create mode 100644 repack-midx.c create mode 100644 repack-promisor.c create mode 100644 repack.c create mode 100644 repack.h create mode 100755 src/cargo-meson.sh create mode 100644 src/lib.rs create mode 100644 src/meson.build create mode 100644 src/varint.rs create mode 100644 t/for-each-ref-tests.sh create mode 100644 t/pack-refs-tests.sh create mode 100755 t/perf/p6010-merge-base.sh create mode 100755 t/perf/p8020-last-modified.sh create mode 100644 t/show-ref-exists-tests.sh create mode 100644 t/t0450/adoc-missing create mode 100755 t/t0614-reftable-fsck.sh create mode 100755 t/t1311-config-optional.sh create mode 100755 t/t1421-reflog-write.sh create mode 100755 t/t1422-show-ref-exists.sh create mode 100755 t/t1461-refs-list.sh create mode 100755 t/t1462-refs-exists.sh create mode 100755 t/t1463-refs-optimize.sh create mode 100755 t/t1900-repo.sh create mode 100755 t/t1901-repo-structure.sh create mode 100644 t/t4013/diff.diff-tree_--cc_--patch-with-stat_--summary_main create mode 100644 t/t4013/diff.diff-tree_--cc_--patch-with-stat_main create mode 100644 t/t4013/diff.diff-tree_--cc_--shortstat_main create mode 100644 t/t4013/diff.diff-tree_--cc_--stat_--summary_main create mode 100644 t/t4013/diff.diff-tree_--cc_--stat_main create mode 100644 t/t4013/diff.diff-tree_--cc_main create mode 100644 t/t4013/diff.diff-tree_-c_--abbrev_main create mode 100644 t/t4013/diff.diff-tree_-c_--stat_--summary_main create mode 100644 t/t4013/diff.diff-tree_-c_--stat_main create mode 100644 t/t4013/diff.diff-tree_-c_main create mode 100644 t/t4013/diff.diff-tree_-m_main create mode 100644 t/t4013/diff.diff-tree_-p_-m_main create mode 100644 t/t4013/diff.diff-tree_-p_main create mode 100644 t/t4013/diff.diff-tree_main create mode 100644 t/t4013/diff.diff_--dirstat_--cc_main~1_main create mode 100644 t/t4013/diff.diff_--dirstat_main~1_main~2 create mode 100644 t/t4013/diff.diff_--line-prefix=abc_main_main^_side create mode 100644 t/t4013/diff.diff_main_main^_side create mode 100644 t/t4013/diff.format-patch_--attach_--stdout_initial..main create mode 100644 t/t4013/diff.format-patch_--attach_--stdout_initial..main^ create mode 100644 t/t4013/diff.format-patch_--inline_--stdout_--numbered-files_initial..main create mode 100644 t/t4013/diff.format-patch_--inline_--stdout_--subject-prefix=TESTCASE_initial..main create mode 100644 t/t4013/diff.format-patch_--inline_--stdout_initial..main create mode 100644 t/t4013/diff.format-patch_--inline_--stdout_initial..main^ create mode 100644 t/t4013/diff.format-patch_--inline_--stdout_initial..main^^ create mode 100644 t/t4013/diff.format-patch_--stdout_--cover-letter_-n_initial..main^ create mode 100644 t/t4013/diff.format-patch_--stdout_--no-numbered_initial..main create mode 100644 t/t4013/diff.format-patch_--stdout_--numbered_initial..main create mode 100644 t/t4013/diff.format-patch_--stdout_initial..main create mode 100644 t/t4013/diff.format-patch_--stdout_initial..main^ create mode 100644 t/t4013/diff.log_--cc_-m_-p_main create mode 100644 t/t4013/diff.log_--diff-merges=first-parent_main create mode 100644 t/t4013/diff.log_--diff-merges=off_-p_--first-parent_main create mode 100644 t/t4013/diff.log_--first-parent_--diff-merges=off_-p_main create mode 100644 t/t4013/diff.log_--no-diff-merges_-p_--first-parent_main create mode 100644 t/t4013/diff.log_--patch-with-stat_--summary_main_--_dir_ create mode 100644 t/t4013/diff.log_--patch-with-stat_main create mode 100644 t/t4013/diff.log_--patch-with-stat_main_--_dir_ create mode 100644 t/t4013/diff.log_--root_--cc_--patch-with-stat_--summary_main create mode 100644 t/t4013/diff.log_--root_--patch-with-stat_--summary_main create mode 100644 t/t4013/diff.log_--root_--patch-with-stat_main create mode 100644 t/t4013/diff.log_--root_-c_--patch-with-stat_--summary_main create mode 100644 t/t4013/diff.log_--root_-p_main create mode 100644 t/t4013/diff.log_--root_main create mode 100644 t/t4013/diff.log_-GF_-p_--pickaxe-all_main create mode 100644 t/t4013/diff.log_-GF_-p_main create mode 100644 t/t4013/diff.log_-GF_main create mode 100644 t/t4013/diff.log_-IA_-IB_-I1_-I2_-p_main create mode 100644 t/t4013/diff.log_-SF_-p_main create mode 100644 t/t4013/diff.log_-SF_main create mode 100644 t/t4013/diff.log_-SF_main_--max-count=0 create mode 100644 t/t4013/diff.log_-SF_main_--max-count=1 create mode 100644 t/t4013/diff.log_-SF_main_--max-count=2 create mode 100644 t/t4013/diff.log_-S_F_main create mode 100644 t/t4013/diff.log_-c_-m_-p_main create mode 100644 t/t4013/diff.log_-m_--raw_main create mode 100644 t/t4013/diff.log_-m_--stat_main create mode 100644 t/t4013/diff.log_-m_-p_--first-parent_main create mode 100644 t/t4013/diff.log_-m_-p_main create mode 100644 t/t4013/diff.log_-p_--diff-merges=first-parent_main create mode 100644 t/t4013/diff.log_-p_--first-parent_main create mode 100644 t/t4013/diff.log_-p_main create mode 100644 t/t4013/diff.log_main create mode 100644 t/t4013/diff.noellipses-diff-tree_-c_--abbrev_main create mode 100644 t/t4013/diff.noellipses-whatchanged_--root_main create mode 100644 t/t4013/diff.noellipses-whatchanged_-SF_main create mode 100644 t/t4013/diff.noellipses-whatchanged_main create mode 100644 t/t4013/diff.show_--first-parent_main create mode 100644 t/t4013/diff.show_-c_main create mode 100644 t/t4013/diff.show_-m_main create mode 100644 t/t4013/diff.show_main create mode 100644 t/t4013/diff.whatchanged_--patch-with-stat_--summary_main_--_dir_ create mode 100644 t/t4013/diff.whatchanged_--patch-with-stat_main create mode 100644 t/t4013/diff.whatchanged_--patch-with-stat_main_--_dir_ create mode 100644 t/t4013/diff.whatchanged_--root_--cc_--patch-with-stat_--summary_main create mode 100644 t/t4013/diff.whatchanged_--root_--patch-with-stat_--summary_main create mode 100644 t/t4013/diff.whatchanged_--root_--patch-with-stat_main create mode 100644 t/t4013/diff.whatchanged_--root_-c_--patch-with-stat_--summary_main create mode 100644 t/t4013/diff.whatchanged_--root_-p_main create mode 100644 t/t4013/diff.whatchanged_--root_main create mode 100644 t/t4013/diff.whatchanged_-SF_-p_main create mode 100644 t/t4013/diff.whatchanged_-SF_main create mode 100644 t/t4013/diff.whatchanged_-p_main create mode 100644 t/t4013/diff.whatchanged_main create mode 100755 t/t4072-diff-max-depth.sh create mode 100644 t/t4211/sha1/expect.no-assertion-error create mode 100644 t/t4211/sha256/expect.no-assertion-error create mode 100755 t/t5565-push-multiple.sh create mode 100755 t/t8015-blame-diff-algorithm.sh create mode 100755 t/t8020-last-modified.sh create mode 100755 t/t9305-fast-import-signatures.sh create mode 100755 t/t9306-fast-import-signed-tags.sh create mode 100644 t/unit-tests/clar/example/CMakeLists.txt create mode 100644 t/unit-tests/clar/example/example.c create mode 100644 t/unit-tests/clar/example/main.c create mode 100644 t/unit-tests/clar/test/expected/help create mode 100644 t/unit-tests/clar/test/expected/quiet create mode 100644 t/unit-tests/clar/test/expected/specific_test create mode 100644 t/unit-tests/clar/test/expected/stop_on_failure create mode 100644 t/unit-tests/clar/test/expected/suite_names create mode 100644 t/unit-tests/clar/test/expected/summary.xml create mode 100644 t/unit-tests/clar/test/expected/summary_with_filename create mode 100644 t/unit-tests/clar/test/expected/summary_without_filename create mode 100644 t/unit-tests/clar/test/expected/tap create mode 100644 t/unit-tests/clar/test/expected/without_arguments create mode 100644 t/unit-tests/clar/test/selftest.c create mode 100644 t/unit-tests/clar/test/selftest.h create mode 100644 t/unit-tests/clar/test/suites/CMakeLists.txt create mode 100644 t/unit-tests/clar/test/suites/combined.c create mode 100644 t/unit-tests/clar/test/suites/main.c create mode 100644 t/unit-tests/clar/test/suites/pointer.c create mode 100644 t/unit-tests/clar/test/suites/resources/test/file create mode 100644 t/unit-tests/u-dir.c create mode 100644 t/unit-tests/u-utf8-width.c diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md new file mode 100644 index 00000000..c8755e38 --- /dev/null +++ b/.github/CONTRIBUTING.md @@ -0,0 +1,22 @@ +## Contributing to Git + +Thanks for taking the time to contribute to Git! Please be advised that the +Git community does not use github.com for their contributions. Instead, we use +a mailing list (git@vger.kernel.org) for code submissions, code +reviews, and bug reports. + +Nevertheless, you can use [GitGitGadget](https://gitgitgadget.github.io/) to +conveniently send your Pull Requests commits to our mailing list. + +Please read ["A note from the maintainer"](https://git.kernel.org/pub/scm/git/git.git/plain/MaintNotes?h=todo) +to learn how the Git project is managed, and how you can work with it. +In addition, we highly recommend you to read [our submission guidelines](../Documentation/SubmittingPatches). + +If you prefer video, then [this talk](https://www.youtube.com/watch?v=Q7i_qQW__q4&feature=youtu.be&t=6m4s) +might be useful to you as the presenter walks you through the contribution +process by example. + +Or, you can follow the ["My First Contribution"](https://git-scm.com/docs/MyFirstContribution) +tutorial for another example of the contribution process. + +Your friendly Git community! diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 00000000..37654cdf --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,10 @@ +Thanks for taking the time to contribute to Git! Please be advised that the +Git community does not use github.com for their contributions. Instead, we use +a mailing list (git@vger.kernel.org) for code submissions, code reviews, and +bug reports. Nevertheless, you can use GitGitGadget (https://gitgitgadget.github.io/) +to conveniently send your Pull Requests commits to our mailing list. + +For a single-commit pull request, please *leave the pull request description +empty*: your commit message itself should describe your changes. + +Please read the "guidelines for contributing" linked above! diff --git a/.github/workflows/check-style.yml b/.github/workflows/check-style.yml new file mode 100644 index 00000000..19a145d4 --- /dev/null +++ b/.github/workflows/check-style.yml @@ -0,0 +1,34 @@ +name: check-style + +# Get the repository with all commits to ensure that we can analyze +# all of the commits contributed via the Pull Request. + +on: + pull_request: + types: [opened, synchronize] + +# Avoid unnecessary builds. Unlike the main CI jobs, these are not +# ci-configurable (but could be). +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + check-style: + env: + CC: clang + jobname: ClangFormat + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + with: + fetch-depth: 0 + + - run: ci/install-dependencies.sh + + - name: git clang-format + continue-on-error: true + id: check_out + run: | + ./ci/run-style-check.sh \ + "${{github.event.pull_request.base.sha}}" diff --git a/.github/workflows/check-whitespace.yml b/.github/workflows/check-whitespace.yml new file mode 100644 index 00000000..928fd4cf --- /dev/null +++ b/.github/workflows/check-whitespace.yml @@ -0,0 +1,32 @@ +name: check-whitespace + +# Get the repository with all commits to ensure that we can analyze +# all of the commits contributed via the Pull Request. +# Process `git log --check` output to extract just the check errors. +# Exit with failure upon white-space issues. + +on: + pull_request: + types: [opened, synchronize] + +# Avoid unnecessary builds. Unlike the main CI jobs, these are not +# ci-configurable (but could be). +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + check-whitespace: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + with: + fetch-depth: 0 + + - name: git log --check + id: check_out + run: | + ./ci/check-whitespace.sh \ + "${{github.event.pull_request.base.sha}}" \ + "$GITHUB_STEP_SUMMARY" \ + "https://github.com/${{github.repository}}" diff --git a/.github/workflows/coverity.yml b/.github/workflows/coverity.yml new file mode 100644 index 00000000..cfa17d39 --- /dev/null +++ b/.github/workflows/coverity.yml @@ -0,0 +1,167 @@ +name: Coverity + +# This GitHub workflow automates submitting builds to Coverity Scan. To enable it, +# set the repository variable `ENABLE_COVERITY_SCAN_FOR_BRANCHES` (for details, see +# https://docs.github.com/en/actions/learn-github-actions/variables) to a JSON +# string array containing the names of the branches for which the workflow should be +# run, e.g. `["main", "next"]`. +# +# In addition, two repository secrets must be set (for details how to add secrets, see +# https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions): +# `COVERITY_SCAN_EMAIL` and `COVERITY_SCAN_TOKEN`. The former specifies the +# email to which the Coverity reports should be sent and the latter can be +# obtained from the Project Settings tab of the Coverity project). +# +# The workflow runs on `ubuntu-latest` by default. This can be overridden by setting +# the repository variable `ENABLE_COVERITY_SCAN_ON_OS` to a JSON string array specifying +# the operating systems, e.g. `["ubuntu-latest", "windows-latest"]`. +# +# By default, the builds are submitted to the Coverity project `git`. To override this, +# set the repository variable `COVERITY_PROJECT`. + +on: + push: + +defaults: + run: + shell: bash + +jobs: + coverity: + if: contains(fromJSON(vars.ENABLE_COVERITY_SCAN_FOR_BRANCHES || '[""]'), github.ref_name) + strategy: + matrix: + os: ${{ fromJSON(vars.ENABLE_COVERITY_SCAN_ON_OS || '["ubuntu-latest"]') }} + runs-on: ${{ matrix.os }} + env: + COVERITY_PROJECT: ${{ vars.COVERITY_PROJECT || 'git' }} + COVERITY_LANGUAGE: cxx + COVERITY_PLATFORM: overridden-below + steps: + - uses: actions/checkout@v5 + - name: install minimal Git for Windows SDK + if: contains(matrix.os, 'windows') + uses: git-for-windows/setup-git-for-windows-sdk@v1 + - run: ci/install-dependencies.sh + if: contains(matrix.os, 'ubuntu') || contains(matrix.os, 'macos') + env: + CI_JOB_IMAGE: ${{ matrix.os }} + + # The Coverity site says the tool is usually updated twice yearly, so the + # MD5 of download can be used to determine whether there's been an update. + - name: get the Coverity Build Tool hash + id: lookup + run: | + case "${{ matrix.os }}" in + *windows*) + COVERITY_PLATFORM=win64 + COVERITY_TOOL_FILENAME=cov-analysis.zip + MAKEFLAGS=-j$(nproc) + ;; + *macos*) + COVERITY_PLATFORM=macOSX + COVERITY_TOOL_FILENAME=cov-analysis.dmg + MAKEFLAGS=-j$(sysctl -n hw.physicalcpu) + ;; + *ubuntu*) + COVERITY_PLATFORM=linux64 + COVERITY_TOOL_FILENAME=cov-analysis.tgz + MAKEFLAGS=-j$(nproc) + ;; + *) + echo '::error::unhandled OS ${{ matrix.os }}' >&2 + exit 1 + ;; + esac + echo "COVERITY_PLATFORM=$COVERITY_PLATFORM" >>$GITHUB_ENV + echo "COVERITY_TOOL_FILENAME=$COVERITY_TOOL_FILENAME" >>$GITHUB_ENV + echo "MAKEFLAGS=$MAKEFLAGS" >>$GITHUB_ENV + MD5=$(curl https://scan.coverity.com/download/$COVERITY_LANGUAGE/$COVERITY_PLATFORM \ + --fail \ + --form token='${{ secrets.COVERITY_SCAN_TOKEN }}' \ + --form project="$COVERITY_PROJECT" \ + --form md5=1) + case $? in + 0) ;; # okay + 22) # 40x, i.e. access denied + echo "::error::incorrect token or project?" >&2 + exit 1 + ;; + *) # other error + echo "::error::Failed to retrieve MD5" >&2 + exit 1 + ;; + esac + echo "hash=$MD5" >>$GITHUB_OUTPUT + + # Try to cache the tool to avoid downloading 1GB+ on every run. + # A cache miss will add ~30s to create, but a cache hit will save minutes. + - name: restore the Coverity Build Tool + id: cache + uses: actions/cache/restore@v4 + with: + path: ${{ runner.temp }}/cov-analysis + key: cov-build-${{ env.COVERITY_LANGUAGE }}-${{ env.COVERITY_PLATFORM }}-${{ steps.lookup.outputs.hash }} + - name: download the Coverity Build Tool (${{ env.COVERITY_LANGUAGE }} / ${{ env.COVERITY_PLATFORM}}) + if: steps.cache.outputs.cache-hit != 'true' + run: | + curl https://scan.coverity.com/download/$COVERITY_LANGUAGE/$COVERITY_PLATFORM \ + --fail --no-progress-meter \ + --output $RUNNER_TEMP/$COVERITY_TOOL_FILENAME \ + --form token='${{ secrets.COVERITY_SCAN_TOKEN }}' \ + --form project="$COVERITY_PROJECT" + - name: extract the Coverity Build Tool + if: steps.cache.outputs.cache-hit != 'true' + run: | + case "$COVERITY_TOOL_FILENAME" in + *.tgz) + mkdir $RUNNER_TEMP/cov-analysis && + tar -xzf $RUNNER_TEMP/$COVERITY_TOOL_FILENAME --strip 1 -C $RUNNER_TEMP/cov-analysis + ;; + *.dmg) + cd $RUNNER_TEMP && + attach="$(hdiutil attach $COVERITY_TOOL_FILENAME)" && + volume="$(echo "$attach" | cut -f 3 | grep /Volumes/)" && + mkdir cov-analysis && + cd cov-analysis && + sh "$volume"/cov-analysis-macosx-*.sh && + ls -l && + hdiutil detach "$volume" + ;; + *.zip) + cd $RUNNER_TEMP && + mkdir cov-analysis-tmp && + unzip -d cov-analysis-tmp $COVERITY_TOOL_FILENAME && + mv cov-analysis-tmp/* cov-analysis + ;; + *) + echo "::error::unhandled archive type: $COVERITY_TOOL_FILENAME" >&2 + exit 1 + ;; + esac + - name: cache the Coverity Build Tool + if: steps.cache.outputs.cache-hit != 'true' + uses: actions/cache/save@v4 + with: + path: ${{ runner.temp }}/cov-analysis + key: cov-build-${{ env.COVERITY_LANGUAGE }}-${{ env.COVERITY_PLATFORM }}-${{ steps.lookup.outputs.hash }} + - name: build with cov-build + run: | + export PATH="$PATH:$RUNNER_TEMP/cov-analysis/bin" && + cov-configure --gcc && + if ! cov-build --dir cov-int make + then + cat cov-int/build-log.txt + exit 1 + fi + - name: package the build + run: tar -czvf cov-int.tgz cov-int + - name: submit the build to Coverity Scan + run: | + curl \ + --fail \ + --form token='${{ secrets.COVERITY_SCAN_TOKEN }}' \ + --form email='${{ secrets.COVERITY_SCAN_EMAIL }}' \ + --form file=@cov-int.tgz \ + --form version='${{ github.sha }}' \ + "https://scan.coverity.com/builds?project=$COVERITY_PROJECT" diff --git a/.github/workflows/l10n.yml b/.github/workflows/l10n.yml new file mode 100644 index 00000000..95e55134 --- /dev/null +++ b/.github/workflows/l10n.yml @@ -0,0 +1,111 @@ +name: git-l10n + +on: [push, pull_request_target] + +# Avoid unnecessary builds. Unlike the main CI jobs, these are not +# ci-configurable (but could be). +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + git-po-helper: + if: >- + endsWith(github.repository, '/git-po') || + contains(github.head_ref, 'l10n') || + contains(github.ref, 'l10n') + runs-on: ubuntu-latest + permissions: + pull-requests: write + steps: + - name: Setup base and head objects + id: setup-tips + run: | + if test "${{ github.event_name }}" = "pull_request_target" + then + base=${{ github.event.pull_request.base.sha }} + head=${{ github.event.pull_request.head.sha }} + else + base=${{ github.event.before }} + head=${{ github.event.after }} + fi + echo base=$base >>$GITHUB_OUTPUT + echo head=$head >>$GITHUB_OUTPUT + - name: Run partial clone + run: | + git -c init.defaultBranch=master init --bare . + git remote add \ + --mirror=fetch \ + origin \ + https://github.com/${{ github.repository }} + # Fetch tips that may be unreachable from github.ref: + # - For a forced push, "$base" may be unreachable. + # - For a "pull_request_target" event, "$head" may be unreachable. + args= + for commit in \ + ${{ steps.setup-tips.outputs.base }} \ + ${{ steps.setup-tips.outputs.head }} + do + case $commit in + *[^0]*) + args="$args $commit" + ;; + *) + # Should not fetch ZERO-OID. + ;; + esac + done + git -c protocol.version=2 fetch \ + --progress \ + --no-tags \ + --no-write-fetch-head \ + --filter=blob:none \ + origin \ + ${{ github.ref }} \ + $args + - uses: actions/setup-go@v6 + with: + go-version: '>=1.16' + cache: false + - name: Install git-po-helper + run: go install github.com/git-l10n/git-po-helper@main + - name: Install other dependencies + run: | + sudo apt-get update -q && + sudo apt-get install -q -y gettext + - name: Run git-po-helper + id: check-commits + run: | + exit_code=0 + git-po-helper check-commits \ + --github-action-event="${{ github.event_name }}" -- \ + ${{ steps.setup-tips.outputs.base }}..${{ steps.setup-tips.outputs.head }} \ + >git-po-helper.out 2>&1 || exit_code=$? + if test $exit_code -ne 0 || grep -q WARNING git-po-helper.out + then + # Remove ANSI colors which are proper for console logs but not + # proper for PR comment. + echo "COMMENT_BODY<>$GITHUB_ENV + perl -pe 's/\e\[[0-9;]*m//g; s/\bEOF$//g' git-po-helper.out >>$GITHUB_ENV + echo "EOF" >>$GITHUB_ENV + fi + cat git-po-helper.out + exit $exit_code + - name: Create comment in pull request for report + uses: mshick/add-pr-comment@v2 + if: >- + always() && + github.event_name == 'pull_request_target' && + env.COMMENT_BODY != '' + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + message: > + ${{ steps.check-commits.outcome == 'failure' && 'Errors and warnings' || 'Warnings' }} + found by [git-po-helper](https://github.com/git-l10n/git-po-helper#readme) in workflow + [#${{ github.run_number }}](${{ env.GITHUB_SERVER_URL }}/${{ github.repository }}/actions/runs/${{ github.run_id }}): + + ``` + + ${{ env.COMMENT_BODY }} + + ``` diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 00000000..f2e93f54 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,515 @@ +name: CI + +on: [push, pull_request] + +env: + DEVELOPER: 1 + +# If more than one workflow run is triggered for the very same commit hash +# (which happens when multiple branches pointing to the same commit), only +# the first one is allowed to run, the second will be kept in the "queued" +# state. This allows a successful completion of the first run to be reused +# in the second run via the `skip-if-redundant` logic in the `config` job. +# +# The only caveat is that if a workflow run is triggered for the same commit +# hash that another run is already being held, that latter run will be +# canceled. For more details about the `concurrency` attribute, see: +# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#concurrency +concurrency: + group: ${{ github.sha }} + +jobs: + ci-config: + name: config + if: vars.CI_BRANCHES == '' || contains(vars.CI_BRANCHES, github.ref_name) + runs-on: ubuntu-latest + outputs: + enabled: ${{ steps.check-ref.outputs.enabled }}${{ steps.skip-if-redundant.outputs.enabled }} + skip_concurrent: ${{ steps.check-ref.outputs.skip_concurrent }} + steps: + - name: try to clone ci-config branch + run: | + git -c protocol.version=2 clone \ + --no-tags \ + --single-branch \ + -b ci-config \ + --depth 1 \ + --no-checkout \ + --filter=blob:none \ + https://github.com/${{ github.repository }} \ + config-repo && + cd config-repo && + git checkout HEAD -- ci/config || : ignore + - id: check-ref + name: check whether CI is enabled for ref + run: | + enabled=yes + if test -x config-repo/ci/config/allow-ref + then + echo "::warning::ci/config/allow-ref is deprecated; use CI_BRANCHES instead" + if ! config-repo/ci/config/allow-ref '${{ github.ref }}' + then + enabled=no + fi + fi + + skip_concurrent=yes + if test -x config-repo/ci/config/skip-concurrent && + ! config-repo/ci/config/skip-concurrent '${{ github.ref }}' + then + skip_concurrent=no + fi + echo "enabled=$enabled" >>$GITHUB_OUTPUT + echo "skip_concurrent=$skip_concurrent" >>$GITHUB_OUTPUT + - name: skip if the commit or tree was already tested + id: skip-if-redundant + uses: actions/github-script@v8 + if: steps.check-ref.outputs.enabled == 'yes' + with: + github-token: ${{secrets.GITHUB_TOKEN}} + script: | + try { + // Figure out workflow ID, commit and tree + const { data: run } = await github.rest.actions.getWorkflowRun({ + owner: context.repo.owner, + repo: context.repo.repo, + run_id: context.runId, + }); + const workflow_id = run.workflow_id; + const head_sha = run.head_sha; + const tree_id = run.head_commit.tree_id; + + // See whether there is a successful run for that commit or tree + const { data: runs } = await github.rest.actions.listWorkflowRuns({ + owner: context.repo.owner, + repo: context.repo.repo, + per_page: 500, + status: 'success', + workflow_id, + }); + for (const run of runs.workflow_runs) { + if (head_sha === run.head_sha) { + core.warning(`Successful run for the commit ${head_sha}: ${run.html_url}`); + core.setOutput('enabled', ' but skip'); + break; + } + if (run.head_commit && tree_id === run.head_commit.tree_id) { + core.warning(`Successful run for the tree ${tree_id}: ${run.html_url}`); + core.setOutput('enabled', ' but skip'); + break; + } + } + } catch (e) { + core.warning(e); + } + + windows-build: + name: win build + needs: ci-config + if: needs.ci-config.outputs.enabled == 'yes' + runs-on: windows-latest + concurrency: + group: windows-build-${{ github.ref }} + cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }} + steps: + - uses: actions/checkout@v5 + - uses: git-for-windows/setup-git-for-windows-sdk@v1 + - name: build + shell: bash + env: + HOME: ${{runner.workspace}} + NO_PERL: 1 + run: . /etc/profile && ci/make-test-artifacts.sh artifacts + - name: zip up tracked files + run: git archive -o artifacts/tracked.tar.gz HEAD + - name: upload tracked files and build artifacts + uses: actions/upload-artifact@v5 + with: + name: windows-artifacts + path: artifacts + windows-test: + name: win test + runs-on: windows-latest + needs: [ci-config, windows-build] + strategy: + fail-fast: false + matrix: + nr: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] + concurrency: + group: windows-test-${{ matrix.nr }}-${{ github.ref }} + cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }} + steps: + - name: download tracked files and build artifacts + uses: actions/download-artifact@v6 + with: + name: windows-artifacts + path: ${{github.workspace}} + - name: extract tracked files and build artifacts + shell: bash + run: tar xf artifacts.tar.gz && tar xf tracked.tar.gz + - uses: git-for-windows/setup-git-for-windows-sdk@v1 + - name: test + shell: bash + run: . /etc/profile && ci/run-test-slice.sh ${{matrix.nr}} 10 + - name: print test failures + if: failure() && env.FAILED_TEST_ARTIFACTS != '' + shell: bash + run: ci/print-test-failures.sh + - name: Upload failed tests' directories + if: failure() && env.FAILED_TEST_ARTIFACTS != '' + uses: actions/upload-artifact@v5 + with: + name: failed-tests-windows-${{ matrix.nr }} + path: ${{env.FAILED_TEST_ARTIFACTS}} + vs-build: + name: win+VS build + needs: ci-config + if: github.event.repository.owner.login == 'git-for-windows' && needs.ci-config.outputs.enabled == 'yes' + env: + NO_PERL: 1 + GIT_CONFIG_PARAMETERS: "'user.name=CI' 'user.email=ci@git'" + runs-on: windows-latest + concurrency: + group: vs-build-${{ github.ref }} + cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }} + steps: + - uses: actions/checkout@v5 + - uses: git-for-windows/setup-git-for-windows-sdk@v1 + - name: initialize vcpkg + uses: actions/checkout@v5 + with: + repository: 'microsoft/vcpkg' + path: 'compat/vcbuild/vcpkg' + - name: download vcpkg artifacts + uses: git-for-windows/get-azure-pipelines-artifact@v0 + with: + repository: git/git + definitionId: 9 + - name: add msbuild to PATH + uses: microsoft/setup-msbuild@v2 + - name: copy dlls to root + shell: cmd + run: compat\vcbuild\vcpkg_copy_dlls.bat release + - name: generate Visual Studio solution + shell: bash + run: | + cmake `pwd`/contrib/buildsystems/ -DCMAKE_PREFIX_PATH=`pwd`/compat/vcbuild/vcpkg/installed/x64-windows \ + -DNO_GETTEXT=YesPlease -DPERL_TESTS=OFF -DPYTHON_TESTS=OFF -DCURL_NO_CURL_CMAKE=ON + - name: MSBuild + run: msbuild git.sln -property:Configuration=Release -property:Platform=x64 -maxCpuCount:4 -property:PlatformToolset=v142 + - name: bundle artifact tar + shell: bash + env: + MSVC: 1 + VCPKG_ROOT: ${{github.workspace}}\compat\vcbuild\vcpkg + run: | + mkdir -p artifacts && + eval "$(make -n artifacts-tar INCLUDE_DLLS_IN_ARTIFACTS=YesPlease ARTIFACTS_DIRECTORY=artifacts NO_GETTEXT=YesPlease 2>&1 | grep ^tar)" + - name: zip up tracked files + run: git archive -o artifacts/tracked.tar.gz HEAD + - name: upload tracked files and build artifacts + uses: actions/upload-artifact@v5 + with: + name: vs-artifacts + path: artifacts + vs-test: + name: win+VS test + runs-on: windows-latest + needs: [ci-config, vs-build] + strategy: + fail-fast: false + matrix: + nr: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] + concurrency: + group: vs-test-${{ matrix.nr }}-${{ github.ref }} + cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }} + steps: + - uses: git-for-windows/setup-git-for-windows-sdk@v1 + - name: download tracked files and build artifacts + uses: actions/download-artifact@v6 + with: + name: vs-artifacts + path: ${{github.workspace}} + - name: extract tracked files and build artifacts + shell: bash + run: tar xf artifacts.tar.gz && tar xf tracked.tar.gz + - name: test + shell: bash + env: + NO_SVN_TESTS: 1 + run: . /etc/profile && ci/run-test-slice.sh ${{matrix.nr}} 10 + - name: print test failures + if: failure() && env.FAILED_TEST_ARTIFACTS != '' + shell: bash + run: ci/print-test-failures.sh + - name: Upload failed tests' directories + if: failure() && env.FAILED_TEST_ARTIFACTS != '' + uses: actions/upload-artifact@v5 + with: + name: failed-tests-windows-vs-${{ matrix.nr }} + path: ${{env.FAILED_TEST_ARTIFACTS}} + + windows-meson-build: + name: win+Meson build + needs: ci-config + if: needs.ci-config.outputs.enabled == 'yes' + runs-on: windows-latest + concurrency: + group: windows-meson-build-${{ github.ref }} + cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }} + steps: + - uses: actions/checkout@v5 + - uses: actions/setup-python@v6 + - name: Set up dependencies + shell: pwsh + run: pip install meson ninja + - name: Setup + shell: pwsh + run: meson setup build --vsenv -Dbuildtype=release -Dperl=disabled -Dcredential_helpers=wincred + - name: Compile + shell: pwsh + run: meson compile -C build + - name: Upload build artifacts + uses: actions/upload-artifact@v5 + with: + name: windows-meson-artifacts + path: build + windows-meson-test: + name: win+Meson test + runs-on: windows-latest + needs: [ci-config, windows-meson-build] + strategy: + fail-fast: false + matrix: + nr: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] + concurrency: + group: windows-meson-test-${{ matrix.nr }}-${{ github.ref }} + cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }} + steps: + - uses: actions/checkout@v5 + - uses: actions/setup-python@v6 + - name: Set up dependencies + shell: pwsh + run: pip install meson ninja + - name: Download build artifacts + uses: actions/download-artifact@v6 + with: + name: windows-meson-artifacts + path: build + - name: Test + shell: pwsh + run: ci/run-test-slice-meson.sh build ${{matrix.nr}} 10 + - name: print test failures + if: failure() && env.FAILED_TEST_ARTIFACTS != '' + shell: bash + run: ci/print-test-failures.sh + - name: Upload failed tests' directories + if: failure() && env.FAILED_TEST_ARTIFACTS != '' + uses: actions/upload-artifact@v4 + with: + name: failed-tests-windows-meson-${{ matrix.nr }} + path: ${{env.FAILED_TEST_ARTIFACTS}} + + regular: + name: ${{matrix.vector.jobname}} (${{matrix.vector.pool}}) + needs: ci-config + if: needs.ci-config.outputs.enabled == 'yes' + concurrency: + group: ${{ matrix.vector.jobname }}-${{ matrix.vector.pool }}-${{ github.ref }} + cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }} + strategy: + fail-fast: false + matrix: + vector: + - jobname: osx-clang + cc: clang + pool: macos-14 + - jobname: osx-reftable + cc: clang + pool: macos-14 + - jobname: osx-gcc + cc: gcc-13 + pool: macos-14 + - jobname: osx-meson + cc: clang + pool: macos-14 + env: + CC: ${{matrix.vector.cc}} + CC_PACKAGE: ${{matrix.vector.cc_package}} + jobname: ${{matrix.vector.jobname}} + CI_JOB_IMAGE: ${{matrix.vector.pool}} + TEST_OUTPUT_DIRECTORY: ${{github.workspace}}/t + runs-on: ${{matrix.vector.pool}} + steps: + - uses: actions/checkout@v5 + - run: ci/install-dependencies.sh + - run: ci/run-build-and-tests.sh + - name: print test failures + if: failure() && env.FAILED_TEST_ARTIFACTS != '' + run: ci/print-test-failures.sh + - name: Upload failed tests' directories + if: failure() && env.FAILED_TEST_ARTIFACTS != '' + uses: actions/upload-artifact@v5 + with: + name: failed-tests-${{matrix.vector.jobname}} + path: ${{env.FAILED_TEST_ARTIFACTS}} + fuzz-smoke-test: + name: fuzz smoke test + needs: ci-config + if: needs.ci-config.outputs.enabled == 'yes' + env: + CC: clang + CI_JOB_IMAGE: ubuntu-latest + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + - run: ci/install-dependencies.sh + - run: ci/run-build-and-minimal-fuzzers.sh + dockerized: + name: ${{matrix.vector.jobname}} (${{matrix.vector.image}}) + needs: ci-config + if: needs.ci-config.outputs.enabled == 'yes' + concurrency: + group: dockerized-${{ matrix.vector.jobname }}-${{ matrix.vector.image }}-${{ github.ref }} + cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }} + strategy: + fail-fast: false + matrix: + vector: + - jobname: linux-sha256 + image: ubuntu:rolling + cc: clang + - jobname: linux-reftable + image: ubuntu:rolling + cc: clang + - jobname: linux-TEST-vars + image: ubuntu:20.04 + cc: gcc + cc_package: gcc-8 + - jobname: linux-breaking-changes + cc: gcc + image: ubuntu:rolling + - jobname: fedora-breaking-changes-meson + image: fedora:latest + - jobname: linux-leaks + image: ubuntu:rolling + cc: gcc + - jobname: linux-reftable-leaks + image: ubuntu:rolling + cc: gcc + - jobname: linux-asan-ubsan + image: ubuntu:rolling + cc: clang + - jobname: linux-meson + image: ubuntu:rolling + cc: gcc + - jobname: linux-musl-meson + image: alpine:latest + # Supported until 2025-04-02. + - jobname: linux32 + image: i386/ubuntu:focal + # A RHEL 8 compatible distro. Supported until 2029-05-31. + - jobname: almalinux-8 + image: almalinux:8 + # Supported until 2026-08-31. + - jobname: debian-11 + image: debian:11 + env: + jobname: ${{matrix.vector.jobname}} + CC: ${{matrix.vector.cc}} + CI_JOB_IMAGE: ${{matrix.vector.image}} + CUSTOM_PATH: /custom + runs-on: ubuntu-latest + container: ${{matrix.vector.image}} + steps: + - name: prepare libc6 for actions + if: matrix.vector.jobname == 'linux32' + run: apt -q update && apt -q -y install libc6-amd64 lib64stdc++6 + - name: install git in container + run: | + if command -v git + then + : # nothing to do + elif command -v apk + then + apk add --update git + elif command -v dnf + then + dnf -yq update && dnf -yq install git + else + apt-get -q update && apt-get -q -y install git + fi + - uses: actions/checkout@v5 + - run: ci/install-dependencies.sh + - run: useradd builder --create-home + - run: chown -R builder . + - run: chmod a+w $GITHUB_ENV && sudo --preserve-env --set-home --user=builder ci/run-build-and-tests.sh + - name: print test failures + if: failure() && env.FAILED_TEST_ARTIFACTS != '' + run: sudo --preserve-env --set-home --user=builder ci/print-test-failures.sh + - name: Upload failed tests' directories + if: failure() && env.FAILED_TEST_ARTIFACTS != '' + uses: actions/upload-artifact@v5 + with: + name: failed-tests-${{matrix.vector.jobname}} + path: ${{env.FAILED_TEST_ARTIFACTS}} + static-analysis: + needs: ci-config + if: needs.ci-config.outputs.enabled == 'yes' + env: + jobname: StaticAnalysis + CI_JOB_IMAGE: ubuntu-22.04 + runs-on: ubuntu-22.04 + concurrency: + group: static-analysis-${{ github.ref }} + cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }} + steps: + - uses: actions/checkout@v5 + - run: ci/install-dependencies.sh + - run: ci/run-static-analysis.sh + - run: ci/check-directional-formatting.bash + rust-analysis: + needs: ci-config + if: needs.ci-config.outputs.enabled == 'yes' + env: + jobname: RustAnalysis + CI_JOB_IMAGE: ubuntu:rolling + runs-on: ubuntu-latest + container: ubuntu:rolling + concurrency: + group: rust-analysis-${{ github.ref }} + cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }} + steps: + - uses: actions/checkout@v4 + - run: ci/install-dependencies.sh + - run: ci/run-rust-checks.sh + sparse: + needs: ci-config + if: needs.ci-config.outputs.enabled == 'yes' + env: + jobname: sparse + CI_JOB_IMAGE: ubuntu-22.04 + runs-on: ubuntu-22.04 + concurrency: + group: sparse-${{ github.ref }} + cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }} + steps: + - uses: actions/checkout@v5 + - name: Install other dependencies + run: ci/install-dependencies.sh + - run: make sparse + documentation: + name: documentation + needs: ci-config + if: needs.ci-config.outputs.enabled == 'yes' + concurrency: + group: documentation-${{ github.ref }} + cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }} + env: + jobname: Documentation + CI_JOB_IMAGE: ubuntu-latest + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + - run: ci/install-dependencies.sh + - run: ci/test-documentation.sh diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 00000000..2f51bf5d --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "gitcore" +version = "0.1.0" +edition = "2018" +rust-version = "1.49.0" + +[lib] +crate-type = ["staticlib"] + +[dependencies] diff --git a/Documentation/RelNotes/2.51.1.adoc b/Documentation/RelNotes/2.51.1.adoc new file mode 100644 index 00000000..b8bd49c8 --- /dev/null +++ b/Documentation/RelNotes/2.51.1.adoc @@ -0,0 +1,99 @@ +Git 2.51.1 Release Notes +======================== + +There shouldn't be anything exciting to see here. This is primarily +to flush the "do you still use it?" improvements that has landed on +the master front, together with a handful of low-hanging, low-impact +fixes that should be safe. + + +Fixes since Git 2.51.0 +---------------------- + + * The "do you still use it?" message given by a command that is + deeply deprecated and allow us to suggest alternatives has been + updated. + + * The compatObjectFormat extension is used to hide an incomplete + feature that is not yet usable for any purpose other than + developing the feature further. Document it as such to discourage + its use by mere mortals. + + * Manual page for "gitk" is updated with the current maintainer's + name. + + * Update the instructions for using GGG in the MyFirstContribution + document to say that a GitHub PR could be made against `git/git` + instead of `gitgitgadget/git`. + + * Clang-format update to let our control macros be formatted the way we + had them traditionally, e.g., "for_each_string_list_item()" without + space before the parentheses. + + * A few places where a size_t value was cast to curl_off_t without + checking has been updated to use the existing helper function. + + * The start_delayed_progress() function in the progress eye-candy API + did not clear its internal state, making an initial delay value + larger than 1 second ineffective, which has been corrected. + + * Makefile tried to run multiple "cargo build" which would not work + very well; serialize their execution to work around this problem. + + * Adjust to the way newer versions of cURL selectively enable tracing + options, so that our tests can continue to work. + + * During interactive rebase, using 'drop' on a merge commit led to + an error, which has been corrected. + + * "git refs migrate" to migrate the reflog entries from a refs + backend to another had a handful of bugs squashed. + + * "git push" had a code path that led to BUG() but it should have + been a die(), as it is a response to a usual but invalid end-user + action to attempt pushing an object that does not exist. + + * Various bugs about rename handling in "ort" merge strategy have + been fixed. + + * "git diff --no-index" run inside a subdirectory under control of a + Git repository operated at the top of the working tree and stripped + the prefix from the output, and oddballs like "-" (stdin) did not + work correctly because of it. Correct the set-up by undoing what + the set-up sequence did to cwd and prefix. + + * Various options to "git diff" that make comparison ignore certain + aspects of the differences (like "space changes are ignored", + "differences in lines that match these regular expressions are + ignored") did not work well with "--name-only" and friends. + + * Under a race against another process that is repacking the + repository, especially a partially cloned one, "git fetch" may + mistakenly think some objects we do have are missing, which has + been corrected. + + * "git repack --path-walk" lost objects in some corner cases, which + has been corrected. + cf. + + * Fixes multiple crashes around midx write-out codepaths. + + * A broken or malicious "git fetch" can say that it has the same + object for many many times, and the upload-pack serving it can + exhaust memory storing them redundantly, which has been corrected. + + * A corner case bug in "git log -L..." has been corrected. + + * Some among "git add -p" and friends ignored color.diff and/or + color.ui configuration variables, which is an old regression, which + has been corrected. + + * "git rebase -i" failed to clean-up the commit log message when the + command commits the final one in a chain of "fixup" commands, which + has been corrected. + + * Deal more gracefully with directory / file conflicts when the files + backend is used for ref storage, by failing only the ones that are + involved in the conflict while allowing others. + +Also contains various documentation updates, code cleanups and minor fixups. diff --git a/Documentation/RelNotes/2.51.2.adoc b/Documentation/RelNotes/2.51.2.adoc new file mode 100644 index 00000000..f0be6033 --- /dev/null +++ b/Documentation/RelNotes/2.51.2.adoc @@ -0,0 +1,45 @@ +Git 2.51.2 Release Notes +======================== + +In addition to fixes for an unfortunate regression introduced in Git +2.51.1 that caused "git diff --quiet -w" to be not so quiet when there +are additions, deletions and conflicts, this maintenance release merges +more fixes/improvements that have landed on the master front, primarily +to make the CI part of the system a bit more robust. + + +Fixes since Git 2.51.1 +---------------------- + + * Recently we attempted to improve "git diff -w --quiet" and friends + to handle cases where patch output would be suppressed, but it + introduced a bug that emits unnecessary output, which has been + corrected. + + * The code to squelch output from "git diff -w --name-status" + etc. for paths that "git diff -w -p" would have stayed silent + leaked output from dry-run patch generation, which has been + corrected. + + * Windows "real-time monitoring" interferes with the execution of + tests and affects negatively in both correctness and performance, + which has been disabled in Gitlab CI. + + * An earlier addition to "git diff --no-index A B" to limit the + output with pathspec after the two directories misbehaved when + these directories were given with a trailing slash, which has been + corrected. + + * The "--short" option of "git status" that meant output for humans + and "-z" option to show NUL delimited output format did not mix + well, and colored some but not all things. The command has been + updated to color all elements consistently in such a case. + + * Unicode width table update. + + * Recent OpenSSH creates the Unix domain socket to communicate with + ssh-agent under $HOME instead of /tmp, which causes our test to + fail doe to overly long pathname in our test environment, which has + been worked around by using "ssh-agent -T". + +Also contains various documentation updates, code cleanups and minor fixups. diff --git a/Documentation/RelNotes/2.52.0.adoc b/Documentation/RelNotes/2.52.0.adoc new file mode 100644 index 00000000..fc78d225 --- /dev/null +++ b/Documentation/RelNotes/2.52.0.adoc @@ -0,0 +1,454 @@ +Git v2.52 Release Notes +======================= + +UI, Workflows & Features +------------------------ + + * The "list" subcommand of "git refs" acts as a front-end for + "git for-each-ref". + + * "git cmd --help-all" now works outside repositories. + + * "git diff-tree" learned "--max-depth" option. + + * A new subcommand "git repo" gives users a way to grab various + repository characteristics. + + * A new command "git last-modified" has been added to show the closest + ancestor commit that touched each path. + + * The "git refs exists" command that works like "git show-ref --exists" + has been added. + + * "git repo info" learns the short-hand option "-z" that is the same as + "--format=nul", and learns to report the objects format used in the + repository. + + * "core.commentChar=auto" that attempts to dynamically pick a + suitable comment character is non-workable, as it is too much + trouble to support for little benefit, and is marked as deprecated. + + * "git send-email" learned to drive "git imap-send" to store already + sent e-mails in an IMAP folder. + + * The "promisor-remote" capability mechanism has been updated to + allow the "partialCloneFilter" settings and the "token" value to be + communicated from the server side. + + * Declare that "git init" that is not otherwise configured uses + 'main' as the initial branch, not 'master', starting Git 3.0. + + * Keep giving hint about the default initial branch name for users + who may be surprised after Git 3.0 switch-over. + + * The stash.index configuration variable can be set to make "git stash + pop/apply" pretend that it was invoked with "--index". + + * "git fast-import" learned that "--signed-commits=" option that + corresponds to that of "git fast-export". + + * Marking a hunk 'selected' in "git add -p" and then splitting made + all the split pieces 'selected'; this has been changed to make them + all 'undecided', which gives better end-user experience. + + * Configuration variables that take a pathname as a value + (e.g. blame.ignorerevsfile) can be marked as optional by prefixing + ":(optional)" before its value. + + * Show 'P'ipe command in "git add -p". + + * "git sparse-checkout" subcommand learned a new "clean" action to + prune otherwise unused working-tree files that are outside the + areas of interest. + + * "git fast-import" is taught to handle signed tags, just like it + recently learned to handle signed commits, in different ways. + + * A new configuration variable commitGraph.changedPaths allows to + turn "--changed-paths" on by default for "git commit-graph". + + * "Symlink symref" has been added to the list of things that will + disappear at Git 3.0 boundary. + + * "git maintenance" command learns the "geometric" strategy where it + avoids doing maintenance tasks that rebuilds everything from + scratch. + + * "git repo structure", a new command. + + * The help text and manual page of "git bisect" command have been + made consistent with each other. + + +Performance, Internal Implementation, Development Support etc. +-------------------------------------------------------------- + + * string_list_split*() family of functions have been extended to + simplify common use cases. + + * Arrays of strbuf is often a wrong data structure to use, and + strbuf_split*() family of functions that create them often have + better alternatives. Update several code paths and replace + strbuf_split*(). + + * Revision traversal limited with pathspec, like "git log dir/*", + used to ignore changed-paths Bloom filter when the pathspec + contained wildcards; now they take advantage of the filter when + they can. + + * Doc lint updates to encourage the newer and easier-to-use + `synopsis` format, with fixes to a handful of existing uses. + + * Remove dependency on the_repository and other globals from the + commit-graph code, and other changes unrelated to de-globaling. + + * Discord has been added to the first contribution documentation as + another way to ask for help. + + * Inspired by Ezekiel's recent effort to showcase Rust interface, the + hash function implementation used to hash lines have been updated + to the one used for ELF symbol lookup by Glibc. + + * Instead of scanning for the remaining items to see if there are + still commits to be explored in the queue, use khash to remember + which items are still on the queue (an unacceptable alternative is + to reserve one object flag bits). + + * The bulk-checkin code used to depend on a file-scope static + singleton variable, which has been updated to pass an instance + throughout the callchain. + + * The work to build on the bulk-checkin infrastructure to create many + objects at once in a transaction and to abstract it into the + generic object layer continues. + + * CodingGuidelines now spells out how bitfields are to be written. + + * Adjust to the way newer versions of cURL selectively enable tracing + options, so that our tests can continue to work. + + * The clear_alloc_state() API function was not fully clearing the + structure for reuse, but since nobody reuses it, replace it with a + variant that frees the structure as well, making the callers simpler. + + * "git range-diff" learned a way to limit the memory consumed by + O(N*N) cost matrix. + + * Some places in the code confused a variable that is *not* a boolean + to enable color but is an enum that records what the user requested + to do about color. A couple of bugs of this sort have been fixed, + while the code has been cleaned up to prevent similar bugs in the + future. + + * The build procedure based on meson learned a target to only build + documentation, similar to "make doc". + (merge ff4ec8ded0 ps/meson-build-docs later to maint). + + * Dip our toes a bit to (optionally) use Rust implemented helper + called from our C code. + + * Documentation for "git log --pretty" options has been updated + to make it easier to translate. + + * Instead of three library archives (one for git, one for reftable, + and one for xdiff), roll everything into a single libgit.a archive. + This would help later effort to FFI into Rust. + + * The beginning of SHA1-SHA256 interoperability work. + + * Build procedure for a few credential helpers (in contrib/) have + been updated. + + * CI improvements to handle the recent Rust integration better. + + * The code in "git repack" machinery has been cleaned up to prepare + for incremental update of midx files. + + * Two slightly different ways to get at "all the packfiles" in API + has been cleaned up. + + * The code to walk revision graph to compute merge base has been + optimized. + + * AI guidelines has been added to our documentation set. + + * Contributed credential helpers (obviously in contrib/) now have "cd + $there && make install" target. + + * The "MyFirstContribution" tutorial tells the reader how to send out + their patches; the section gained a hint to verify the message + reached the mailing list. + + * The "debug" ref-backend was missing a method implementation, which + has been corrected. + + * Build procedure for Wincred credential helper has been updated. + + * The build procedure based on meson learned to allow builders to + specify the directory to install HTML documents. + + * Building "git contacts" script (in contrib/) left the resulting + file unexecutable, which has been corrected. + + +Fixes since v2.51 +----------------- + +Unless otherwise noted, all the changes in 2.51.X maintenance track, +including security updates, are included in this release. + + * During interactive rebase, using 'drop' on a merge commit lead to + an error, which was incorrect. + + * "git refs migrate" to migrate the reflog entries from a refs + backend to another had a handful of bugs squashed. + + * "git remote rename origin upstream" failed to move origin/HEAD to + upstream/HEAD when origin/HEAD is unborn and performed other + renames extremely inefficiently, which has been corrected. + (merge 16c4fa26b9 ps/remote-rename-fix later to maint). + + * "git describe" has been optimized by using better data structure. + (merge 08bb69d70f rs/describe-with-prio-queue later to maint). + + * "git push" had a code path that led to BUG() but it should have + been a die(), as it is a response to a usual but invalid end-user + action to attempt pushing an object that does not exist. + + * Various bugs about rename handling in "ort" merge strategy have + been fixed. + + * "git jump" (in contrib/) fails to parse the diff header correctly + when a file has a space in its name, which has been corrected. + (merge 621ce9c1c6 gh/git-jump-pathname-with-sp later to maint). + + * "git diff --no-index" run inside a subdirectory under control of a + Git repository operated at the top of the working tree and stripped + the prefix from the output, and oddballs like "-" (stdin) did not + work correctly because of it. Correct the set-up by undoing what + the set-up sequence did to cwd and prefix. + + * Various options to "git diff" that makes comparison ignore certain + aspects of the differences (like "space changes are ignored", + "differences in lines that match these regular expressions are + ignored") did not work well with "--name-only" and friends. + (merge b55e6d36eb ly/diff-name-only-with-diff-from-content later to maint). + + * The above caused regressions, which has been corrected. + + * Documentation for "git rebase" has been updated. + (merge 3f7f2b0359 je/doc-rebase later to maint). + + * The start_delayed_progress() function in the progress eye-candy API + did not clear its internal state, making an initial delay value + larger than 1 second ineffective, which has been corrected. + + * The compatObjectFormat extension is used to hide an incomplete + feature that is not yet usable for any purpose other than + developing the feature further. Document it as such to discourage + its use by mere mortals. + + * "git log -L..." compared trees of multiple parents with the tree of the + merge result in an unnecessarily inefficient way. + (merge 0a15bb634c sg/line-log-merge-optim later to maint). + + * Under a race against another process that is repacking the + repository, especially a partially cloned one, "git fetch" may + mistakenly think some objects we do have are missing, which has + been corrected. + + * "git fetch" can clobber a symref that is dangling when the + remote-tracking HEAD is set to auto update, which has been + corrected. + + * "git describe " misbehaves and/or crashes in some corner + cases, which has been taught to exit with failure gracefully. + (merge 7c10e48e81 jk/describe-blob later to maint). + + * Manual page for "gitk" is updated with the current maintainer's + name. + + * Update the instructions for using GGG in the MyFirstContribution + document to say that a GitHub PR could be made against `git/git` + instead of `gitgitgadget/git`. + + * Makefile tried to run multiple "cargo build" which would not work + very well; serialize their execution to work around this problem. + + * "git repack --path-walk" lost objects in some corner cases, which + has been corrected. + + * "git ls-files ..." should not necessarily have to expand + the index fully if a sparsified directory is excluded by the + pathspec; the code is taught to expand the index on demand to avoid + this. + (merge 681f26bccc ds/ls-files-lazy-unsparse later to maint). + + * Windows "real-time monitoring" interferes with the execution of + tests and affects negatively in both correctness and performance, + which has been disabled in Gitlab CI. + + * A broken or malicious "git fetch" can say that it has the same + object for many many times, and the upload-pack serving it can + exhaust memory storing them redundantly, which has been corrected. + + * A corner case bug in "git log -L..." has been corrected. + + * "git rev-parse --short" and friends failed to disambiguate two + objects with object names that share common prefix longer than 32 + characters, which has been fixed. + (merge 8655908b9e jc/longer-disambiguation-fix later to maint). + + * Some among "git add -p" and friends ignored color.diff and/or + color.ui configuration variables, which is an old regression, which + has been corrected. + + * "git subtree" (in contrib/) did not work correctly when splitting + squashed subtrees, which has been improved. + + * Import a newer version of the clar unit testing framework. + (merge 93dbb6b3c5 ps/clar-updates later to maint). + + * "git send-email --compose --reply-to=
" used to add + duplicated Reply-To: header, which made mailservers unhappy. This + has been corrected. + (merge f448f65719 nb/send-email-no-dup-reply-to later to maint). + + * "git rebase -i" failed to clean-up the commit log message when the + command commits the final one in a chain of "fixup" commands, which + has been corrected. + + * There are double frees and leaks around setup_revisions() API used + in "git stash show", which has been fixed, and setup_revisions() + API gained a wrapper to make it more ergonomic when using it with + strvec-manged argc/argv pairs. + (merge a04bc71725 jk/setup-revisions-freefix later to maint). + + * Deal more gracefully with directory / file conflicts when the files + backend is used for ref storage, by failing only the ones that are + involved in the conflict while allowing others. + + * "git last-modified" operating in non-recursive mode used to trigger + a BUG(), which has been corrected. + + * The use of "git config get" command to learn how ANSI color + sequence is for a particular type, e.g., "git config get + --type=color --default=reset no.such.thing", isn't very ergonomic. + (merge e4dabf4fd6 ps/config-get-color-fixes later to maint). + + * The "do you still use it?" message given by a command that is + deeply deprecated and allow us to suggest alternatives has been + updated. + + * Clang-format update to let our control macros be formatted the way we + had them traditionally, e.g., "for_each_string_list_item()" without + space before the parentheses. + + * A few places where a size_t value was cast to curl_off_t without + checking has been updated to use the existing helper function. + + * "git reflog write" did not honor the configured user.name/email + which has been corrected. + + * Handling of an empty subdirectory of .git/refs/ in the ref-files + backend has been corrected. + + * Our CI script requires "sudo" that can be told to preserve + environment, but Ubuntu replaced with "sudo" with an implementation + that lacks the feature. Work this around by reinstalling the + original version. + + * The reftable backend learned to sanity check its on-disk data more + carefully. + (merge 466a3a1afd kn/reftable-consistency-checks later to maint). + + * A lot of code clean-up of xdiff. + Split out of a larger topic. + (merge 8b9c5d2e3a en/xdiff-cleanup later to maint). + + * "git format-patch --range-diff=... --notes=..." did not drive the + underlying range-diff with correct --notes parameter, ending up + comparing with different set of notes from its main patch output + you would get from "git format-patch --notes=..." for a singleton + patch. + + * The code in "git add -p" and friends to iterate over hunks was + riddled with bugs, which has been corrected. + + * A few more things that patch authors can do to help maintainer to + keep track of their topics better. + (merge 1a41698841 tb/doc-submitting-patches later to maint). + + * An earlier addition to "git diff --no-index A B" to limit the + output with pathspec after the two directories misbehaved when + these directories were given with a trailing slash, which has been + corrected. + + * The "--short" option of "git status" that meant output for humans + and "-z" option to show NUL delimited output format did not mix + well, and colored some but not all things. The command has been + updated to color all elements consistently in such a case. + + * Unicode width table update. + + * GPG signing test set-up has been broken for a year, which has been + corrected. + (merge 516bf45749 jc/t1016-setup-fix later to maint). + + * Recent OpenSSH creates the Unix domain socket to communicate with + ssh-agent under $HOME instead of /tmp, which causes our test to + fail doe to overly long pathname in our test environment, which has + been worked around by using "ssh-agent -T". + + * strbuf_split*() to split a string into multiple strbufs is often a + wrong API to use. A few uses of it have been removed by + simplifying the code. + (merge 2ab72a16d9 ob/gpg-interface-cleanup later to maint). + + * "git shortlog" knows "--committer" and "--author" options, which + the command line completion (in contrib/) did not handle well, + which has been corrected. + (merge c568fa8e1c kf/log-shortlog-completion-fix later to maint). + + * "git bisect" command did not react correctly to "git bisect help" + and "git bisect unknown", which has been corrected. + (merge 2bb3a012f3 rz/bisect-help-unknown later to maint). + + * The 'q'(uit) command in "git add -p" has been improved to quit + without doing any meaningless work before leaving, and giving EOF + (typically control-D) to the prompt is made to behave the same way. + + * The wildmatch code had a corner case bug that mistakenly makes + "foo**/bar" match with "foobar", which has been corrected. + (merge 1940a02dc1 jk/match-pathname-fix later to maint). + + * Tests did not set up GNUPGHOME correctly, which is fixed but some + flaky tests are exposed in t1016, which needs to be addressed + before this topic can move forward. + (merge 6cd8369ef3 tz/test-prepare-gnupghome later to maint). + + * The patterns used in the .gitignore files use backslash in the way + documented for fnmatch(3); document as such to reduce confusion. + (merge 8a6d158a1d jk/doc-backslash-in-exclude later to maint). + + * The version of macos image used in GitHub CI has been updated to + macos-14, as the macos-13 that we have been using got deprecated. + Perforce binary used there has been changed to arm64 version to + match. + (merge 73b9cdb7c4 jc/ci-use-macos-14 later to maint). + (merge ffff0bb0da jc/ci-use-arm64-p4-on-macos later to maint). + + * Other code cleanup, docfix, build fix, etc. + (merge 529a60a885 ua/t1517-short-help-tests later to maint). + (merge 22d421fed9 ac/deglobal-fmt-merge-log-config later to maint). + (merge a60203a015 dk/t7005-editor-updates later to maint). + (merge 16684b6fae ps/reftable-libgit2-cleanup later to maint). + (merge e5c27bd3d8 je/doc-add later to maint). + (merge 13296ac909 ps/object-store-midx-dedup-info later to maint). + (merge f9a6705d9a tc/t0450-harden later to maint). + (merge a66fc22bf9 rs/get-oid-with-flags-cleanup later to maint). + (merge 15b8abde07 js/mingw-includes-cleanup later to maint). + (merge 2cebca0582 tb/cat-file-objectmode-update later to maint). + (merge 8f487db07a kh/doc-patch-id-1 later to maint). + (merge f711f37b05 eb/t1016-hash-transition-fix later to maint). + (merge 85333aa1af jk/test-delete-gpgsig-leakfix later to maint). diff --git a/Documentation/RelNotes/2.53.0.adoc b/Documentation/RelNotes/2.53.0.adoc new file mode 100644 index 00000000..2668c2e9 --- /dev/null +++ b/Documentation/RelNotes/2.53.0.adoc @@ -0,0 +1,336 @@ +Git v2.53 Release Notes +======================= + +UI, Workflows & Features +------------------------ + + * "git maintenance" command learned "is-needed" subcommand to tell if + it is necessary to perform various maintenance tasks. + + * "git replay" (experimental) learned to perform ref updates itself + in a transaction by default, instead of emitting where each refs + should point at and leaving the actual update to another command. + + * "git blame" learns "--diff-algorithm=" option. + + * "git repo info" learned "--all" option. + + * Both "git apply" and "git diff" learn a new whitespace error class, + "incomplete-line". + + * Add a new manual that describes the data model. + + * "git fast-import" learns "--signed-commits=strip-if-invalid" option + to drop invalid cryptographic signature from objects. + + * The use of "revision" (a connected set of commits) has been + clarified in the "git replay" documentation. + + * A help message from "git branch" now mentions "git help" instead of + "man" when suggesting to read some documentation. + + * "git repo struct" learned to take "-z" as a synonym to "--format=nul". + + * More object database related information are shown in "git repo + structure" output. + + * Improve the error message when a bad argument is given to the + `--onto` option of "git replay". Test coverage of "git replay" has + been improved. + + * The iconv library on macOS fails to correctly handle stateful + ISO/IEC 2022:1994 encoded strings. Work it around instead of + replacing it wholesale from homebrew. + + * Upstream symbolic link support on Windows from Git-for-Windows. + + +Performance, Internal Implementation, Development Support etc. +-------------------------------------------------------------- + + * The list of packfiles used in a running Git process is moved from + the packed_git structure into the packfile store. + + * Some ref backend storage can hold not just the object name of an + annotated tag, but the object name of the object the tag points at. + The code to handle this information has been streamlined. + + * As "git diff --quiet" only cares about the existence of any + changes, disable rename/copy detection to skip more expensive + processing whose result will be discarded anyway. + + * A part of code paths that deals with loose objects has been cleaned + up. + + * "make strip" has been taught to strip "scalar" as well as "git". + + * Dockerized jobs at the GitHub Actions CI have been taught to show + more details of failed tests. + + * Code refactoring around object database sources. + + * Halve the memory consumed by artificial filepairs created during + "git diff --find-copies-harder", also making the operation run + faster. + + * The "git_istream" abstraction has been revamped to make it easier + to interface with pluggable object database design. + + * Rewrite the only use of "mktemp()" that is subject to TOCTOU race + and Stop using the insecure "mktemp()" function. + (merge 10bba537c4 rs/ban-mktemp later to maint). + + * In-code comment update to clarify that single-letter options are + outside of the scope of command line completion script. + (merge dc8a00fafe jc/completion-no-single-letter-options later to maint). + + * MEMZERO_ARRAY() helper is introduced to avoid clearing only the + first N bytes of an N-element array whose elements are larger than + a byte. + + * "git diff-files -R --find-copies-harder" has been taught to use + the potential copy sources from the index correctly. + + * Require C99 style flexible array member support from all platforms. + + * The code path that enumerates promisor objects have been optimized + to skip pointlessly parsing blob objects. + + * Prepare test suite for Git for Windows that supports symbolic + links. + + * Import newer version of "clar", unit testing framework. + (merge 84071a6dea ps/clar-integers later to maint). + + * The packfile_store data structure is moved from object store to odb + source. + + * The object-info API has been cleaned up. + + * Further preparation to upstream symbolic link support on Windows. + + * Remove implicit reliance on the_repository global in the APIs + around tree objects and make it explicit which repository to work + in. + + * "git bugreport" and "git version --build-options" learned to + include use of 'gettext' feature, to make it easier to diagnose + problems around l10n. + + * Dscho observed that SVN tests are taking too much time in CI leak + checking tasks, but most time is spent not in our code but in libsvn + code (which happen to be written in Perl), whose leaks have little + value to discover for us. Skip SVN, P4, and CVS tests in the leak + checking tasks. + (merge 047bd7dfe3 js/ci-leak-skip-svn later to maint). + + +Fixes since v2.52 +----------------- + + * Ever since we added whitespace rules for this project, we misspelt + an entry, which has been corrected. + (merge 358e94dc70 jc/gitattributes-whitespace-no-indent-fix later to maint). + + * The code to expand attribute macros has been rewritten to avoid + recursion to avoid running out of stack space in an uncontrolled + way. + (merge 42ed046866 jk/attr-macroexpand-wo-recursion later to maint). + + * Adding a repository that uses a different hash function is a no-no, + but "git submodule add" did not prevent it, which has been corrected. + (merge 6fe288bfbc bc/submodule-force-same-hash later to maint). + + * An earlier check added to osx keychain credential helper to avoid + storing the credential itself supplied was overeager and rejected + credential material supplied by other helper backends that it would + have wanted to store, which has been corrected. + (merge 4580bcd235 kn/osxkeychain-idempotent-store-fix later to maint). + + * The "git repo structure" subcommand tried to align its output but + mixed up byte count and display column width, which has been + corrected. + (merge 7a03a10a3a jx/repo-struct-utf8width-fix later to maint). + + * Yet another corner case fix around renames in the "ort" merge + strategy. + (merge a562d90a35 en/ort-rename-another-fix later to maint). + + * Test leakfix. + (merge 14b561e768 jk/test-mktemp-leakfix later to maint). + + * Update a version of action used at the GitHub Actions CI. + (merge cd99203f86 js/ci-github-setup-go-update later to maint). + + * The "return errno = EFOO, -1" construct, which is heavily used in + compat/mingw.c and triggers warnings under "-Wcomma", has been + rewritten to avoid the warnings. + (merge af3919816f js/mingw-assign-comma-fix later to maint). + + * Makefile based build have recently been updated to build a + libgit.a that also has reftable and xdiff objects; CMake based + build procedure has been updated to match. + (merge b0d5c88cca js/cmake-libgit-fix later to maint). + + * Under-allocation fix. + (merge d22a488482 js/wincred-get-credential-alloc-fix later to maint). + + * "git worktree list" attempts to show paths to worktrees while + aligning them, but miscounted display columns for the paths when + non-ASCII characters were involved, which has been corrected. + (merge 08dfa59835 pw/worktree-list-display-width-fix later to maint). + + * "Windows+meson" job at the GitHub Actions CI was hard to debug, as + it did not show and save failed test artifacts, which has been + corrected. + (merge 17bd1108ea jk/ci-windows-meson-test-fix later to maint). + + * Emulation code clean-up. + (merge 2367c6bcd6 gf/win32-pthread-cond-wait-err later to maint). + + * Various issues detected by Asan have been corrected. + (merge a031b6181a jk/asan-bonanza later to maint). + + * "git config get --path" segfaulted on an ":(optional)path" that + does not exist, which has been corrected. + (merge 0bd16856ff jc/optional-path later to maint). + + * The "--committer-date-is-author-date" option of "git am/rebase" is + a misguided one. The documentation is updated to discourage its + use. + (merge fbf3d0669f kh/doc-committer-date-is-author-date later to maint). + + * The option help text given by "git config unset -h" described + the "--all" option to "replace", not "unset", multiple variables, + which has been corrected. + (merge 18bf67b753 rs/config-unset-opthelp-fix later to maint). + + * The error message given by "git config set", when the variable + being updated has more than one values defined, used old style "git + config" syntax with an incorrect option in its hint, both of which + have been corrected. + (merge df963f0df4 rs/config-set-multi-error-message-fix later to maint). + + * "git replay" forgot to omit the "gpgsig-sha256" extended header + from the resulting commit the same way it omits "gpgsig", which has + been corrected. + (merge 9f3a115087 pw/replay-exclude-gpgsig-fix later to maint). + + * A few tests have been updated to work under the shell compatible + mode of zsh. + (merge a92f243a94 bc/zsh-testsuite later to maint). + + * The way patience diff finds LCS has been optimized. + (merge c7e3b8085b yc/xdiff-patience-optim later to maint). + + * Recent optimization to "last-modified" command introduced use of + uninitialized block of memory, which has been corrected. + (merge fe4e60759b tc/last-modified-active-paths-optimization later to maint). + + * "git last-modified" used to mishandle "--" to mark the beginning of + pathspec, which has been corrected. + (merge 05491b90ce js/last-modified-with-sparse-checkouts later to maint). + + * Emulation code clean-up. + (merge 42aa7603aa gf/win32-pthread-cond-init later to maint). + + * "git submodule add" to add a submodule under segfaulted, + when a submodule..something is already in .gitmodules file + without defining where its submodule..path is, which has been + corrected. + (merge dd8e8c786e jc/submodule-add later to maint). + + * "git fetch" that involves fetching tags, when a tag being fetched + needs to overwrite existing one, failed to fetch other tags, which + has been corrected. + (merge b7b17ec8a6 kn/fix-fetch-backfill-tag-with-batched-ref-updates later to maint). + + * Document "rev-list --filter-provided-objects" better. + (merge 6d8dc99478 jt/doc-rev-list-filter-provided-objects later to maint). + + * Even when there is no changes in the packfile and no need to + recompute bitmaps, "git repack" recomputed and updated the MIDX + file, which has been corrected. + (merge 6ce9d558ce ps/repack-avoid-noop-midx-rewrite later to maint). + + * Update HTTP tests to adjust for changes in curl 8.18.0 + (merge 17f4b01da7 jk/test-curl-updates later to maint). + + * Workaround the "iconv" shipped as part of macOS, which is broken + handling stateful ISO/IEC 2022 encoded strings. + (merge cee341e9dd rs/macos-iconv-workaround later to maint). + + * Running "git diff" with "--name-only" and other options that allows + us not to look at the blob contents, while objects that are lazily + fetched from a promisor remote, caused use-after-free, which has + been corrected. + + * The ort merge machinery hit an assertion failure in a history with + criss-cross merges renamed a directory and a non-directory, which + has been corrected. + (merge 979ee83e8a en/ort-recursive-d-f-conflict-fix later to maint). + + * Diagnose invalid bundle-URI that lack the URI entry, instead of + crashing. + (merge 7796c14a1a sb/bundle-uri-without-uri later to maint). + + * Mailmap update for Karsten + (merge e97678c4ef js/mailmap-karsten-blees later to maint). + + * Perf-test fixes. + (merge 79d301c767 jk/t-perf-fixes later to maint). + + * Fix for a performance regression in "git cat-file". + (merge 9e8b448dd8 jk/cat-file-avoid-bitmap-when-unneeded later to maint). + + * Update a FAQ entry on synching two separate repositories using the + "git stash export/import" recently introduced. + (merge 02fc44a989 bc/doc-stash-import-export later to maint). + + * "git fsck" used inconsistent set of refs to show a confused + warning, which has been corrected. + + * Some error messages from the http transport layer lacked the + terminating newline, which has been corrected. + (merge a8227ae8d5 kt/http-backend-errors later to maint). + + * "git repack --geometric" did not work with promisor packs, which + has been corrected. + + * The logic that avoids reusing MIDX files with a wrong checksum was + broken, which has been corrected. + + * Other code cleanup, docfix, build fix, etc. + (merge 46207a54cc qj/doc-http-bad-want-response later to maint). + (merge df90eccd93 kh/doc-commit-extra-references later to maint). + (merge f18aa68861 rs/xmkstemp-simplify later to maint). + (merge fddba8f737 ja/doc-synopsis-style later to maint). + (merge 22ce0cb639 en/xdiff-cleanup-2 later to maint). + (merge 8ef7355a8f je/doc-pull later to maint). + (merge 48176f953f jc/capability-leak later to maint). + (merge 8cbbdc92f7 kh/doc-pre-commit-fix later to maint). + (merge d4bc39a4d9 mh/doc-config-gui-gcwarning later to maint). + (merge 41d425008a kh/doc-send-email-paragraph-fix later to maint). + (merge d4b732899e jc/macports-darwinports later to maint). + (merge bab391761d kj/pull-options-decl-cleanup later to maint). + (merge 007b8994d4 rs/t4014-git-version-string-fix later to maint). + (merge 4ce170c522 ds/doc-scalar-config later to maint). + (merge a0c813951a jc/doc-commit-signoff-config later to maint). + (merge 8ee262985a ja/doc-misc-fixes later to maint). + (merge 1722c2244b mh/doc-core-attributesfile later to maint). + (merge c469ca26c5 dk/ci-rust-fix later to maint). + (merge 12f0be0857 gf/clear-path-cache-cleanup later to maint). + (merge 949df6ed6b js/test-func-comment-fix later to maint). + (merge 93f894c001 bc/checkout-error-message-fix later to maint). + (merge abf05d856f rs/show-branch-prio-queue later to maint). + (merge 06188ea5f3 rs/parse-config-expiry-simplify later to maint). + (merge 861dbb1586 dd/t5403-modernise later to maint). + (merge acffc5e9e5 ja/doc-synopsis-style-more later to maint). + (merge 6c5c7e7071 ac/t1420-use-more-direct-check later to maint). + (merge 2ac93bfcbc ds/builtin-doc-update later to maint). + (merge 3f051fc9c9 kh/doc-patch-id later to maint). + (merge 555c8464e5 je/doc-reset later to maint). + (merge 220f888d7e ps/t1410-cleanup later to maint). + (merge 5814b04c02 ps/config-doc-get-urlmatch-fix later to maint). + (merge 5ae594f30b sb/doc-update-ref-markup-fix later to maint). + (merge bc8556d066 ty/t1005-test-path-is-helpers later to maint). diff --git a/Documentation/config/replay.adoc b/Documentation/config/replay.adoc new file mode 100644 index 00000000..7d549d2f --- /dev/null +++ b/Documentation/config/replay.adoc @@ -0,0 +1,11 @@ +replay.refAction:: + Specifies the default mode for handling reference updates in + `git replay`. The value can be: ++ +-- + * `update`: Update refs directly using an atomic transaction (default behavior). + * `print`: Output update-ref commands for pipeline use. +-- ++ +This setting can be overridden with the `--ref-action` command-line option. +When not configured, `git replay` defaults to `update` mode. diff --git a/Documentation/diff-algorithm-option.adoc b/Documentation/diff-algorithm-option.adoc new file mode 100644 index 00000000..8e3a0b63 --- /dev/null +++ b/Documentation/diff-algorithm-option.adoc @@ -0,0 +1,20 @@ +`--diff-algorithm=(patience|minimal|histogram|myers)`:: + Choose a diff algorithm. The variants are as follows: ++ +-- + `default`;; + `myers`;; + The basic greedy diff algorithm. Currently, this is the default. + `minimal`;; + Spend extra time to make sure the smallest possible diff is + produced. + `patience`;; + Use "patience diff" algorithm when generating patches. + `histogram`;; + This algorithm extends the patience algorithm to "support + low-occurrence common elements". +-- ++ +For instance, if you configured the `diff.algorithm` variable to a +non-default value and want to use the default one, then you +have to use `--diff-algorithm=default` option. diff --git a/Documentation/for-each-ref-options.adoc b/Documentation/for-each-ref-options.adoc new file mode 100644 index 00000000..f13efb5f --- /dev/null +++ b/Documentation/for-each-ref-options.adoc @@ -0,0 +1,85 @@ +`...`:: + If one or more __ parameters are given, only refs are shown that + match against at least one pattern, either using `fnmatch`(3) or + literally, in the latter case matching completely or from the + beginning up to a slash. + +`--stdin`:: + The list of patterns is read from standard input instead of from + the argument list. + +`--count=`:: + Stop after showing __ refs. + +`--sort=`:: + Sort on the field name __. Prefix `-` to sort in + descending order of the value. When unspecified, + `refname` is used. You may use the `--sort=` option + multiple times, in which case the last key becomes the primary + key. + +`--format[=]`:: + A string that interpolates `%(fieldname)` from a ref being shown and + the object it points at. In addition, the string literal `%%` + renders as `%` and `%xx` - where `xx` are hex digits - renders as + the character with hex code `xx`. For example, `%00` interpolates to + `\0` (_NUL_), `%09` to `\t` (_TAB_), and `%0a` to `\n` (_LF_). + +When unspecified, __ defaults to `%(objectname) SPC %(objecttype) +TAB %(refname)`. + +`--color[=]`:: + Respect any colors specified in the `--format` option. The + _` is absent, behave as if `always` was given). + +`--shell`:: +`--perl`:: +`--python`:: +`--tcl`:: + If given, strings that substitute `%(fieldname)` + placeholders are quoted as string literals suitable for + the specified host language. This is meant to produce + a scriptlet that can directly be "eval"ed. + +`--points-at=`:: + Only list refs which points at the given object. + +`--merged[=]`:: + Only list refs whose tips are reachable from the + specified commit (`HEAD` if not specified). + +`--no-merged[=]`:: + Only list refs whose tips are not reachable from __(`HEAD` if not + specified). + +`--contains[=]`:: + Only list refs which contain __(`HEAD` if not specified). + +`--no-contains[=]`:: + Only list refs which don't contain __ (`HEAD` + if not specified). + +`--ignore-case`:: + Sorting and filtering refs are case insensitive. + +`--omit-empty`:: + Do not print a newline after formatted refs where the format expands + to the empty string. + +`--exclude=`:: + If one or more `--exclude` options are given, only refs which do not + match any __ parameters are shown. Matching is done + using the same rules as __ above. + +`--include-root-refs`:: + List root refs (`HEAD` and pseudorefs) apart from regular refs. + +`--start-after=`:: + Allows paginating the output by skipping references up to and including the + specified marker. When paging, it should be noted that references may be + deleted, modified or added between invocations. Output will only yield those + references which follow the marker lexicographically. Output begins from the + first reference that would come after the marker alphabetically. Cannot be + used with `--sort=` or `--stdin` options, or the __ argument(s) + to limit the refs. diff --git a/Documentation/git-last-modified.adoc b/Documentation/git-last-modified.adoc new file mode 100644 index 00000000..602843e0 --- /dev/null +++ b/Documentation/git-last-modified.adoc @@ -0,0 +1,54 @@ +git-last-modified(1) +==================== + +NAME +---- +git-last-modified - EXPERIMENTAL: Show when files were last modified + + +SYNOPSIS +-------- +[synopsis] +git last-modified [--recursive] [--show-trees] [] [[--] ...] + +DESCRIPTION +----------- + +Shows which commit last modified each of the relevant files and subdirectories. +A commit renaming a path, or changing it's mode is also taken into account. + +THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHANGE. + +OPTIONS +------- + +`-r`:: +`--recursive`:: + Instead of showing tree entries, step into subtrees and show all entries + inside them recursively. + +`-t`:: +`--show-trees`:: + Show tree entries even when recursing into them. It has no effect + without `--recursive`. + +``:: + Only traverse commits in the specified revision range. When no + `` is specified, it defaults to `HEAD` (i.e. the whole + history leading to the current commit). For a complete list of ways to + spell ``, see the 'Specifying Ranges' section of + linkgit:gitrevisions[7]. + +`[--] ...`:: + For each __ given, the commit which last modified it is returned. + Without an optional path parameter, all files and subdirectories + in path traversal the are included in the output. + +SEE ALSO +-------- +linkgit:git-blame[1], +linkgit:git-log[1]. + +GIT +--- +Part of the linkgit:git[1] suite diff --git a/Documentation/git-repo.adoc b/Documentation/git-repo.adoc new file mode 100644 index 00000000..7d70270d --- /dev/null +++ b/Documentation/git-repo.adoc @@ -0,0 +1,122 @@ +git-repo(1) +=========== + +NAME +---- +git-repo - Retrieve information about the repository + +SYNOPSIS +-------- +[synopsis] +git repo info [--format=(keyvalue|nul) | -z] [--all | ...] +git repo structure [--format=(table|keyvalue|nul) | -z] + +DESCRIPTION +----------- +Retrieve information about the repository. + +THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHANGE. + +COMMANDS +-------- +`info [--format=(keyvalue|nul) | -z] [--all | ...]`:: + Retrieve metadata-related information about the current repository. Only + the requested data will be returned based on their keys (see "INFO KEYS" + section below). ++ +The values are returned in the same order in which their respective keys were +requested. The `--all` flag requests the values for all the available keys. ++ +The output format can be chosen through the flag `--format`. Two formats are +supported: ++ +`keyvalue`::: + output key-value pairs one per line using the `=` character as + the delimiter between the key and the value. Values containing "unusual" + characters are quoted as explained for the configuration variable + `core.quotePath` (see linkgit:git-config[1]). This is the default. + +`nul`::: + similar to `keyvalue`, but using a newline character as the delimiter + between the key and the value and using a NUL character after each value. + This format is better suited for being parsed by another applications than + `keyvalue`. Unlike in the `keyvalue` format, the values are never quoted. ++ +`-z` is an alias for `--format=nul`. + +`structure [--format=(table|keyvalue|nul) | -z]`:: + Retrieve statistics about the current repository structure. The + following kinds of information are reported: ++ +* Reference counts categorized by type +* Reachable object counts categorized by type +* Total inflated size of reachable objects by type +* Total disk size of reachable objects by type ++ +The output format can be chosen through the flag `--format`. Three formats are +supported: ++ +`table`::: + Outputs repository stats in a human-friendly table. This format may + change and is not intended for machine parsing. This is the default + format. + +`keyvalue`::: + Each line of output contains a key-value pair for a repository stat. + The '=' character is used to delimit between the key and the value. + Values containing "unusual" characters are quoted as explained for the + configuration variable `core.quotePath` (see linkgit:git-config[1]). + +`nul`::: + Similar to `keyvalue`, but uses a NUL character to delimit between + key-value pairs instead of a newline. Also uses a newline character as + the delimiter between the key and value instead of '='. Unlike the + `keyvalue` format, values containing "unusual" characters are never + quoted. ++ +`-z` is an alias for `--format=nul`. + +INFO KEYS +--------- +In order to obtain a set of values from `git repo info`, you should provide +the keys that identify them. Here's a list of the available keys and the +values that they return: + +`layout.bare`:: + `true` if this is a bare repository, otherwise `false`. + +`layout.shallow`:: + `true` if this is a shallow repository, otherwise `false`. + +`object.format`:: + The object format (hash algorithm) used in the repository. + +`references.format`:: + The reference storage format. The valid values are: ++ +include::ref-storage-format.adoc[] + +EXAMPLES +-------- + +* Retrieves the reference format of the current repository: ++ +------------ +git repo info references.format +------------ ++ + +* Retrieves whether the current repository is bare and whether it is shallow +using the `nul` format: ++ +------------ +git repo info --format=nul layout.bare layout.shallow +------------ + +SEE ALSO +-------- +linkgit:git-rev-parse[1] + +GIT +--- +Part of the linkgit:git[1] suite diff --git a/Documentation/gitdatamodel.adoc b/Documentation/gitdatamodel.adoc new file mode 100644 index 00000000..dcfdff03 --- /dev/null +++ b/Documentation/gitdatamodel.adoc @@ -0,0 +1,305 @@ +gitdatamodel(7) +=============== + +NAME +---- +gitdatamodel - Git's core data model + +SYNOPSIS +-------- +gitdatamodel + +DESCRIPTION +----------- + +It's not necessary to understand Git's data model to use Git, but it's +very helpful when reading Git's documentation so that you know what it +means when the documentation says "object", "reference" or "index". + +Git's core operations use 4 kinds of data: + +1. <>: commits, trees, blobs, and tag objects +2. <>: branches, tags, + remote-tracking branches, etc +3. <>, also known as the staging area +4. <>: logs of changes to references ("ref log") + +[[objects]] +OBJECTS +------- + +All of the commits and files in a Git repository are stored as "Git objects". +Git objects never change after they're created, and every object has an ID, +like `1b61de420a21a2f1aaef93e38ecd0e45e8bc9f0a`. + +This means that if you have an object's ID, you can always recover its +exact contents as long as the object hasn't been deleted. + +Every object has: + +[[object-id]] +1. an *ID* (aka "object name"), which is a cryptographic hash of its + type and contents. + It's fast to look up a Git object using its ID. + This is usually represented in hexadecimal, like + `1b61de420a21a2f1aaef93e38ecd0e45e8bc9f0a`. +2. a *type*. There are 4 types of objects: + <>, <>, <>, + and <>. +3. *contents*. The structure of the contents depends on the type. + +Here's how each type of object is structured: + +[[commit]] +commit:: + A commit contains these required fields + (though there are other optional fields): ++ +1. The full directory structure of all the files in that version of the + repository and each file's contents, stored as the *<>* ID + of the commit's top-level directory +2. Its *parent commit ID(s)*. The first commit in a repository has 0 parents, + regular commits have 1 parent, merge commits have 2 or more parents +3. An *author* and the time the commit was authored +4. A *committer* and the time the commit was committed +5. A *commit message* ++ +Here's how an example commit is stored: ++ +---- +tree 1b61de420a21a2f1aaef93e38ecd0e45e8bc9f0a +parent 4ccb6d7b8869a86aae2e84c56523f8705b50c647 +author Maya 1759173425 -0400 +committer Maya 1759173425 -0400 + +Add README +---- ++ +Like all other objects, commits can never be changed after they're created. +For example, "amending" a commit with `git commit --amend` creates a new +commit with the same parent. ++ +Git does not store the diff for a commit: when you ask Git to show +the commit with linkgit:git-show[1], it calculates the diff from its +parent on the fly. + +[[tree]] +tree:: + A tree is how Git represents a directory. + It can contain files or other trees (which are subdirectories). + It lists, for each item in the tree: ++ +1. The *filename*, for example `hello.py` +2. The *file type*, which must be one of these five types: + - *regular file* + - *executable file* + - *symbolic link* + - *directory* + - *gitlink* (for use with submodules) +3. The <> with the contents of the file, directory, + or gitlink. ++ +For example, this is how a tree containing one directory (`src`) and one file +(`README.md`) is stored: ++ +---- +100644 blob 8728a858d9d21a8c78488c8b4e70e531b659141f README.md +040000 tree 89b1d2e0495f66d6929f4ff76ff1bb07fc41947d src +---- + +NOTE: In the output above, Git displays the file type of each tree entry +using a format that's loosely modelled on Unix file modes (`100644` is +"regular file", `100755` is "executable file", `120000` is "symbolic +link", `040000` is "directory", and `160000` is "gitlink"). It also +displays the object's type: `blob` for files and symlinks, `tree` for +directories, and `commit` for gitlinks. + +[[blob]] +blob:: + A blob object contains a file's contents. ++ +When you make a commit, Git stores the full contents of each file that +you changed as a blob. +For example, if you have a commit that changes 2 files in a repository +with 1000 files, that commit will create 2 new blobs, and use the +previous blob ID for the other 998 files. +This means that commits can use relatively little disk space even in a +very large repository. + +[[tag-object]] +tag object:: + Tag objects contain these required fields + (though there are other optional fields): ++ +1. The *ID* of the object it references +2. The *type* of the object it references +3. The *tagger* and tag date +4. A *tag message*, similar to a commit message + +Here's how an example tag object is stored: + +---- +object 750b4ead9c87ceb3ddb7a390e6c7074521797fb3 +type commit +tag v1.0.0 +tagger Maya 1759927359 -0400 + +Release version 1.0.0 +---- + +NOTE: All of the examples in this section were generated with +`git cat-file -p `. + +[[references]] +REFERENCES +---------- + +References are a way to give a name to a commit. +It's easier to remember "the changes I'm working on are on the `turtle` +branch" than "the changes are in commit bb69721404348e". +Git often uses "ref" as shorthand for "reference". + +References can either refer to: + +1. An object ID, usually a <> ID +2. Another reference. This is called a "symbolic reference" + +References are stored in a hierarchy, and Git handles references +differently based on where they are in the hierarchy. +Most references are under `refs/`. Here are the main types: + +[[branch]] +branches: `refs/heads/`:: + A branch refers to a commit ID. + That commit is the latest commit on the branch. ++ +To get the history of commits on a branch, Git will start at the commit +ID the branch references, and then look at the commit's parent(s), +the parent's parent, etc. + +[[tag]] +tags: `refs/tags/`:: + A tag refers to a commit ID, tag object ID, or other object ID. + There are two types of tags: + 1. "Annotated tags", which reference a <> ID + which contains a tag message + 2. "Lightweight tags", which reference a commit, blob, or tree ID + directly ++ +Even though branches and tags both refer to a commit ID, Git +treats them very differently. +Branches are expected to change over time: when you make a commit, Git +will update your <> to point to the new commit. +Tags are usually not changed after they're created. + +[[HEAD]] +HEAD: `HEAD`:: + `HEAD` is where Git stores your current <>, + if there is a current branch. `HEAD` can either be: ++ +1. A symbolic reference to your current branch, for example `ref: + refs/heads/main` if your current branch is `main`. +2. A direct reference to a commit ID. In this case there is no current branch. + This is called "detached HEAD state", see the DETACHED HEAD section + of linkgit:git-checkout[1] for more. + +[[remote-tracking-branch]] +remote-tracking branches: `refs/remotes//`:: + A remote-tracking branch refers to a commit ID. + It's how Git stores the last-known state of a branch in a remote + repository. `git fetch` updates remote-tracking branches. When + `git status` says "you're up to date with origin/main", it's looking at + this. ++ +`refs/remotes//HEAD` is a symbolic reference to the remote's +default branch. This is the branch that `git clone` checks out by default. + +[[other-refs]] +Other references:: + Git tools may create references anywhere under `refs/`. + For example, linkgit:git-stash[1], linkgit:git-bisect[1], + and linkgit:git-notes[1] all create their own references + in `refs/stash`, `refs/bisect`, etc. + Third-party Git tools may also create their own references. ++ +Git may also create references other than `HEAD` at the base of the +hierarchy, like `ORIG_HEAD`. + +NOTE: Git may delete objects that aren't "reachable" from any reference +or <>. +An object is "reachable" if we can find it by following tags to whatever +they tag, commits to their parents or trees, and trees to the trees or +blobs that they contain. +For example, if you amend a commit with `git commit --amend`, +there will no longer be a branch that points at the old commit. +The old commit is recorded in the current branch's <>, +so it is still "reachable", but when the reflog entry expires it may +become unreachable and get deleted. +Reachable objects will never be deleted. + +[[index]] +THE INDEX +--------- +The index, also known as the "staging area", is a list of files and +the contents of each file, stored as a <>. +You can add files to the index or update the contents of a file in the +index with linkgit:git-add[1]. This is called "staging" the file for commit. + +Unlike a <>, the index is a flat list of files. +When you commit, Git converts the list of files in the index to a +directory <> and uses that tree in the new <>. + +Each index entry has 4 fields: + +1. The *file type*, which must be one of: + - *regular file* + - *executable file* + - *symbolic link* + - *gitlink* (for use with submodules) +2. The *<>* ID of the file, + or (rarely) the *<>* ID of the submodule +3. The *stage number*, either 0, 1, 2, or 3. This is normally 0, but if + there's a merge conflict there can be multiple versions of the same + filename in the index. +4. The *file path*, for example `src/hello.py` + +It's extremely uncommon to look at the index directly: normally you'd +run `git status` to see a list of changes between the index and <>. +But you can use `git ls-files --stage` to see the index. +Here's the output of `git ls-files --stage` in a repository with 2 files: + +---- +100644 8728a858d9d21a8c78488c8b4e70e531b659141f 0 README.md +100644 665c637a360874ce43bf74018768a96d2d4d219a 0 src/hello.py +---- + +[[reflogs]] +REFLOGS +------- + +Every time a branch, remote-tracking branch, or HEAD is updated, Git +updates a log called a "reflog" for that <>. +This means that if you make a mistake and "lose" a commit, you can +generally recover the commit ID by running `git reflog `. + +A reflog is a list of log entries. Each entry has: + +1. The *commit ID* +2. *Timestamp* when the change was made +3. *Log message*, for example `pull: Fast-forward` + +Reflogs only log changes made in your local repository. +They are not shared with remotes. + +You can view a reflog with `git reflog `. +For example, here's the reflog for a `main` branch which has changed twice: + +---- +$ git reflog main --date=iso --no-decorate +750b4ea main@{2025-09-29 15:17:05 -0400}: commit: Add README +4ccb6d7 main@{2025-09-29 15:16:48 -0400}: commit (initial): Initial commit +---- + +GIT +--- +Part of the linkgit:git[1] suite diff --git a/Documentation/gitformat-loose.adoc b/Documentation/gitformat-loose.adoc new file mode 100644 index 00000000..94799366 --- /dev/null +++ b/Documentation/gitformat-loose.adoc @@ -0,0 +1,53 @@ +gitformat-loose(5) +================== + +NAME +---- +gitformat-loose - Git loose object format + + +SYNOPSIS +-------- +[verse] +$GIT_DIR/objects/[0-9a-f][0-9a-f]/* + +DESCRIPTION +----------- + +Loose objects are how Git stores individual objects, where every object is +written as a separate file. + +Over the lifetime of a repository, objects are usually written as loose objects +initially. Eventually, these loose objects will be compacted into packfiles +via repository maintenance to improve disk space usage and speed up the lookup +of these objects. + +== Loose objects + +Each loose object contains a prefix, followed immediately by the data of the +object. The prefix contains ` \0`. `` is one of `blob`, +`tree`, `commit`, or `tag` and `size` is the size of the data (without the +prefix) as a decimal integer expressed in ASCII. + +The entire contents, prefix and data concatenated, is then compressed with zlib +and the compressed data is stored in the file. The object ID of the object is +the SHA-1 or SHA-256 (as appropriate) hash of the uncompressed data. + +The file for the loose object is stored under the `objects` directory, with the +first two hex characters of the object ID being the directory and the remaining +characters being the file name. This is done to shard the data and avoid too +many files being in one directory, since some file systems perform poorly with +many items in a directory. + +As an example, the empty tree contains the data (when uncompressed) `tree 0\0` +and, in a SHA-256 repository, would have the object ID +`6ef19b41225c5369f1c104d45d8d85efa9b057b53b14b4b9b939dd74decc5321` and would be +stored under +`$GIT_DIR/objects/6e/f19b41225c5369f1c104d45d8d85efa9b057b53b14b4b9b939dd74decc5321`. + +Similarly, a blob containing the contents `abc` would have the uncompressed +data of `blob 3\0abc`. + +GIT +--- +Part of the linkgit:git[1] suite diff --git a/Documentation/lint-delimited-sections.perl b/Documentation/lint-delimited-sections.perl new file mode 100755 index 00000000..140b852e --- /dev/null +++ b/Documentation/lint-delimited-sections.perl @@ -0,0 +1,48 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +my $exit_code = 0; +sub report { + my ($msg) = @_; + print STDERR "$ARGV:$.: $msg\n"; + $exit_code = 1; +} + +my $line_length = 0; +my $in_section = 0; +my $section_header = ""; + + +while (my $line = <>) { + if (($line =~ /^\+?$/) || + ($line =~ /^\[.*\]$/) || + ($line =~ /^ifdef::/)) { + $line_length = 0; + } elsif ($line =~ /^[^-.]/) { + $line_length = length($line); + } elsif (($line =~ /^-{3,}$/) || ($line =~ /^\.{3,}$/)) { + if ($in_section) { + if ($line eq $section_header) { + $in_section = 0; + } + next; + } + if ($line_length == 0) { + $in_section = 1; + $section_header = $line; + next; + } + if (($line_length != 0) && (length($line) != $line_length)) { + report("section delimiter not preceded by an empty line"); + } + $line_length = 0; + } +} + +if ($in_section) { + report("section not finished"); +} + +exit $exit_code; diff --git a/Documentation/lint-documentation-style.perl b/Documentation/lint-documentation-style.perl new file mode 100755 index 00000000..d7ab7322 --- /dev/null +++ b/Documentation/lint-documentation-style.perl @@ -0,0 +1,33 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +my $exit_code = 0; +sub report { + my ($line, $msg) = @_; + chomp $line; + print STDERR "$ARGV:$.: '$line' $msg\n"; + $exit_code = 1; +} + +my $synopsis_style = 0; + +while (my $line = <>) { + if ($line =~ /^[ \t]*`?[-a-z0-9.]+`?(, `?[-a-z0-9.]+`?)+(::|;;)$/) { + + report($line, "multiple parameters in a definition list item"); + } + if ($line =~ /^`?--\[no-\][a-z0-9-]+.*(::|;;)$/) { + report($line, "definition list item with a `--[no-]` parameter"); + } + if ($line =~ /^\[synopsis\]$/) { + $synopsis_style = 1; + } + if (($line =~ /^(-[-a-z].*|<[-a-z0-9]+>(\.{3})?)(::|;;)$/) && ($synopsis_style)) { + report($line, "synopsis style and definition list item not backquoted"); + } +} + + +exit $exit_code; diff --git a/Documentation/pack-refs-options.adoc b/Documentation/pack-refs-options.adoc new file mode 100644 index 00000000..0b112829 --- /dev/null +++ b/Documentation/pack-refs-options.adoc @@ -0,0 +1,52 @@ +--all:: + +The command by default packs all tags and refs that are already +packed, and leaves other refs +alone. This is because branches are expected to be actively +developed and packing their tips does not help performance. +This option causes all refs to be packed as well, with the exception +of hidden refs, broken refs, and symbolic refs. Useful for a repository +with many branches of historical interests. + +--no-prune:: + +The command usually removes loose refs under `$GIT_DIR/refs` +hierarchy after packing them. This option tells it not to. + +--auto:: + +Pack refs as needed depending on the current state of the ref database. The +behavior depends on the ref format used by the repository and may change in the +future. ++ + - "files": Loose references are packed into the `packed-refs` file + based on the ratio of loose references to the size of the + `packed-refs` file. The bigger the `packed-refs` file, the more loose + references need to exist before we repack. ++ + - "reftable": Tables are compacted such that they form a geometric + sequence. For two tables N and N+1, where N+1 is newer, this + maintains the property that N is at least twice as big as N+1. Only + tables that violate this property are compacted. + +--include :: + +Pack refs based on a `glob(7)` pattern. Repetitions of this option +accumulate inclusion patterns. If a ref is both included in `--include` and +`--exclude`, `--exclude` takes precedence. Using `--include` will preclude all +tags from being included by default. Symbolic refs and broken refs will never +be packed. When used with `--all`, it will be a noop. Use `--no-include` to clear +and reset the list of patterns. + +--exclude :: + +Do not pack refs matching the given `glob(7)` pattern. Repetitions of this option +accumulate exclusion patterns. Use `--no-exclude` to clear and reset the list of +patterns. If a ref is already packed, including it with `--exclude` will not +unpack it. ++ +When used with `--all`, pack only loose refs which do not match any of +the provided `--exclude` patterns. ++ +When used with `--include`, refs provided to `--include`, minus refs that are +provided to `--exclude` will be packed. diff --git a/Documentation/technical/unambiguous-types.adoc b/Documentation/technical/unambiguous-types.adoc new file mode 100644 index 00000000..9a499084 --- /dev/null +++ b/Documentation/technical/unambiguous-types.adoc @@ -0,0 +1,224 @@ += Unambiguous types + +Most of these mappings are obvious, but there are some nuances and gotchas with +Rust FFI (Foreign Function Interface). + +This document defines clear, one-to-one mappings between primitive types in C, +Rust (and possible other languages in the future). Its purpose is to eliminate +ambiguity in type widths, signedness, and binary representation across +platforms and languages. + +For Git, the only header required to use these unambiguous types in C is +`git-compat-util.h`. + +== Boolean types +[cols="1,1", options="header"] +|=== +| C Type | Rust Type +| bool^1^ | bool +|=== + +== Integer types + +In C, `` (or an equivalent) must be included. + +[cols="1,1", options="header"] +|=== +| C Type | Rust Type +| uint8_t | u8 +| uint16_t | u16 +| uint32_t | u32 +| uint64_t | u64 + +| int8_t | i8 +| int16_t | i16 +| int32_t | i32 +| int64_t | i64 +|=== + +== Floating-point types + +Rust requires IEEE-754 semantics. +In C, that is typically true, but not guaranteed by the standard. + +[cols="1,1", options="header"] +|=== +| C Type | Rust Type +| float^2^ | f32 +| double^2^ | f64 +|=== + +== Size types + +These types represent pointer-sized integers and are typically defined in +`` or an equivalent header. + +Size types should be used any time pointer arithmetic is performed e.g. +indexing an array, describing the number of elements in memory, etc... + +[cols="1,1", options="header"] +|=== +| C Type | Rust Type +| size_t^3^ | usize +| ptrdiff_t^3^ | isize +|=== + +== Character types + +This is where C and Rust don't have a clean one-to-one mapping. + +A C `char` and a Rust `u8` share the same bit width, so any C struct containing +a `char` will have the same size as the corresponding Rust struct using `u8`. +In that sense, such structs are safe to pass over the FFI boundary, because +their fields will be laid out identically. However, beyond bit width, C `char` +has additional semantics and platform-dependent behavior that can cause +problems, as discussed below. + +The C language leaves the signedness of `char` implementation defined. Because +our developer build enables -Wsign-compare, comparison of a value of `char` +type with either signed or unsigned integers may trigger warnings from the +compiler. + +Note: Rust's `char` type is an unsigned 32-bit integer that is used to describe +Unicode code points. + +=== Notes +^1^ This is only true if stdbool.h (or equivalent) is used. + +^2^ C does not enforce IEEE-754 compatibility, but Rust expects it. If the +platform/arch for C does not follow IEEE-754 then this equivalence does not +hold. Also, it's assumed that `float` is 32 bits and `double` is 64, but +there may be a strange platform/arch where even this isn't true. + +^3^ C also defines uintptr_t, ssize_t and intptr_t, but these types are +discouraged for FFI purposes. For functions like `read()` and `write()` ssize_t +should be cast to a different, and unambiguous, type before being passed over +the FFI boundary. + + +== Problems with std::ffi::c_* types in Rust +TL;DR: In practice, Rust's `c_*` types aren't guaranteed to match C types for +all possible C compilers, platforms, or architectures, because Rust only +ensures correctness of C types on officially supported targets. These +definitions have changed over time to match more targets which means that the +c_* definitions will differ based on which Rust version Git chooses to use. + +Current list of safe, Rust side, FFI types in Git: + + +* `c_void` +* `CStr` +* `CString` + +Even then, they should be used sparingly, and only where the semantics match +exactly. + +The std::os::raw::c_* directly inherits the problems of core::ffi, which +changes over time and seems to make a best guess at the correct definition for +a given platform/target. This probably isn't a problem for all other platforms +that Rust supports currently, but can anyone say that Rust got it right for all +C compilers of all platforms/targets? + +To give an example: c_long is defined in +footnote:[https://doc.rust-lang.org/1.63.0/src/core/ffi/mod.rs.html#175-189[c_long in 1.63.0]] +footnote:[https://doc.rust-lang.org/1.89.0/src/core/ffi/primitives.rs.html#135-151[c_long in 1.89.0]] + +=== Rust version 1.63.0 + +``` +mod c_long_definition { + cfg_if! { + if #[cfg(all(target_pointer_width = "64", not(windows)))] { + pub type c_long = i64; + pub type NonZero_c_long = crate::num::NonZeroI64; + pub type c_ulong = u64; + pub type NonZero_c_ulong = crate::num::NonZeroU64; + } else { + // The minimal size of `long` in the C standard is 32 bits + pub type c_long = i32; + pub type NonZero_c_long = crate::num::NonZeroI32; + pub type c_ulong = u32; + pub type NonZero_c_ulong = crate::num::NonZeroU32; + } + } +} +``` + +=== Rust version 1.89.0 + +``` +mod c_long_definition { + crate::cfg_select! { + any( + all(target_pointer_width = "64", not(windows)), + // wasm32 Linux ABI uses 64-bit long + all(target_arch = "wasm32", target_os = "linux") + ) => { + pub(super) type c_long = i64; + pub(super) type c_ulong = u64; + } + _ => { + // The minimal size of `long` in the C standard is 32 bits + pub(super) type c_long = i32; + pub(super) type c_ulong = u32; + } + } +} +``` + +Even for the cases where C types are correctly mapped to Rust types via +std::ffi::c_* there are still problems. Let's take c_char for example. On some +platforms it's u8 on others it's i8. + +=== Subtraction underflow in debug mode + +The following code will panic in debug on platforms that define c_char as u8, +but won't if it's an i8. + +``` +let mut x: std::ffi::c_char = 0; +x -= 1; +``` + +=== Inconsistent shift behavior + +`x` will be 0xC0 for platforms that use i8, but will be 0x40 where it's u8. + +``` +let mut x: std::ffi::c_char = 0x80; +x >>= 1; +``` + +=== Equality fails to compile on some platforms + +The following will not compile on platforms that define c_char as i8, but will +if it's u8. You can cast x e.g. `assert_eq!(x as u8, b'a');`, but then you get +a warning on platforms that use u8 and a clean compilation where i8 is used. + +``` +let mut x: std::ffi::c_char = 0x61; +assert_eq!(x, b'a'); +``` + +== Enum types +Rust enum types should not be used as FFI types. Rust enum types are more like +C union types than C enum's. For something like: + +``` +#[repr(C, u8)] +enum Fruit { + Apple, + Banana, + Cherry, +} +``` + +It's easy enough to make sure the Rust enum matches what C would expect, but a +more complex type like. + +``` +enum HashResult { + SHA1([u8; 20]), + SHA256([u8; 32]), +} +``` + +The Rust compiler has to add a discriminant to the enum to distinguish between +the variants. The width, location, and values for that discriminant is up to +the Rust compiler and is not ABI stable. diff --git a/builtin/last-modified.c b/builtin/last-modified.c new file mode 100644 index 00000000..c80f0535 --- /dev/null +++ b/builtin/last-modified.c @@ -0,0 +1,548 @@ +#include "git-compat-util.h" +#include "bloom.h" +#include "builtin.h" +#include "commit-graph.h" +#include "commit-slab.h" +#include "commit.h" +#include "config.h" +#include "diff.h" +#include "diffcore.h" +#include "environment.h" +#include "ewah/ewok.h" +#include "hashmap.h" +#include "hex.h" +#include "object-name.h" +#include "object.h" +#include "parse-options.h" +#include "prio-queue.h" +#include "quote.h" +#include "repository.h" +#include "revision.h" + +/* Remember to update object flag allocation in object.h */ +#define PARENT1 (1u<<16) /* used instead of SEEN */ +#define PARENT2 (1u<<17) /* used instead of BOTTOM, BOUNDARY */ + +struct last_modified_entry { + struct hashmap_entry hashent; + struct object_id oid; + struct bloom_key key; + size_t diff_idx; + const char path[FLEX_ARRAY]; +}; + +static int last_modified_entry_hashcmp(const void *unused UNUSED, + const struct hashmap_entry *hent1, + const struct hashmap_entry *hent2, + const void *path) +{ + const struct last_modified_entry *ent1 = + container_of(hent1, const struct last_modified_entry, hashent); + const struct last_modified_entry *ent2 = + container_of(hent2, const struct last_modified_entry, hashent); + return strcmp(ent1->path, path ? path : ent2->path); +} + +/* + * Hold a bitmap for each commit we're working with. In the bitmap, each bit + * represents a path in `lm->all_paths`. An active bit indicates the path still + * needs to be associated to a commit. + */ +define_commit_slab(active_paths_for_commit, struct bitmap *); + +struct last_modified { + struct hashmap paths; + struct rev_info rev; + bool recursive; + bool show_trees; + + const char **all_paths; + size_t all_paths_nr; + struct active_paths_for_commit active_paths; + + /* 'scratch' to avoid allocating a bitmap every process_parent() */ + struct bitmap *scratch; +}; + +static struct bitmap *active_paths_for(struct last_modified *lm, struct commit *c) +{ + struct bitmap **bitmap = active_paths_for_commit_at(&lm->active_paths, c); + if (!*bitmap) + *bitmap = bitmap_word_alloc(lm->all_paths_nr / BITS_IN_EWORD + 1); + + return *bitmap; +} + +static void active_paths_free(struct last_modified *lm, struct commit *c) +{ + struct bitmap **bitmap = active_paths_for_commit_at(&lm->active_paths, c); + if (*bitmap) { + bitmap_free(*bitmap); + *bitmap = NULL; + } +} + +static void last_modified_release(struct last_modified *lm) +{ + struct hashmap_iter iter; + struct last_modified_entry *ent; + + hashmap_for_each_entry(&lm->paths, &iter, ent, hashent) + bloom_key_clear(&ent->key); + + hashmap_clear_and_free(&lm->paths, struct last_modified_entry, hashent); + release_revisions(&lm->rev); + + free(lm->all_paths); +} + +struct last_modified_callback_data { + struct last_modified *lm; + struct commit *commit; +}; + +static void add_path_from_diff(struct diff_queue_struct *q, + struct diff_options *opt UNUSED, void *data) +{ + struct last_modified *lm = data; + + for (int i = 0; i < q->nr; i++) { + struct diff_filepair *p = q->queue[i]; + struct last_modified_entry *ent; + const char *path = p->two->path; + + FLEX_ALLOC_STR(ent, path, path); + oidcpy(&ent->oid, &p->two->oid); + if (lm->rev.bloom_filter_settings) + bloom_key_fill(&ent->key, path, strlen(path), + lm->rev.bloom_filter_settings); + hashmap_entry_init(&ent->hashent, strhash(ent->path)); + hashmap_add(&lm->paths, &ent->hashent); + } +} + +static int populate_paths_from_revs(struct last_modified *lm) +{ + int num_interesting = 0; + struct diff_options diffopt; + + /* + * Create a copy of `struct diff_options`. In this copy a callback is + * set that when called adds entries to `paths` in `struct last_modified`. + * This copy is used to diff the tree of the target revision against an + * empty tree. This results in all paths in the target revision being + * listed. After `paths` is populated, we don't need this copy no more. + */ + memcpy(&diffopt, &lm->rev.diffopt, sizeof(diffopt)); + copy_pathspec(&diffopt.pathspec, &lm->rev.diffopt.pathspec); + diffopt.output_format = DIFF_FORMAT_CALLBACK; + diffopt.format_callback = add_path_from_diff; + diffopt.format_callback_data = lm; + + for (size_t i = 0; i < lm->rev.pending.nr; i++) { + struct object_array_entry *obj = lm->rev.pending.objects + i; + + if (obj->item->flags & UNINTERESTING) + continue; + + if (num_interesting++) + return error(_("last-modified can only operate on one tree at a time")); + + diff_tree_oid(lm->rev.repo->hash_algo->empty_tree, + &obj->item->oid, "", &diffopt); + diff_flush(&diffopt); + } + clear_pathspec(&diffopt.pathspec); + + return 0; +} + +static void last_modified_emit(struct last_modified *lm, + const char *path, const struct commit *commit) + +{ + if (commit->object.flags & BOUNDARY) + putchar('^'); + printf("%s\t", oid_to_hex(&commit->object.oid)); + + if (lm->rev.diffopt.line_termination) + write_name_quoted(path, stdout, '\n'); + else + printf("%s%c", path, '\0'); +} + +static void mark_path(const char *path, const struct object_id *oid, + struct last_modified_callback_data *data) +{ + struct last_modified_entry *ent; + + /* Is it even a path that we are interested in? */ + ent = hashmap_get_entry_from_hash(&data->lm->paths, strhash(path), path, + struct last_modified_entry, hashent); + if (!ent) + return; + + /* + * Is it arriving at a version of interest, or is it from a side branch + * which did not contribute to the final state? + */ + if (oid && !oideq(oid, &ent->oid)) + return; + + last_modified_emit(data->lm, path, data->commit); + + hashmap_remove(&data->lm->paths, &ent->hashent, path); + bloom_key_clear(&ent->key); + free(ent); +} + +static void last_modified_diff(struct diff_queue_struct *q, + struct diff_options *opt UNUSED, void *cbdata) +{ + struct last_modified_callback_data *data = cbdata; + + for (int i = 0; i < q->nr; i++) { + struct diff_filepair *p = q->queue[i]; + switch (p->status) { + case DIFF_STATUS_DELETED: + /* + * There's no point in feeding a deletion, as it could + * not have resulted in our current state, which + * actually has the file. + */ + break; + + default: + /* + * Otherwise, we care only that we somehow arrived at + * a final oid state. Note that this covers some + * potentially controversial areas, including: + * + * 1. A rename or copy will be found, as it is the + * first time the content has arrived at the given + * path. + * + * 2. Even a non-content modification like a mode or + * type change will trigger it. + * + * We take the inclusive approach for now, and find + * anything which impacts the path. Options to tweak + * the behavior (e.g., to "--follow" the content across + * renames) can come later. + */ + mark_path(p->two->path, &p->two->oid, data); + break; + } + } +} + +static void pass_to_parent(struct bitmap *c, + struct bitmap *p, + size_t pos) +{ + bitmap_unset(c, pos); + bitmap_set(p, pos); +} + +static bool maybe_changed_path(struct last_modified *lm, + struct commit *origin, + struct bitmap *active) +{ + struct bloom_filter *filter; + struct last_modified_entry *ent; + struct hashmap_iter iter; + + if (!lm->rev.bloom_filter_settings) + return true; + + if (commit_graph_generation(origin) == GENERATION_NUMBER_INFINITY) + return true; + + filter = get_bloom_filter(lm->rev.repo, origin); + if (!filter) + return true; + + hashmap_for_each_entry(&lm->paths, &iter, ent, hashent) { + if (active && !bitmap_get(active, ent->diff_idx)) + continue; + + if (bloom_filter_contains(filter, &ent->key, + lm->rev.bloom_filter_settings)) + return true; + } + return false; +} + +static void process_parent(struct last_modified *lm, + struct prio_queue *queue, + struct commit *c, struct bitmap *active_c, + struct commit *parent, int parent_i) +{ + struct bitmap *active_p; + + repo_parse_commit(lm->rev.repo, parent); + active_p = active_paths_for(lm, parent); + + /* + * The first time entering this function for this commit (i.e. first parent) + * see if Bloom filters will tell us it's worth to do the diff. + */ + if (parent_i || maybe_changed_path(lm, c, active_c)) { + diff_tree_oid(&parent->object.oid, + &c->object.oid, "", &lm->rev.diffopt); + diffcore_std(&lm->rev.diffopt); + } + + /* + * Test each path for TREESAME-ness against the parent. If a path is + * TREESAME, pass it on to this parent. + * + * First, collect all paths that are *not* TREESAME in 'scratch'. + * Then, pass paths that *are* TREESAME and active to the parent. + */ + for (int i = 0; i < diff_queued_diff.nr; i++) { + struct diff_filepair *fp = diff_queued_diff.queue[i]; + const char *path = fp->two->path; + struct last_modified_entry *ent = + hashmap_get_entry_from_hash(&lm->paths, strhash(path), path, + struct last_modified_entry, hashent); + if (ent) { + size_t k = ent->diff_idx; + if (bitmap_get(active_c, k)) + bitmap_set(lm->scratch, k); + } + } + for (size_t i = 0; i < lm->all_paths_nr; i++) { + if (bitmap_get(active_c, i) && !bitmap_get(lm->scratch, i)) + pass_to_parent(active_c, active_p, i); + } + + /* + * If parent has any active paths, put it on the queue (if not already). + */ + if (!bitmap_is_empty(active_p) && !(parent->object.flags & PARENT1)) { + parent->object.flags |= PARENT1; + prio_queue_put(queue, parent); + } + if (!(parent->object.flags & PARENT1)) + active_paths_free(lm, parent); + + MEMZERO_ARRAY(lm->scratch->words, lm->scratch->word_alloc); + diff_queue_clear(&diff_queued_diff); +} + +static int last_modified_run(struct last_modified *lm) +{ + int max_count, queue_popped = 0; + struct prio_queue queue = { compare_commits_by_gen_then_commit_date }; + struct prio_queue not_queue = { compare_commits_by_gen_then_commit_date }; + struct commit_list *list; + struct last_modified_callback_data data = { .lm = lm }; + + lm->rev.diffopt.output_format = DIFF_FORMAT_CALLBACK; + lm->rev.diffopt.format_callback = last_modified_diff; + lm->rev.diffopt.format_callback_data = &data; + lm->rev.no_walk = 1; + + prepare_revision_walk(&lm->rev); + + max_count = lm->rev.max_count; + + init_active_paths_for_commit(&lm->active_paths); + lm->scratch = bitmap_word_alloc(lm->all_paths_nr); + + /* + * lm->rev.commits holds the set of boundary commits for our walk. + * + * Loop through each such commit, and place it in the appropriate queue. + */ + for (list = lm->rev.commits; list; list = list->next) { + struct commit *c = list->item; + + if (c->object.flags & BOTTOM) { + prio_queue_put(¬_queue, c); + c->object.flags |= PARENT2; + } else if (!(c->object.flags & PARENT1)) { + /* + * If the commit is a starting point (and hasn't been + * seen yet), then initialize the set of interesting + * paths, too. + */ + struct bitmap *active; + + prio_queue_put(&queue, c); + c->object.flags |= PARENT1; + + active = active_paths_for(lm, c); + for (size_t i = 0; i < lm->all_paths_nr; i++) + bitmap_set(active, i); + } + } + + while (queue.nr) { + int parent_i; + struct commit_list *p; + struct commit *c = prio_queue_get(&queue); + struct bitmap *active_c = active_paths_for(lm, c); + + if ((0 <= max_count && max_count < ++queue_popped) || + (c->object.flags & PARENT2)) { + /* + * Either a boundary commit, or we have already seen too + * many others. Either way, stop here. + */ + c->object.flags |= PARENT2 | BOUNDARY; + data.commit = c; + diff_tree_oid(lm->rev.repo->hash_algo->empty_tree, + &c->object.oid, + "", &lm->rev.diffopt); + diff_flush(&lm->rev.diffopt); + goto cleanup; + } + + /* + * Otherwise, make sure that 'c' isn't reachable from anything + * in the '--not' queue. + */ + repo_parse_commit(lm->rev.repo, c); + + while (not_queue.nr) { + struct commit_list *np; + struct commit *n = prio_queue_get(¬_queue); + + repo_parse_commit(lm->rev.repo, n); + + for (np = n->parents; np; np = np->next) { + if (!(np->item->object.flags & PARENT2)) { + prio_queue_put(¬_queue, np->item); + np->item->object.flags |= PARENT2; + } + } + + if (commit_graph_generation(n) < commit_graph_generation(c)) + break; + } + + /* + * Look at each parent and pass on each path that's TREESAME + * with that parent. Stop early when no active paths remain. + */ + for (p = c->parents, parent_i = 0; p; p = p->next, parent_i++) { + process_parent(lm, &queue, + c, active_c, + p->item, parent_i); + + if (bitmap_is_empty(active_c)) + break; + } + + /* + * Paths that remain active, or not TREESAME with any parent, + * were changed by 'c'. + */ + if (!bitmap_is_empty(active_c)) { + data.commit = c; + for (size_t i = 0; i < lm->all_paths_nr; i++) { + if (bitmap_get(active_c, i)) + mark_path(lm->all_paths[i], NULL, &data); + } + } + +cleanup: + active_paths_free(lm, c); + } + + if (hashmap_get_size(&lm->paths)) + BUG("paths remaining beyond boundary in last-modified"); + + clear_prio_queue(¬_queue); + clear_prio_queue(&queue); + clear_active_paths_for_commit(&lm->active_paths); + bitmap_free(lm->scratch); + + return 0; +} + +static int last_modified_init(struct last_modified *lm, struct repository *r, + const char *prefix, int argc, const char **argv) +{ + struct hashmap_iter iter; + struct last_modified_entry *ent; + + hashmap_init(&lm->paths, last_modified_entry_hashcmp, NULL, 0); + + repo_init_revisions(r, &lm->rev, prefix); + lm->rev.def = "HEAD"; + lm->rev.combine_merges = 1; + lm->rev.show_root_diff = 1; + lm->rev.boundary = 1; + lm->rev.no_commit_id = 1; + lm->rev.diff = 1; + lm->rev.diffopt.flags.no_recursive_diff_tree_combined = 1; + lm->rev.diffopt.flags.recursive = lm->recursive; + lm->rev.diffopt.flags.tree_in_recursive = lm->show_trees; + + argc = setup_revisions(argc, argv, &lm->rev, NULL); + if (argc > 1) { + error(_("unknown last-modified argument: %s"), argv[1]); + return argc; + } + + lm->rev.bloom_filter_settings = get_bloom_filter_settings(lm->rev.repo); + + if (populate_paths_from_revs(lm) < 0) + return error(_("unable to setup last-modified")); + + CALLOC_ARRAY(lm->all_paths, hashmap_get_size(&lm->paths)); + lm->all_paths_nr = 0; + hashmap_for_each_entry(&lm->paths, &iter, ent, hashent) { + ent->diff_idx = lm->all_paths_nr++; + lm->all_paths[ent->diff_idx] = ent->path; + } + + return 0; +} + +int cmd_last_modified(int argc, const char **argv, const char *prefix, + struct repository *repo) +{ + int ret; + struct last_modified lm = { 0 }; + + const char * const last_modified_usage[] = { + N_("git last-modified [--recursive] [--show-trees] " + "[] [[--] ...]"), + NULL + }; + + struct option last_modified_options[] = { + OPT_BOOL('r', "recursive", &lm.recursive, + N_("recurse into subtrees")), + OPT_BOOL('t', "show-trees", &lm.show_trees, + N_("show tree entries when recursing into subtrees")), + OPT_END() + }; + + argc = parse_options(argc, argv, prefix, last_modified_options, + last_modified_usage, + PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN_OPT | + PARSE_OPT_KEEP_DASHDASH); + + repo_config(repo, git_default_config, NULL); + + ret = last_modified_init(&lm, repo, prefix, argc, argv); + if (ret > 0) + usage_with_options(last_modified_usage, + last_modified_options); + if (ret) + goto out; + + ret = last_modified_run(&lm); + if (ret) + goto out; + +out: + last_modified_release(&lm); + + return ret; +} diff --git a/builtin/repo.c b/builtin/repo.c new file mode 100644 index 00000000..0ea045ab --- /dev/null +++ b/builtin/repo.c @@ -0,0 +1,703 @@ +#define USE_THE_REPOSITORY_VARIABLE + +#include "builtin.h" +#include "environment.h" +#include "hex.h" +#include "odb.h" +#include "parse-options.h" +#include "path-walk.h" +#include "progress.h" +#include "quote.h" +#include "ref-filter.h" +#include "refs.h" +#include "revision.h" +#include "strbuf.h" +#include "string-list.h" +#include "shallow.h" +#include "utf8.h" + +static const char *const repo_usage[] = { + "git repo info [--format=(keyvalue|nul) | -z] [--all | ...]", + "git repo structure [--format=(table|keyvalue|nul) | -z]", + NULL +}; + +typedef int get_value_fn(struct repository *repo, struct strbuf *buf); + +enum output_format { + FORMAT_TABLE, + FORMAT_KEYVALUE, + FORMAT_NUL_TERMINATED, +}; + +struct field { + const char *key; + get_value_fn *get_value; +}; + +static int get_layout_bare(struct repository *repo UNUSED, struct strbuf *buf) +{ + strbuf_addstr(buf, is_bare_repository() ? "true" : "false"); + return 0; +} + +static int get_layout_shallow(struct repository *repo, struct strbuf *buf) +{ + strbuf_addstr(buf, + is_repository_shallow(repo) ? "true" : "false"); + return 0; +} + +static int get_object_format(struct repository *repo, struct strbuf *buf) +{ + strbuf_addstr(buf, repo->hash_algo->name); + return 0; +} + +static int get_references_format(struct repository *repo, struct strbuf *buf) +{ + strbuf_addstr(buf, + ref_storage_format_to_name(repo->ref_storage_format)); + return 0; +} + +/* repo_info_fields keys must be in lexicographical order */ +static const struct field repo_info_fields[] = { + { "layout.bare", get_layout_bare }, + { "layout.shallow", get_layout_shallow }, + { "object.format", get_object_format }, + { "references.format", get_references_format }, +}; + +static int repo_info_fields_cmp(const void *va, const void *vb) +{ + const struct field *a = va; + const struct field *b = vb; + + return strcmp(a->key, b->key); +} + +static get_value_fn *get_value_fn_for_key(const char *key) +{ + const struct field search_key = { key, NULL }; + const struct field *found = bsearch(&search_key, repo_info_fields, + ARRAY_SIZE(repo_info_fields), + sizeof(*found), + repo_info_fields_cmp); + return found ? found->get_value : NULL; +} + +static void print_field(enum output_format format, const char *key, + const char *value) +{ + switch (format) { + case FORMAT_KEYVALUE: + printf("%s=", key); + quote_c_style(value, NULL, stdout, 0); + putchar('\n'); + break; + case FORMAT_NUL_TERMINATED: + printf("%s\n%s%c", key, value, '\0'); + break; + default: + BUG("not a valid output format: %d", format); + } +} + +static int print_fields(int argc, const char **argv, + struct repository *repo, + enum output_format format) +{ + int ret = 0; + struct strbuf valbuf = STRBUF_INIT; + + for (int i = 0; i < argc; i++) { + get_value_fn *get_value; + const char *key = argv[i]; + + get_value = get_value_fn_for_key(key); + + if (!get_value) { + ret = error(_("key '%s' not found"), key); + continue; + } + + strbuf_reset(&valbuf); + get_value(repo, &valbuf); + print_field(format, key, valbuf.buf); + } + + strbuf_release(&valbuf); + return ret; +} + +static int print_all_fields(struct repository *repo, + enum output_format format) +{ + struct strbuf valbuf = STRBUF_INIT; + + for (size_t i = 0; i < ARRAY_SIZE(repo_info_fields); i++) { + const struct field *field = &repo_info_fields[i]; + + strbuf_reset(&valbuf); + field->get_value(repo, &valbuf); + print_field(format, field->key, valbuf.buf); + } + + strbuf_release(&valbuf); + return 0; +} + +static int parse_format_cb(const struct option *opt, + const char *arg, int unset UNUSED) +{ + enum output_format *format = opt->value; + + if (opt->short_name == 'z') + *format = FORMAT_NUL_TERMINATED; + else if (!strcmp(arg, "nul")) + *format = FORMAT_NUL_TERMINATED; + else if (!strcmp(arg, "keyvalue")) + *format = FORMAT_KEYVALUE; + else if (!strcmp(arg, "table")) + *format = FORMAT_TABLE; + else + die(_("invalid format '%s'"), arg); + + return 0; +} + +static int cmd_repo_info(int argc, const char **argv, const char *prefix, + struct repository *repo) +{ + enum output_format format = FORMAT_KEYVALUE; + int all_keys = 0; + struct option options[] = { + OPT_CALLBACK_F(0, "format", &format, N_("format"), + N_("output format"), + PARSE_OPT_NONEG, parse_format_cb), + OPT_CALLBACK_F('z', NULL, &format, NULL, + N_("synonym for --format=nul"), + PARSE_OPT_NONEG | PARSE_OPT_NOARG, + parse_format_cb), + OPT_BOOL(0, "all", &all_keys, N_("print all keys/values")), + OPT_END() + }; + + argc = parse_options(argc, argv, prefix, options, repo_usage, 0); + if (format != FORMAT_KEYVALUE && format != FORMAT_NUL_TERMINATED) + die(_("unsupported output format")); + + if (all_keys && argc) + die(_("--all and cannot be used together")); + + if (all_keys) + return print_all_fields(repo, format); + else + return print_fields(argc, argv, repo, format); +} + +struct ref_stats { + size_t branches; + size_t remotes; + size_t tags; + size_t others; +}; + +struct object_values { + size_t tags; + size_t commits; + size_t trees; + size_t blobs; +}; + +struct object_stats { + struct object_values type_counts; + struct object_values inflated_sizes; + struct object_values disk_sizes; +}; + +struct repo_structure { + struct ref_stats refs; + struct object_stats objects; +}; + +struct stats_table { + struct string_list rows; + + int name_col_width; + int value_col_width; + int unit_col_width; +}; + +/* + * Holds column data that gets stored for each row. + */ +struct stats_table_entry { + char *value; + const char *unit; +}; + +static void stats_table_vaddf(struct stats_table *table, + struct stats_table_entry *entry, + const char *format, va_list ap) +{ + struct strbuf buf = STRBUF_INIT; + struct string_list_item *item; + char *formatted_name; + int name_width; + + strbuf_vaddf(&buf, format, ap); + formatted_name = strbuf_detach(&buf, NULL); + name_width = utf8_strwidth(formatted_name); + + item = string_list_append_nodup(&table->rows, formatted_name); + item->util = entry; + + if (name_width > table->name_col_width) + table->name_col_width = name_width; + if (!entry) + return; + if (entry->value) { + int value_width = utf8_strwidth(entry->value); + if (value_width > table->value_col_width) + table->value_col_width = value_width; + } + if (entry->unit) { + int unit_width = utf8_strwidth(entry->unit); + if (unit_width > table->unit_col_width) + table->unit_col_width = unit_width; + } +} + +static void stats_table_addf(struct stats_table *table, const char *format, ...) +{ + va_list ap; + + va_start(ap, format); + stats_table_vaddf(table, NULL, format, ap); + va_end(ap); +} + +static void stats_table_count_addf(struct stats_table *table, size_t value, + const char *format, ...) +{ + struct stats_table_entry *entry; + va_list ap; + + CALLOC_ARRAY(entry, 1); + humanise_count(value, &entry->value, &entry->unit); + + va_start(ap, format); + stats_table_vaddf(table, entry, format, ap); + va_end(ap); +} + +static void stats_table_size_addf(struct stats_table *table, size_t value, + const char *format, ...) +{ + struct stats_table_entry *entry; + va_list ap; + + CALLOC_ARRAY(entry, 1); + humanise_bytes(value, &entry->value, &entry->unit, HUMANISE_COMPACT); + + va_start(ap, format); + stats_table_vaddf(table, entry, format, ap); + va_end(ap); +} + +static inline size_t get_total_reference_count(struct ref_stats *stats) +{ + return stats->branches + stats->remotes + stats->tags + stats->others; +} + +static inline size_t get_total_object_values(struct object_values *values) +{ + return values->tags + values->commits + values->trees + values->blobs; +} + +static void stats_table_setup_structure(struct stats_table *table, + struct repo_structure *stats) +{ + struct object_stats *objects = &stats->objects; + struct ref_stats *refs = &stats->refs; + size_t inflated_object_total; + size_t object_count_total; + size_t disk_object_total; + size_t ref_total; + + ref_total = get_total_reference_count(refs); + stats_table_addf(table, "* %s", _("References")); + stats_table_count_addf(table, ref_total, " * %s", _("Count")); + stats_table_count_addf(table, refs->branches, " * %s", _("Branches")); + stats_table_count_addf(table, refs->tags, " * %s", _("Tags")); + stats_table_count_addf(table, refs->remotes, " * %s", _("Remotes")); + stats_table_count_addf(table, refs->others, " * %s", _("Others")); + + object_count_total = get_total_object_values(&objects->type_counts); + stats_table_addf(table, ""); + stats_table_addf(table, "* %s", _("Reachable objects")); + stats_table_count_addf(table, object_count_total, " * %s", _("Count")); + stats_table_count_addf(table, objects->type_counts.commits, + " * %s", _("Commits")); + stats_table_count_addf(table, objects->type_counts.trees, + " * %s", _("Trees")); + stats_table_count_addf(table, objects->type_counts.blobs, + " * %s", _("Blobs")); + stats_table_count_addf(table, objects->type_counts.tags, + " * %s", _("Tags")); + + inflated_object_total = get_total_object_values(&objects->inflated_sizes); + stats_table_size_addf(table, inflated_object_total, + " * %s", _("Inflated size")); + stats_table_size_addf(table, objects->inflated_sizes.commits, + " * %s", _("Commits")); + stats_table_size_addf(table, objects->inflated_sizes.trees, + " * %s", _("Trees")); + stats_table_size_addf(table, objects->inflated_sizes.blobs, + " * %s", _("Blobs")); + stats_table_size_addf(table, objects->inflated_sizes.tags, + " * %s", _("Tags")); + + disk_object_total = get_total_object_values(&objects->disk_sizes); + stats_table_size_addf(table, disk_object_total, + " * %s", _("Disk size")); + stats_table_size_addf(table, objects->disk_sizes.commits, + " * %s", _("Commits")); + stats_table_size_addf(table, objects->disk_sizes.trees, + " * %s", _("Trees")); + stats_table_size_addf(table, objects->disk_sizes.blobs, + " * %s", _("Blobs")); + stats_table_size_addf(table, objects->disk_sizes.tags, + " * %s", _("Tags")); +} + +static void stats_table_print_structure(const struct stats_table *table) +{ + const char *name_col_title = _("Repository structure"); + const char *value_col_title = _("Value"); + int title_name_width = utf8_strwidth(name_col_title); + int title_value_width = utf8_strwidth(value_col_title); + int name_col_width = table->name_col_width; + int value_col_width = table->value_col_width; + int unit_col_width = table->unit_col_width; + struct string_list_item *item; + struct strbuf buf = STRBUF_INIT; + + if (title_name_width > name_col_width) + name_col_width = title_name_width; + if (title_value_width > value_col_width + unit_col_width + 1) + value_col_width = title_value_width - unit_col_width; + + strbuf_addstr(&buf, "| "); + strbuf_utf8_align(&buf, ALIGN_LEFT, name_col_width, name_col_title); + strbuf_addstr(&buf, " | "); + strbuf_utf8_align(&buf, ALIGN_LEFT, + value_col_width + unit_col_width + 1, value_col_title); + strbuf_addstr(&buf, " |"); + printf("%s\n", buf.buf); + + printf("| "); + for (int i = 0; i < name_col_width; i++) + putchar('-'); + printf(" | "); + for (int i = 0; i < value_col_width + unit_col_width + 1; i++) + putchar('-'); + printf(" |\n"); + + for_each_string_list_item(item, &table->rows) { + struct stats_table_entry *entry = item->util; + const char *value = ""; + const char *unit = ""; + + if (entry) { + struct stats_table_entry *entry = item->util; + value = entry->value; + if (entry->unit) + unit = entry->unit; + } + + strbuf_reset(&buf); + strbuf_addstr(&buf, "| "); + strbuf_utf8_align(&buf, ALIGN_LEFT, name_col_width, item->string); + strbuf_addstr(&buf, " | "); + strbuf_utf8_align(&buf, ALIGN_RIGHT, value_col_width, value); + strbuf_addch(&buf, ' '); + strbuf_utf8_align(&buf, ALIGN_LEFT, unit_col_width, unit); + strbuf_addstr(&buf, " |"); + printf("%s\n", buf.buf); + } + + strbuf_release(&buf); +} + +static void stats_table_clear(struct stats_table *table) +{ + struct stats_table_entry *entry; + struct string_list_item *item; + + for_each_string_list_item(item, &table->rows) { + entry = item->util; + if (entry) + free(entry->value); + } + + string_list_clear(&table->rows, 1); +} + +static void structure_keyvalue_print(struct repo_structure *stats, + char key_delim, char value_delim) +{ + printf("references.branches.count%c%" PRIuMAX "%c", key_delim, + (uintmax_t)stats->refs.branches, value_delim); + printf("references.tags.count%c%" PRIuMAX "%c", key_delim, + (uintmax_t)stats->refs.tags, value_delim); + printf("references.remotes.count%c%" PRIuMAX "%c", key_delim, + (uintmax_t)stats->refs.remotes, value_delim); + printf("references.others.count%c%" PRIuMAX "%c", key_delim, + (uintmax_t)stats->refs.others, value_delim); + + printf("objects.commits.count%c%" PRIuMAX "%c", key_delim, + (uintmax_t)stats->objects.type_counts.commits, value_delim); + printf("objects.trees.count%c%" PRIuMAX "%c", key_delim, + (uintmax_t)stats->objects.type_counts.trees, value_delim); + printf("objects.blobs.count%c%" PRIuMAX "%c", key_delim, + (uintmax_t)stats->objects.type_counts.blobs, value_delim); + printf("objects.tags.count%c%" PRIuMAX "%c", key_delim, + (uintmax_t)stats->objects.type_counts.tags, value_delim); + + printf("objects.commits.inflated_size%c%" PRIuMAX "%c", key_delim, + (uintmax_t)stats->objects.inflated_sizes.commits, value_delim); + printf("objects.trees.inflated_size%c%" PRIuMAX "%c", key_delim, + (uintmax_t)stats->objects.inflated_sizes.trees, value_delim); + printf("objects.blobs.inflated_size%c%" PRIuMAX "%c", key_delim, + (uintmax_t)stats->objects.inflated_sizes.blobs, value_delim); + printf("objects.tags.inflated_size%c%" PRIuMAX "%c", key_delim, + (uintmax_t)stats->objects.inflated_sizes.tags, value_delim); + + printf("objects.commits.disk_size%c%" PRIuMAX "%c", key_delim, + (uintmax_t)stats->objects.disk_sizes.commits, value_delim); + printf("objects.trees.disk_size%c%" PRIuMAX "%c", key_delim, + (uintmax_t)stats->objects.disk_sizes.trees, value_delim); + printf("objects.blobs.disk_size%c%" PRIuMAX "%c", key_delim, + (uintmax_t)stats->objects.disk_sizes.blobs, value_delim); + printf("objects.tags.disk_size%c%" PRIuMAX "%c", key_delim, + (uintmax_t)stats->objects.disk_sizes.tags, value_delim); + + fflush(stdout); +} + +struct count_references_data { + struct ref_stats *stats; + struct rev_info *revs; + struct progress *progress; +}; + +static int count_references(const struct reference *ref, void *cb_data) +{ + struct count_references_data *data = cb_data; + struct ref_stats *stats = data->stats; + size_t ref_count; + + switch (ref_kind_from_refname(ref->name)) { + case FILTER_REFS_BRANCHES: + stats->branches++; + break; + case FILTER_REFS_REMOTES: + stats->remotes++; + break; + case FILTER_REFS_TAGS: + stats->tags++; + break; + case FILTER_REFS_OTHERS: + stats->others++; + break; + default: + BUG("unexpected reference type"); + } + + /* + * While iterating through references for counting, also add OIDs in + * preparation for the path walk. + */ + add_pending_oid(data->revs, NULL, ref->oid, 0); + + ref_count = get_total_reference_count(stats); + display_progress(data->progress, ref_count); + + return 0; +} + +static void structure_count_references(struct ref_stats *stats, + struct rev_info *revs, + struct repository *repo, + int show_progress) +{ + struct count_references_data data = { + .stats = stats, + .revs = revs, + }; + + if (show_progress) + data.progress = start_delayed_progress(repo, + _("Counting references"), 0); + + refs_for_each_ref(get_main_ref_store(repo), count_references, &data); + stop_progress(&data.progress); +} + +struct count_objects_data { + struct object_database *odb; + struct object_stats *stats; + struct progress *progress; +}; + +static int count_objects(const char *path UNUSED, struct oid_array *oids, + enum object_type type, void *cb_data) +{ + struct count_objects_data *data = cb_data; + struct object_stats *stats = data->stats; + size_t inflated_total = 0; + size_t disk_total = 0; + size_t object_count; + + for (size_t i = 0; i < oids->nr; i++) { + struct object_info oi = OBJECT_INFO_INIT; + unsigned long inflated; + off_t disk; + + oi.sizep = &inflated; + oi.disk_sizep = &disk; + + if (odb_read_object_info_extended(data->odb, &oids->oid[i], &oi, + OBJECT_INFO_SKIP_FETCH_OBJECT | + OBJECT_INFO_QUICK) < 0) + continue; + + inflated_total += inflated; + disk_total += disk; + } + + switch (type) { + case OBJ_TAG: + stats->type_counts.tags += oids->nr; + stats->inflated_sizes.tags += inflated_total; + stats->disk_sizes.tags += disk_total; + break; + case OBJ_COMMIT: + stats->type_counts.commits += oids->nr; + stats->inflated_sizes.commits += inflated_total; + stats->disk_sizes.commits += disk_total; + break; + case OBJ_TREE: + stats->type_counts.trees += oids->nr; + stats->inflated_sizes.trees += inflated_total; + stats->disk_sizes.trees += disk_total; + break; + case OBJ_BLOB: + stats->type_counts.blobs += oids->nr; + stats->inflated_sizes.blobs += inflated_total; + stats->disk_sizes.blobs += disk_total; + break; + default: + BUG("invalid object type"); + } + + object_count = get_total_object_values(&stats->type_counts); + display_progress(data->progress, object_count); + + return 0; +} + +static void structure_count_objects(struct object_stats *stats, + struct rev_info *revs, + struct repository *repo, int show_progress) +{ + struct path_walk_info info = PATH_WALK_INFO_INIT; + struct count_objects_data data = { + .odb = repo->objects, + .stats = stats, + }; + + info.revs = revs; + info.path_fn = count_objects; + info.path_fn_data = &data; + + if (show_progress) + data.progress = start_delayed_progress(repo, _("Counting objects"), 0); + + walk_objects_by_path(&info); + path_walk_info_clear(&info); + stop_progress(&data.progress); +} + +static int cmd_repo_structure(int argc, const char **argv, const char *prefix, + struct repository *repo) +{ + struct stats_table table = { + .rows = STRING_LIST_INIT_DUP, + }; + enum output_format format = FORMAT_TABLE; + struct repo_structure stats = { 0 }; + struct rev_info revs; + int show_progress = -1; + struct option options[] = { + OPT_CALLBACK_F(0, "format", &format, N_("format"), + N_("output format"), + PARSE_OPT_NONEG, parse_format_cb), + OPT_CALLBACK_F('z', NULL, &format, NULL, + N_("synonym for --format=nul"), + PARSE_OPT_NONEG | PARSE_OPT_NOARG, + parse_format_cb), + OPT_BOOL(0, "progress", &show_progress, N_("show progress")), + OPT_END() + }; + + argc = parse_options(argc, argv, prefix, options, repo_usage, 0); + if (argc) + usage(_("too many arguments")); + + repo_init_revisions(repo, &revs, prefix); + + if (show_progress < 0) + show_progress = isatty(2); + + structure_count_references(&stats.refs, &revs, repo, show_progress); + structure_count_objects(&stats.objects, &revs, repo, show_progress); + + switch (format) { + case FORMAT_TABLE: + stats_table_setup_structure(&table, &stats); + stats_table_print_structure(&table); + break; + case FORMAT_KEYVALUE: + structure_keyvalue_print(&stats, '=', '\n'); + break; + case FORMAT_NUL_TERMINATED: + structure_keyvalue_print(&stats, '\n', '\0'); + break; + default: + BUG("invalid output format"); + } + + stats_table_clear(&table); + release_revisions(&revs); + + return 0; +} + +int cmd_repo(int argc, const char **argv, const char *prefix, + struct repository *repo) +{ + parse_opt_subcommand_fn *fn = NULL; + struct option options[] = { + OPT_SUBCOMMAND("info", &fn, cmd_repo_info), + OPT_SUBCOMMAND("structure", &fn, cmd_repo_structure), + OPT_END() + }; + + argc = parse_options(argc, argv, prefix, options, repo_usage, 0); + + return fn(argc, argv, prefix, repo); +} diff --git a/ci/run-rust-checks.sh b/ci/run-rust-checks.sh new file mode 100755 index 00000000..b5ad9e8d --- /dev/null +++ b/ci/run-rust-checks.sh @@ -0,0 +1,22 @@ +#!/bin/sh + +. ${0%/*}/lib.sh + +set +x + +if ! group "Check Rust formatting" cargo fmt --all --check +then + RET=1 +fi + +if ! group "Check for common Rust mistakes" cargo clippy --all-targets --all-features -- -Dwarnings +then + RET=1 +fi + +if ! group "Check for minimum required Rust version" cargo msrv verify +then + RET=1 +fi + +exit $RET diff --git a/ci/run-test-slice-meson.sh b/ci/run-test-slice-meson.sh new file mode 100755 index 00000000..961c94fb --- /dev/null +++ b/ci/run-test-slice-meson.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +# We must load the build options so we know where to find +# things like TEST_OUTPUT_DIRECTORY. This has to come before +# loading lib.sh, though, because it may clobber some CI lib +# variables like our custom GIT_TEST_OPTS. +. "$1"/GIT-BUILD-OPTIONS +. ${0%/*}/lib.sh + +group "Run tests" \ + meson test -C "$1" --no-rebuild --print-errorlogs \ + --test-args="$GIT_TEST_OPTS" --slice "$((1+$2))/$3" || +handle_failed_tests diff --git a/debian/changelog b/debian/changelog index 06b6ef99..d29c2968 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,19 @@ +git (1:2.53.0-1) unstable; urgency=medium + + * New upstream release. + - Includes security updates and bug fixes + - CVE-2025-27613: gitk: file creation/truncation after cloning + untrusted repository (already fixed in 2.50.1) + - CVE-2025-27614: gitk: user can be tricked into running any + script after cloning untrusted repository (already fixed in 2.50.1) + - CVE-2025-46835: git-gui: file creation/overwriting after + cloning untrusted repository (already fixed in 2.50.1) + - CVE-2025-48384: script execution after cloning untrusted + repository (already fixed in 2.50.1) + - CVE-2025-48385: protocol injection when fetching (already fixed in 2.50.1) + + -- deepin-ci-robot Thu, 17 Apr 2026 05:55:00 +0800 + git (1:2.51.0-1) unstable; urgency=low * new upstream release (see RelNotes/2.51.0.adoc). @@ -25,4474 +41,3 @@ git (1:2.50.1-0.1) unstable; urgency=medium -- Adrian Bunk Tue, 29 Jul 2025 20:54:28 +0300 -git (1:2.50.0-1) unstable; urgency=medium - - * new upstream release (see RelNotes/2.50.0.adoc). - * in particular, includes the rest of the parse-options fix - from upstream, avoiding size mismatches that on big-endian - 64-bit platforms was causing commands like "git grep -A" to - write their argument to the 32 bits after the variable that is - used (thx Sebastian Andrzej Siewior; closes: #1106786). - * debian/patches/*: remove; applied upstream. - - -- Jonathan Nieder Tue, 17 Jun 2025 03:50:38 +0200 - -git (1:2.49.0-2) unstable; urgency=medium - - * debian/rules: remove overly strict check for license file - content matching base-files. This unbreaks the build on - builders with an updated copy of the GPLv2 text (thx - Santiago Vila; closes: #1106311). - * debian/patches/0001-parse-options-...diff: new; use correct - type for writing size_t flags, avoiding errors on big-endian - 64-bit platforms (thx Matthias Klose, Bastian Blank, and - Pranav P; closes: #1102106). - - -- Jonathan Nieder Thu, 29 May 2025 17:33:17 +0200 - -git (1:2.49.0-1) unstable; urgency=low - - * new upstream release (see RelNotes/2.48.0.adoc, RelNotes/2.49.0.adoc). - * update debian/copyright. - * debian/rules: adjust for asciidoc files using .adoc suffix. - * debian/control: Standards-Version: 4.7.0. - * debian/git-doc.doc-base.*: remove, as these metadata were not - frequently used and were out of date. - - -- Jonathan Nieder Sat, 15 Mar 2025 18:48:53 +0100 - -git (1:2.47.2-0.1) unstable; urgency=medium - - * Non-maintainer upload. - * new upstream release (see Documentation/RelNotes/2.47.2.txt; addresses - CVE-2024-50349 and CVE-2024-52006; Closes: #1093042). - - -- Salvatore Bonaccorso Sun, 19 Jan 2025 09:06:17 +0100 - -git (1:2.47.1-1) unstable; urgency=low - - * new upstream release (see RelNotes/2.46.0.txt, RelNotes/2.47.0.txt). - * new upstream point release (see RelNotes/2.47.1.txt). - * remove unsafe and under-maintained packages that install an - unsecured git-daemon services (thx Chris Hofstaedtler; closes: - #1078778, #1020284). - - -- Jonathan Nieder Thu, 02 Jan 2025 13:12:25 +0100 - -git (1:2.45.2-1.3) unstable; urgency=medium - - * Non-maintainer upload. - * Revert my two previous NMUs as I don't have the time to fully clean - up the situation. Reopens: #1020284 #1078778 - Closes: #1088019 - - -- Chris Hofstaedtler Sun, 22 Dec 2024 16:52:50 +0100 - -git (1:2.45.2-1.2) unstable; urgency=medium - - * Non-maintainer upload. - * git-daemon-run.postinst: Avoid hard failure when update-service - is not installed yet. - * git-daemon-run.postrm: stop passing -f to deluser (Closes: #1020284) - - -- Chris Hofstaedtler Fri, 08 Nov 2024 17:57:18 +0100 - -git (1:2.45.2-1.1) unstable; urgency=medium - - * Non-maintainer upload. - * Demote "runit" dependency to Recommends. - Demoting Depends: runit to Recommends: should have no effect on default - installs (apt will install Recommends by default), and people wanting to - use runit should have it installed already. (Closes: #1078778) - - -- Chris Hofstaedtler Sun, 13 Oct 2024 14:16:01 +0200 - -git (1:2.45.2-1) unstable; urgency=low - - * new upstream point release (see RelNotes/2.45.2.txt). - * debian/patches/*: remove; applied upstream. - - -- Jonathan Nieder Sun, 16 Jun 2024 15:40:09 +0000 - -git (1:2.45.1-1) unstable; urgency=medium - - * new upstream release (see RelNotes/2.44.0.txt, RelNotes/2.45.0.txt). - * new upstream point release (see RelNotes/2.45.1.txt; addresses - CVE-2024-32002, CVE-2024-32004, CVE-2024-32020, CVE-2024-32021 and - CVE-2024-32465; closes: #1071160). - * debian/patches/0001..0007: new from upstream: followups intended - for v2.45.2 to avoid regressions from the fixes included in - v2.45.1 (thx Johannes Schindelin). - - -- Jonathan Nieder Mon, 20 May 2024 03:36:58 +0000 - -git (1:2.43.0-1) unstable; urgency=low - - * new upstream release (see RelNotes/2.43.0.txt). - - -- Jonathan Nieder Sun, 26 Nov 2023 17:32:42 -0800 - -git (1:2.42.0-1) unstable; urgency=low - - * new upstream release (see RelNotes/2.41.0.txt, RelNotes/2.42.0.txt). - - -- Jonathan Nieder Wed, 27 Sep 2023 09:55:42 -0700 - -git (1:2.40.1-1) unstable; urgency=medium - - * new upstream point release (see RelNotes/2.40.1.txt; addresses - CVE-2023-25652, CVE-2023-25815 CVE-2023-29007). - - -- Jonathan Nieder Tue, 25 Apr 2023 10:16:34 -0700 - -git (1:2.40.0-1) unstable; urgency=low - - * new upstream release (see RelNotes/2.40.0.txt). - * debian/git-doc.doc-base.{git-index-format,git-pack-format,git-protocol}: - remove from documentation index, as the main git(1) reference - manual is the main entry point to find these. - - -- Jonathan Nieder Mon, 20 Mar 2023 16:50:00 -0700 - -git (1:2.39.2-1.1) unstable; urgency=medium - - * Non-maintainer upload (only changes to git-doc). - * Correct paths in git-doc doc-base control files (Closes: #1023255) - - -- Matthew Vernon Tue, 28 Feb 2023 09:25:32 +0000 - -git (1:2.39.2-1) unstable; urgency=medium - - * new upstream point release (see RelNotes/2.39.2.txt). Addresses - CVE-2023-22490 and CVE-2023-23946. - - -- Jonathan Nieder Wed, 15 Feb 2023 17:08:12 -0800 - -git (1:2.39.1-0.1) unstable; urgency=medium - - * Non-maintainer upload. - * New upstream stable release (Closes: #1029114) - Fixes CVE-2022-23521 and CVE-2022-41903. - - -- Aron Xu Thu, 26 Jan 2023 13:43:04 +0800 - -git (1:2.39.0-1) unstable; urgency=low - - * new upstream release (see RelNotes/2.39.0.txt). - - -- Jonathan Nieder Mon, 12 Dec 2022 12:53:44 -0800 - -git (1:2.38.1-1) unstable; urgency=medium - - * new upstream release (closes: #1022046; see RelNotes/2.38.0.txt, - RelNotes/2.38.1.txt). - * Addresses the security issue CVE-2022-39253: cloning an - attacker-controlled local repository could store arbitrary files - in the ".git" directory of the destination repository. - - Thanks to Cory Snider of Mirantis for reporting this - vulnerability and Taylor Blau for the mitigation. - - * Addresses CVE-2022-39260: a long command string passed to a `git - shell` configured to support custom commands could overflow and - run arbitrary code. - - Thanks to Kevin Backhouse of GitHub for reporting this - vulnerability and Kevin Backhouse, Jeff King, and Taylor Blau - for mitigating it. - - -- Jonathan Nieder Mon, 31 Oct 2022 18:32:00 -0700 - -git (1:2.37.2-1) unstable; urgency=low - - * new upstream release (closes: #1016723; see RelNotes/2.37.0.txt, - RelNotes/2.37.1.txt, RelNotes/2.37.2.txt). - - -- Jonathan Nieder Fri, 12 Aug 2022 19:27:24 -0700 - -git (1:2.36.1-1) unstable; urgency=low - - * new upstream point release (closes: #1010720; see - RelNotes/2.36.1.txt). - - -- Jonathan Nieder Mon, 09 May 2022 12:43:15 -0700 - -git (1:2.36.0-1) unstable; urgency=low - - * new upstream release (see RelNotes/2.36.0.txt). - - -- Jonathan Nieder Fri, 22 Apr 2022 16:43:03 -0700 - -git (1:2.35.2-1) unstable; urgency=medium - - * new upstream point release (see RelNotes/2.35.2.txt). - * Addresses the security issue CVE-2022-24765: Git users might - have found themselves unexpectedly in a Git worktree, e.g. when - another user created a repository in `/tmp/.git`, in a mounted - network drive or in a scratch space. Having a Git-aware prompt - that runs `git status` (or `git diff`) and navigating to a - directory which is supposedly not a Git worktree, or opening - such a directory in an IDE with Git support such as VS Code, - could then run commands specified by that other user. - - Thanks to 俞晨东 for discovering this vulnerability and - Johannes Schindelin for the mitigation. - - -- Jonathan Nieder Tue, 12 Apr 2022 21:25:57 -0700 - -git (1:2.35.1-1) unstable; urgency=low - - * new upstream release (see RelNotes/2.35.0.txt, RelNotes/2.35.1.txt). - - -- Jonathan Nieder Mon, 14 Feb 2022 08:24:39 -0800 - -git (1:2.34.1-1) unstable; urgency=low - - * new upstream point release (see RelNotes/2.34.1.txt). - - -- Jonathan Nieder Mon, 29 Nov 2021 11:04:56 -0800 - -git (1:2.34.0-1) unstable; urgency=low - - * new upstream release (see RelNotes/2.34.0.txt). - - -- Jonathan Nieder Sat, 20 Nov 2021 13:14:45 -0800 - -git (1:2.33.1-1) unstable; urgency=low - - * new upstream point release (see RelNotes/2.33.1.txt). - - -- Jonathan Nieder Mon, 25 Oct 2021 15:02:19 -0700 - -git (1:2.33.0-1) unstable; urgency=low - - * new upstream release (see RelNotes/2.33.0.txt). - - -- Jonathan Nieder Mon, 16 Aug 2021 17:54:01 -0700 - -git (1:2.32.0-1) unstable; urgency=low - - * new upstream release (see RelNotes/2.32.0.txt). - - -- Jonathan Nieder Sun, 06 Jun 2021 14:34:33 -0700 - -git (1:2.32.0~rc2-1) unstable; urgency=low - - * new upstream release candidate. - * remove git-el package (closes: #987264, #984931). Since version - 1:2.18.0~rc2-1, it only contained modules that error out with a - message pointing to other Emacs packages. Nowadays users can - use the README.emacs file from the git package for that instead. - - -- Jonathan Nieder Mon, 31 May 2021 15:02:28 -0700 - -git (1:2.32.0~rc0-1) unstable; urgency=low - - * new upstream release candidate (see RelNotes/2.32.0.txt). - - -- Jonathan Nieder Thu, 20 May 2021 13:20:15 -0700 - -git (1:2.31.1-1) unstable; urgency=low - - * new upstream point release (see RelNotes/2.31.1.txt). - * install dashed commands to /usr/lib again (thx Sven Joachim; - closes: #985416). - - -- Jonathan Nieder Mon, 19 Apr 2021 09:23:57 -0700 - -git (1:2.31.0-1) unstable; urgency=low - - * new upstream release (see RelNotes/2.31.0.txt). - * install dashed commands to /usr/libexec instead of /usr/lib (thx - Chris Lamb for suggesting it through lintian). - * remove compatibility code and NEWS.Debian entries that supported - upgrades from versions before 1.7.9.5 (the version in Ubuntu - 12.04, which reached the end of extended security maintenance in - April, 2019). - - -- Jonathan Nieder Mon, 15 Mar 2021 19:32:17 -0700 - -git (1:2.30.2-1) unstable; urgency=medium - - * new upstream point release (see RelNotes/2.30.2.txt). - - -- Jonathan Nieder Tue, 09 Mar 2021 17:45:38 -0800 - -git (1:2.30.1-1) unstable; urgency=low - - * new upstream point release (see RelNotes/2.30.1.txt). - - -- Jonathan Nieder Tue, 16 Feb 2021 21:55:22 -0800 - -git (1:2.30.0-1) unstable; urgency=low - - * new upstream release (see RelNotes/2.30.0.txt). - - -- Jonathan Nieder Mon, 28 Dec 2020 16:22:30 -0800 - -git (1:2.30.0~rc2-1) unstable; urgency=low - - * new upstream release candidate. - - -- Jonathan Nieder Wed, 23 Dec 2020 15:17:54 -0800 - -git (1:2.30.0~rc1-1) unstable; urgency=low - - * new upstream release candidate (see RelNotes/2.30.0.txt). - - -- Jonathan Nieder Mon, 21 Dec 2020 13:58:04 -0800 - -git (1:2.29.2-1) unstable; urgency=low - - * new upstream point release (see RelNotes/2.29.2.txt). - * debian/copyright: remove unused BSD-2-Clause text. The last part - of Git under that license was removed in v2.29.0. - - -- Jonathan Nieder Mon, 02 Nov 2020 09:33:37 -0800 - -git (1:2.29.1-1) unstable; urgency=low - - * new upstream release (see RelNotes/2.29.0.txt). - * update debian/copyright. - * debian/control: Build-Depends: debhelper-compat (= 10) - * debian/rules: run "dh --without autoreconf" to speed up build, - since we don't use the autotools-generated configure script. - * git-el: install elisp for the "emacs" flavor, too (thx Zack Weinberg; - closes: #972871). Breaks: emacsen-common (<< 3.0.0~) to avoid - triggering on older systems where "emacs" was a virtual package. - - -- Jonathan Nieder Mon, 26 Oct 2020 17:25:55 -0700 - -git (1:2.28.0-1) unstable; urgency=low - - * new upstream release (see RelNotes/2.28.0.txt). - - -- Jonathan Nieder Mon, 27 Jul 2020 11:02:01 -0700 - -git (1:2.28.0~rc2-1) unstable; urgency=low - - * new upstream release candidate. - - -- Jonathan Nieder Wed, 22 Jul 2020 17:36:57 -0700 - -git (1:2.28.0~rc1-1) unstable; urgency=low - - * new upstream release candidate. - - -- Jonathan Nieder Fri, 17 Jul 2020 18:40:53 -0700 - -git (1:2.28.0~rc0-1) unstable; urgency=low - - * new upstream release candidate (see RelNotes/2.28.0.txt). - - -- Jonathan Nieder Mon, 13 Jul 2020 15:03:55 -0700 - -git (1:2.27.0-1) unstable; urgency=low - - * new upstream release (see RelNotes/2.27.0.txt). - - -- Jonathan Nieder Mon, 01 Jun 2020 10:05:06 -0700 - -git (1:2.27.0~rc2-1) unstable; urgency=low - - * new upstream release candidate (closes: #757402). - - -- Jonathan Nieder Tue, 26 May 2020 14:27:25 -0700 - -git (1:2.27.0~rc0-1) unstable; urgency=low - - * new upstream release candidate (see RelNotes/2.27.0.txt). - - -- Jonathan Nieder Mon, 18 May 2020 16:57:41 -0700 - -git (1:2.26.2-1) unstable; urgency=high - - * new upstream point release (see RelNotes/2.26.2.txt). - * Addresses the security issue CVE-2020-11008. - - With a crafted URL that contains a newline or empty host, or - lacks a scheme, the credential helper machinery can be fooled - into providing credential information that is not appropriate - for the protocol in use and host being contacted. - - Unlike the vulnerability fixed in 2.26.1, the credentials are - not for a host of the attacker's choosing. Instead, they are - for an unspecified host, based on how the configured - credential helper handles an absent "host" parameter. - - The attack has been made impossible by refusing to work with - underspecified credential patterns. - - Thanks to Carlo Arenas for reporting that Git was still - vulnerable, Felix Wilhelm for providing the proof of concept - demonstrating this issue, and Jeff King for promptly providing - a corrected fix. - - Tested using the proof of concept at - https://crbug.com/project-zero/2021. - - -- Jonathan Nieder Mon, 20 Apr 2020 10:44:09 -0700 - -git (1:2.26.1-1) unstable; urgency=high - - * new upstream point release (see RelNotes/2.26.1.txt). - * Addresses the security issue CVE-2020-5260. - - With a crafted URL that contains a newline, the credential - helper machinery can be fooled to supply credential information - for the wrong host. The attack has been made impossible by - forbidding a newline character in any value passed via the - credential protocol. - - Thanks to Felix Wilhelm of Google Project Zero for finding - this vulnerability and Jeff King for fixing it. - - -- Jonathan Nieder Tue, 14 Apr 2020 10:29:38 -0700 - -git (1:2.26.0-2) unstable; urgency=low - - * fixes to the (newly default) rebase --merge backend: - * honor GIT_REFLOG_ACTION (thx Ian Jackson and Elijah Newren; - closes: #955152). - * avoid "nothing to do" error when fast-forwarding a branch with - rebase.abbreviateCommands=true (thx Jan Alexander Steffens and - Alban Gruin). - * debian/control: downgrade Recommends by git-all on git-daemon-run - to Suggests. The git-all package is a "batteries included" full - installation of Git. Automatically running a daemon is not useful - to most of its users. - - -- Jonathan Nieder Tue, 14 Apr 2020 10:09:37 -0700 - -git (1:2.26.0-1) unstable; urgency=low - - * new upstream release (see RelNotes/2.26.0.txt). - - -- Jonathan Nieder Mon, 23 Mar 2020 13:19:36 -0700 - -git (1:2.26.0~rc2-1) unstable; urgency=low - - * new upstream release candidate (see RelNotes/2.26.0.txt). - - -- Jonathan Nieder Mon, 16 Mar 2020 21:17:23 -0700 - -git (1:2.25.1-1) unstable; urgency=low - - * new upstream point release (see RelNotes/2.25.1.txt). - * update debian/copyright. - * debian/control: remove Gerrit Pape from the Maintainer field, - as requested. Thanks to Gerrit for putting together this - package in a way that has been pleasant to maintain. - * debian/rules: use "dpkg-architecture" instead of "uname -m" to - retrieve host arch. This makes the resulting "git version - --build-options" more predictable when building for i386 on an - amd64 machine (thx to Ceridwen for detecting this in reprotest). - - -- Jonathan Nieder Tue, 18 Feb 2020 17:26:36 -0800 - -git (1:2.25.0-1) unstable; urgency=low - - * new upstream release (see RelNotes/2.25.0.txt). - * build against Python 3 (thx Steve Langasek, closes: #948832). - - -- Jonathan Nieder Tue, 14 Jan 2020 02:58:47 +0000 - -git (1:2.25.0~rc2-1) unstable; urgency=low - - * new upstream release candidate. - - -- Jonathan Nieder Wed, 08 Jan 2020 16:08:27 -0800 - -git (1:2.25.0~rc1-1) unstable; urgency=low - - * new upstream release candidate. - - -- Jonathan Nieder Fri, 03 Jan 2020 15:12:18 -0800 - -git (1:2.25.0~rc0-1) unstable; urgency=low - - * new upstream release candidate (see RelNotes/2.25.0.txt). - - -- Jonathan Nieder Fri, 27 Dec 2019 15:08:51 -0800 - -git (1:2.24.1-1) unstable; urgency=low - - * update to use upstream tarball for 2.24.1. - - -- Jonathan Nieder Tue, 10 Dec 2019 13:21:59 -0800 - -git (1:2.24.0-2) unstable; urgency=high - - * new upstream point release (see RelNotes/2.24.1.txt). - * Addresses the security issues CVE-2019-1348, CVE-2019-1349, - CVE-2019-1350, CVE-2019-1351, CVE-2019-1352, CVE-2019-1353, - CVE-2019-1354, and CVE-2019-1387. - - Credit for finding these vulnerabilities goes to Microsoft - Security Response Center, in particular to Nicolas Joly. Fixes - were provided by Jeff King and Johannes Schindelin with help - from Garima Singh. - - * Addresses CVE-2019-19604, arbitrary code execution via the - "update" field in .gitmodules. - - Credit for finding this vulnerability goes to Joern - Schneeweisz from GitLab. - - -- Jonathan Nieder Mon, 09 Dec 2019 06:20:25 +0000 - -git (1:2.24.0-1) unstable; urgency=medium - - * new upstream release (see RelNotes/2.24.0.txt). - - -- Jonathan Nieder Sun, 03 Nov 2019 22:16:20 -0800 - -git (1:2.24.0~rc2-1) unstable; urgency=low - - * new upstream release candidate. - - -- Jonathan Nieder Wed, 30 Oct 2019 12:52:19 -0700 - -git (1:2.24.0~rc1-1) unstable; urgency=medium - - * new upstream release candidate. - * test-tool: read --total as an int, not uint64 (thx John Paul Adrian - Glaubitz; closes: #942674) - - -- Jonathan Nieder Thu, 24 Oct 2019 15:44:01 -0700 - -git (1:2.24.0~rc0-1) unstable; urgency=medium - - * new upstream release candidate (see RelNotes/2.24.0.txt). - - -- Jonathan Nieder Fri, 18 Oct 2019 15:15:37 -0700 - -git (1:2.23.0-1) unstable; urgency=medium - - * new upstream release (see RelNotes/2.23.0.txt). - - -- Jonathan Nieder Sun, 18 Aug 2019 16:58:15 -0700 - -git (1:2.23.0~rc1-1) unstable; urgency=low - - * new upstream release candidate. - * tests: sort output of hashmap iteration (closes: #933519) - - -- Jonathan Nieder Fri, 02 Aug 2019 17:21:22 -0700 - -git (1:2.23.0~rc0-1) unstable; urgency=low - - * new upstream release candidate (see RelNotes/2.23.0.txt). - - -- Jonathan Nieder Mon, 29 Jul 2019 17:07:53 -0700 - -git (1:2.22.0-1) unstable; urgency=low - - * new upstream release (see RelNotes/2.21.0.txt, RelNotes/2.22.0.txt). - - -- Jonathan Nieder Mon, 08 Jul 2019 10:50:51 -0700 - -git (1:2.20.1-2) unstable; urgency=low - - * package git-gui: actually Suggests: meld for mergetool support; - describe what meld is used for in package description (thx Jens - Reyer; closes: #707790). - * package gitweb: Depends: libhttp-date-perl | libtime-parsedate-perl - instead of ... | libtime-modules-perl (thx gregor herrmann; closes: - #879165). - * debian/control: use https in Vcs-Browser URL. - * debian/rules: build and test quietly if DEB_BUILD_OPTIONS=terse. - * debian/control: Standards-Version: 4.3.0.1. - - -- Jonathan Nieder Mon, 21 Jan 2019 22:32:28 -0800 - -git (1:2.20.1-1) unstable; urgency=medium - - * new upstream point release (see RelNotes/2.20.1.txt). - * package git-gui: Suggests: meld for mergetool support (thx Jens - Reyer; closes: #707790). - - -- Jonathan Nieder Sun, 16 Dec 2018 16:53:30 -0800 - -git (1:2.20.0-1) unstable; urgency=medium - - * new upstream release (see RelNotes/2.20.0.txt). - * package git: Recommends: ca-certificates for https support (thx HJ; - closes: #915644). - - -- Jonathan Nieder Mon, 10 Dec 2018 11:07:26 -0800 - -git (1:2.20.0~rc2-1) unstable; urgency=low - - * new upstream release candidate. - * rebase: specify 'rebase -i' in reflog for interactive rebase - (closes: #914695). - - -- Jonathan Nieder Sun, 02 Dec 2018 12:11:19 -0800 - -git (1:2.20.0~rc1-1) unstable; urgency=low - - * new upstream release candidate (see RelNotes/2.20.0.txt). - * debian/rules: target clean: don't remove t/t4256/1/mailinfo.c.orig. - - -- Jonathan Nieder Sun, 25 Nov 2018 11:47:53 -0800 - -git (1:2.19.2-1) unstable; urgency=high - - * new upstream point release (see RelNotes/2.19.2.txt). - * run-command: do not fall back to cwd when command is not in $PATH. - - -- Jonathan Nieder Thu, 22 Nov 2018 14:48:49 -0800 - -git (1:2.19.1-1) unstable; urgency=high - - * new upstream point release (see RelNotes/2.19.1.txt, - CVE-2018-17456). - - -- Jonathan Nieder Fri, 05 Oct 2018 10:10:45 -0700 - -git (1:2.19.0-1) unstable; urgency=low - - * new upstream release (see RelNotes/2.19.0.txt). - * debian/patches/0001-*, 0002-*: remove; applied upstream. - - -- Jonathan Nieder Mon, 10 Sep 2018 13:33:45 -0700 - -git (1:2.19.0~rc2-2) unstable; urgency=low - - * debian/patches: - * 0001-http-backend-allow-empty-CONTENT_LENGTH: new from - upstream: http-backend: treat empty CONTENT_LENGTH as absent - (closes: #907587). - * 0002-Revert-Merge-branch-sb-submodule-core-worktree.diff: new - from upstream: stop setting and unsetting core.worktree in - submodules, since the code to do so does not handle submodules - with an embedded .git directory (thx Allan Sandfeld Jensen). - - -- Jonathan Nieder Sun, 09 Sep 2018 19:08:55 -0700 - -git (1:2.19.0~rc2-1) unstable; urgency=low - - * new upstream release candidate. - - -- Jonathan Nieder Tue, 04 Sep 2018 15:47:54 -0700 - -git (1:2.19.0~rc1-1) unstable; urgency=low - - * new upstream release candidate (see RelNotes/2.19.0.txt). - * debian/control: Standards-Version: 4.1.5.0. - - -- Jonathan Nieder Tue, 28 Aug 2018 13:48:50 -0700 - -git (1:2.18.0-1) unstable; urgency=low - - * new upstream release (see RelNotes/2.18.0.txt). - - -- Jonathan Nieder Thu, 21 Jun 2018 15:25:50 -0700 - -git (1:2.18.0~rc2-2) unstable; urgency=low - - * debian/control: Breaks: dgit (<< 5.1~) that lacks support - for working-tree-encoding attribute (thx Ian Jackson; - closes: #901897). - - -- Jonathan Nieder Wed, 20 Jun 2018 10:22:51 -0700 - -git (1:2.18.0~rc2-1) unstable; urgency=low - - * new upstream release candidate. - * debian/README.emacs: describe removed emacs support. - * debian/control: package git-el: describe transitional - modules; Recommends: elpa-magit. - - -- Jonathan Nieder Mon, 18 Jun 2018 09:19:59 -0700 - -git (1:2.17.1-1) unstable; urgency=high - - * new upstream point release to fix CVE-2018-11235, arbitary code - execution via submodule names in .gitmodules (see RelNotes/2.17.1.txt). - - -- Jonathan Nieder Mon, 28 May 2018 17:37:54 -0700 - -git (1:2.17.0-1) unstable; urgency=low - - * new upstream release (see RelNotes/2.17.0.txt). - * debian/rules: add NO_USE_CPAN_FALLBACKS=1 to OPTS to avoid - installing bundled copies of perl modules. - * debian/control: Build-Depends: libmailtools-perl, liberror-perl; - git-email: Depends: libmailtools-perl for Mail::Address. - - -- Jonathan Nieder Mon, 02 Apr 2018 12:58:14 -0700 - -git (1:2.16.3-1) unstable; urgency=low - - * new upstream point release (see RelNotes/2.16.3.txt). - - -- Jonathan Nieder Fri, 23 Mar 2018 09:56:37 -0700 - -git (1:2.16.2-1) unstable; urgency=low - - * new upstream point release (see RelNotes/2.16.2.txt). - * debian/control: correct spelling of openssh-client in Breaks - relation. - - -- Jonathan Nieder Fri, 23 Feb 2018 13:53:02 -0800 - -git (1:2.16.1-1) unstable; urgency=low - - * new upstream release (see RelNotes/2.16.txt, RelNotes/2.16.1.txt). - * debian/control: Breaks: openssh-client (<< 1:6.8) since the latter - lacks support for the "-G" option (thx Bryan Turner; see - https://crbug.com/git/7). - * debian/patches/git-gui-Sort-entries-in-optimized-tclIndex.diff: - remove; applied upstream. - * debian/rules: do not install contrib/**/.gitattributes to - /usr/share/doc (thx Paul Wise and Bastien Roucaries for suggesting - it through lintian). - - -- Jonathan Nieder Mon, 05 Feb 2018 12:27:37 -0800 - -git (1:2.15.1-3) unstable; urgency=low - - * debian/rules: remove remnants of git-core package that prevented - building twice in a row (thx Andreas Beckmann; closes: #884890). - - -- Jonathan Nieder Fri, 22 Dec 2017 17:13:42 -0800 - -git (1:2.15.1-2) unstable; urgency=low - - * gitweb: Recommends: 'apache2 (>= 2.4.6-4~) | lynx | httpd' instead - of ... | lynx-cur | ... (thx Łukasz Zemczak; see #490265). - * debian/control: Standards-Version: 4.1.2.0. - - -- Jonathan Nieder Mon, 18 Dec 2017 09:45:31 -0800 - -git (1:2.15.1-1) unstable; urgency=low - - * new upstream point release (see RelNotes/2.15.1.txt). - * debian/control: Build-Depends-Indep: asciidoc (>= 8.6.10). - * debian/control: Standards-Version: 4.1.1.1. - * debian/patches: - * Normalize-generated-asciidoc-timestamps-...diff: remove; no - longer needed (thx Anders Kaseorg; see #782294). - * git-gui-Sort-entries-in-optimized-tclIndex.diff: update to - upstream version. - - -- Jonathan Nieder Wed, 29 Nov 2017 13:49:38 -0800 - -git (1:2.15.0-1) unstable; urgency=low - - * new upstream release (see RelNotes/2.15.0.txt). - - -- Jonathan Nieder Mon, 30 Oct 2017 10:56:56 -0700 - -git (1:2.15.0~rc2-1) unstable; urgency=low - - * new upstream release candidate. - - -- Jonathan Nieder Mon, 23 Oct 2017 10:15:45 -0700 - -git (1:2.15.0~rc1-1) unstable; urgency=low - - * new upstream release candidate. - * remove transitional git-core package (thx Holger Levsen; - closes: #878189). - - -- Jonathan Nieder Mon, 16 Oct 2017 09:29:08 -0700 - -git (1:2.15.0~rc0-1) unstable; urgency=low - - * new upstream release candidate (see RelNotes/2.15.0.txt). - - -- Jonathan Nieder Mon, 09 Oct 2017 10:13:35 -0700 - -git (1:2.14.2-1) unstable; urgency=high - - * new upstream point release (see RelNotes/2.14.1.txt). Among other - changes, this fixes a remote shell command execution vulnerability - via CVS protocol: - - git-shell: drop cvsserver support by default - - git-cvsserver: harden backtick captures against user input - - Thanks to joernchen of Phenoelit for discovering, reporting, and - fixing this vulnerability, and to Junio C Hamano and Jeff King for - the fixes to related issues. - - -- Jonathan Nieder Mon, 25 Sep 2017 18:23:18 -0700 - -git (1:2.14.1-3) unstable; urgency=low - - * git.README.Debian: remove obsolete instructions about setting up a - server to handle rsync:// protocol. - - -- Jonathan Nieder Mon, 28 Aug 2017 10:08:04 -0700 - -git (1:2.14.1-2) unstable; urgency=low - - * debian/control: git-daemon-sysvinit: Priority: optional. - * debian/control: clarify how to decide between git-daemon-run and - git-daemon-sysvinit in package descriptions. - * debian/control: Standards-Version: 4.0.1.0. - - -- Jonathan Nieder Mon, 14 Aug 2017 12:14:32 -0700 - -git (1:2.14.1-1) unstable; urgency=high - - * new upstream point release to fix CVE-2017-1000117, arbitrary - code execution issues via URLs (see RelNotes/2.14.1.txt). - - -- Jonathan Nieder Thu, 10 Aug 2017 09:16:20 -0700 - -git (1:2.14.0-1) unstable; urgency=low - - * new upstream release (see RelNotes/2.14.0.txt). - * debian/patches/0001-pre-rebase-hook-capture-documentation-...diff: - remove; applied upstream. - * build against PCRE v2 if available at build time (thx to Ævar - Arnfjörð Bjarmason for the suggestion). Build-Depends: - libpcre2-dev | libpcre3-dev. - - -- Jonathan Nieder Mon, 07 Aug 2017 11:31:25 -0700 - -git (1:2.13.3-1) unstable; urgency=low - - * new upstream point release (see RelNotes/2.13.3.txt). - - -- Jonathan Nieder Mon, 17 Jul 2017 12:16:44 -0700 - -git (1:2.13.2-3) unstable; urgency=low - - * remove git-arch package. It depended on GNU Arch, which has not - been maintained upstream for more than 10 years (thx Adrian - Bunk; closes: #866059). - * debian/rules: do not allow flaky git-svn tests t9128.4 or t9167.3 - to cause the build to fail, either (closes: #865789). - - -- Jonathan Nieder Fri, 30 Jun 2017 16:11:06 -0700 - -git (1:2.13.2-2) unstable; urgency=low - - * git-email: use perl in dependency instead of perl-modules (thx - Damyan Ivanov for suggesting it through lintian). - * debian/rules: do not allow flaky git-svn test t9128.3 to cause - the build to fail (closes: #865789). - - -- Jonathan Nieder Mon, 26 Jun 2017 15:17:48 -0700 - -git (1:2.13.2-1) unstable; urgency=low - - * new upstream point release (see RelNotes/2.13.2.txt). - * git-email: Depends: perl-modules (>> 5.21.5) | libnet-smtp-ssl-perl - for starttls support instead of unconditionally requiring - Net::SMTP::SSL (thx Dennis Kaarsemaker). - * debian/rules: skip HTML documentation generation when - DEB_BUILD_OPTIONS=nodoc. - * debian/copyright: use https form of Format URL. - * debian/control: Standards-Version: 4.0.0.0. - - -- Jonathan Nieder Mon, 26 Jun 2017 11:47:14 -0700 - -git (1:2.13.1-1) unstable; urgency=low - - * new upstream release (see RelNotes/2.12.0.txt, RelNotes/2.13.0.txt). - * debian/patches/xdiff-Do-not-enable-XDF_FAST_HASH-by-default.diff, - shell-disallow-repo-names-beginning-with-dash.patch: remove; applied - upstream. - * update debian/copyright - * debian/rules: run tests once and always produce verbose output. - - -- Jonathan Nieder Wed, 21 Jun 2017 15:42:17 -0700 - -git (1:2.11.0-4) unstable; urgency=low - - [ Alan Jenkins ] - * git: remove Recommends: rsync (closes #862435). - * git-arch: Depends: rsync. - - -- Jonathan Nieder Mon, 15 May 2017 12:13:38 -0700 - -git (1:2.11.0-3) unstable; urgency=high - - * Do not allow git helpers run via git-shell to launch a pager - (CVE-2017-8386). - - -- Jonathan Nieder Tue, 09 May 2017 16:23:17 -0700 - -git (1:2.11.0-2) unstable; urgency=medium - - * gitweb: Depends: libcgi-pm-perl; Build-Depends: libcgi-pm-perl - (thx Mikko Rasa; closes: #847961). - - -- Jonathan Nieder Tue, 27 Dec 2016 15:17:12 -0800 - -git (1:2.11.0-1) unstable; urgency=medium - - * New upstream release (see RelNotes/2.11.0.txt). - * debian/patches/git-sh-setup-Restore-sourcability-from-outside-script.diff: - remove; applied upstream. - * Replace - debian/patches/Documentation-omit-asciidoc-footer-on-generated-input.diff - with the more upstreamable - debian/patches/Normalize-generated-asciidoc-timestamps-with-SOURCE_D.diff. - * debian/patches/git-gui-Sort-entries-in-optimized-tclIndex.diff, - debian/patches/xdiff-Do-not-enable-XDL_FAST_HASH-by-default.diff: - Further improvements to build reproducibility. - - -- Anders Kaseorg Wed, 30 Nov 2016 23:34:59 -0500 - -git (1:2.10.2-3) unstable; urgency=medium - - * debian/rules: Split override_dh_installdocs into -arch and -indep - parts. (Closes: #843393) - - -- Anders Kaseorg Wed, 16 Nov 2016 16:12:02 -0500 - -git (1:2.10.2-2) unstable; urgency=medium - - * Add missing upstream changelog entries from v2.10.2. - * gitweb: Add version to Breaks: apache2.2-common (<< 2.3~). - * git-mediawiki: Shorten description. - * Link extra license files to common-licenses. - * Invoke dpkg-maintscript-helper dir_to_symlink correctly. - (Closes: #843011) - * debian/patches/Documentation-omit-asciidoc-footer-on-generated-input.diff: - Omit the “last updated” footer when processing asciidoc inputs that - are generated at build time. (Closes: #813912) - - -- Anders Kaseorg Sat, 05 Nov 2016 07:20:14 -0400 - -git (1:2.10.2-1) unstable; urgency=medium - - * New upstream point release (see RelNotes/2.10.2.txt). - - imap-send: Tell cURL to use imap:// or imaps:// (Closes: #648329) - * Run asciidoc in TZ=UTC to improve the reproducibility of documentation - footer timestamps. - * debian/patches/git-sh-setup-Restore-sourcability-from-outside-script.diff: - Restore sourcability of git-sh-setup from outside scripts. - (Closes: #842477) - - -- Anders Kaseorg Sat, 29 Oct 2016 22:44:37 -0400 - -git (1:2.10.1-1) unstable; urgency=medium - - * New upstream release (see RelNotes/2.10.0.txt, RelNotes/2.10.1.txt). - (Closes: #840800) - * debian/rules: Fix clean target to remove GIT-VERSION-FILE and - contrib/subtree build products. (Closes: #834870) - * Fix a missing reference in /usr/share/doc-base/everyday-git. - (Closes: #836516) - * Migrate patches to 3.0 (quilt) format. (Closes: #834566) - * Migrate packaging to Debhelper. (Closes: #834886) - * Replace perl-modules dependency with perl. - * git-daemon-sysvinit: Depend lsb-base (>= 3.0-6) for - /lib/lsb/init-functions. - - -- Anders Kaseorg Fri, 14 Oct 2016 21:47:15 -0400 - -git (1:2.9.3-1) unstable; urgency=medium - - * New upstream release (see RelNotes/2.8.2.txt, RelNotes/2.8.3.txt, - RelNotes/2.9.0.txt, RelNotes/2.9.1.txt, RelNotes/2.9.2.txt, - RelNotes/2.9.3.txt). - - -- Anders Kaseorg Tue, 16 Aug 2016 16:32:47 -0400 - -git (1:2.8.1-1) unstable; urgency=low - - * new upstream point release. - * debian/diff/0003-0007-srv-be-more-tolerant-of-broken-DNS-replies.diff: - remove. - - -- Jonathan Nieder Mon, 18 Apr 2016 17:23:33 -0700 - -git (1:2.8.0~rc3-1) unstable; urgency=medium - - * new upstream release candidate (see RelNotes/2.8.0.txt). - * harden against on-stack and on-heap buffer overflows (CVE-2016-2324, - CVE-2016-2315; closes: #818318). - * debian/git.docs: update for README -> README.md renaming. - - -- Jonathan Nieder Wed, 16 Mar 2016 18:28:12 -0700 - -git (1:2.7.0-1) unstable; urgency=low - - * new upstream release. - - -- Jonathan Nieder Tue, 19 Jan 2016 11:04:08 -0800 - -git (1:2.7.0~rc3-1) unstable; urgency=low - - * new upstream release candidate (see RelNotes/2.7.0.txt). - * debian/control: Standards-Version: 3.9.6.0. - * debian/control: use HTTPS for Homepage URL. - - -- Jonathan Nieder Mon, 04 Jan 2016 12:25:50 -0800 - -git (1:2.6.4-1) unstable; urgency=medium - - * new upstream point release (see RelNotes/2.6.4.txt). - - -- Jonathan Nieder Thu, 10 Dec 2015 16:07:19 -0800 - -git (1:2.6.3-1) unstable; urgency=medium - - * new upstream point release (see RelNotes/2.6.3.txt). - - -- Jonathan Nieder Tue, 08 Dec 2015 12:02:26 -0800 - -git (1:2.6.2-1) unstable; urgency=low - - * new upstream point release (see RelNotes/2.6.2.txt). - - -- Jonathan Nieder Fri, 23 Oct 2015 11:52:44 -0700 - -git (1:2.6.1-1) unstable; urgency=high - - * new upstream point release (see RelNotes/2.6.1.txt). - - -- Jonathan Nieder Mon, 05 Oct 2015 11:16:05 -0700 - -git (1:2.6.0-1) unstable; urgency=low - - * new upstream release (see RelNotes/2.6.0.txt). - - -- Jonathan Nieder Tue, 29 Sep 2015 12:55:19 -0700 - -git (1:2.5.3-1) unstable; urgency=medium - - * new upstream point release (see RelNotes/2.5.2.txt, 2.5.3.txt). - - -- Jonathan Nieder Fri, 18 Sep 2015 12:36:49 -0700 - -git (1:2.5.1-1) unstable; urgency=medium - - * new upstream point release (see RelNotes/2.5.1.txt). - - -- Jonathan Nieder Fri, 28 Aug 2015 14:27:25 -0700 - -git (1:2.5.0-1) unstable; urgency=low - - * new upstream release (see RelNotes/2.5.0.txt). - - -- Jonathan Nieder Tue, 28 Jul 2015 10:47:13 -0700 - -git (1:2.4.6-1) unstable; urgency=medium - - * new upstream release (see RelNotes/2.[234].*.txt). - * debian/rules: use install-html target for git-subtree docs - (see #768795). - * gitweb: Pre-Depends: dpkg 1.16.1 for -noawait support. - * gitweb.apache2.conf: make configuration conditional on MIME - support (thx Uwe Storbeck; closes: #775236). - - -- Jonathan Nieder Tue, 21 Jul 2015 12:08:09 -0700 - -git (1:2.1.4-2.1) unstable; urgency=medium - - * Non-maintainer upload. - * Use interest-noawait triggers for gitweb to avoid a - trigger cycle. (Closes: #774607) - - -- Niels Thykier Mon, 02 Feb 2015 19:42:37 +0100 - -git (1:2.1.4-2) unstable; urgency=medium - - * update gitweb configuration for Apache 2.4: - * apache2.conf: - * make configuration conditional on CGI and alias support. - * put explicit '+' before FollowSymLinks option. - * README.Debian: update with new configuration file path. - Mention CGI support requirement. - * prerm: fix typo in last line (it should be "fi", not "then"). - * update version number in conffile handling code to handle - upgrades within testing. - - -- Jonathan Nieder Fri, 19 Dec 2014 17:52:50 -0800 - -git (1:2.1.4-1) unstable; urgency=medium - - * new upstream point release (CVE-2014-9390). - * checkout: tighten exit code handling on errors. - * avoid writing filenames to the work tree that some filesystems - do not distinguish from ".git". - * reject ".gIt" and other path components that case-fold - to ".git" in "git checkout", "git add", and "git fsck". - * new '[core] protectHFS' setting to reject path components - such as ".Git\u200f" that HFS+ folds to ".git" in - "git checkout" and "git add". Always reject such paths - in "git fsck". (U+200F is the Unicode right-to-left - mark.) - * new '[core] protectNTFS' setting to reject path components - such as ".Git " that NTFS folds to ".git" in "git checkout" - and "git add". Always reject such paths in "git fsck". - * gitweb: use apache 2.4-compatible configuration (thx Jean-Michel - Nirgal Vourgère for advice; closes: #669292). - * rules, conffiles: Apache configuration goes in - /etc/apache2/conf-available, not conf.d. - * preinst, postinst, postrm: use dpkg-maintscript-helper to - rename the conffile and preserve local changes. - * postinst, prerm, postrm: use apache2-maintscript-helper if - present to load and unload gitweb configuration. - * implicit: check for debian/$pkg.triggers. - * triggers: re-run postinst when apache2-maintscript-helper is - installed. - * control: - * Pre-Depends: dpkg 1.15.8 for dpkg-maintscript-helper. - * Breaks: apache2.2-common because the Apache configuration - requires version 2.4. - * debian/diff/0009-git-svn-use-SVN-Ra-get_dir2-when-possible.diff: - new from upstream: git svn: use get_dir2 instead of get_dir when - possible (thx Eric Wong; works around: #767530). - * debian/diff/0010-gitweb-hack-around-CGI-s-list-context-...diff: - new from upstream: gitweb: be explicit about use of param() in list - context, avoiding log noiose with libcgi-pm-perl >= 4.08 and a test - failure in t9500-gitweb-standalone-no-errors.sh (thx Reiner - Herrmann; closes: #770655). - * correct spelling of Roland Mas's name in the 1:2.1.3-1 changelog - entry. - - -- Jonathan Nieder Fri, 19 Dec 2014 15:55:34 -0800 - -git (1:2.1.3-1) unstable; urgency=low - - * new upstream point release. - * config --add: avoid segfault when key already has an empty value. - * remote-http: avoid failure due to command line length limits when - pushing many refs. - * fast-import: avoid segfault when trying to clear root tree. - * index-pack: reliably detect and error out when encountering - duplicate delta base. - * gc: do not prune objects only reachable from HEAD . - * fsck: be more consistent about exiting nonzero for corruption. - * am: tighten check for mbox 'From ' line. - * daemon: fix error message when bind() fails. - * mergetool: fix --output handling in meld >= 3.12 (see GNOME - bug 737869). - * gitweb: use start_form instead of startform for compatibility - with CGI.pm 4.04 and newer (thx Roland Mas; closes: #765525). - * pack-objects: do not write invalid bitmaps when hitting pack - size limit. - - -- Jonathan Nieder Tue, 04 Nov 2014 13:20:39 -0800 - -git (1:2.1.1-1) unstable; urgency=low - - * new upstream point release. - - -- Jonathan Nieder Mon, 22 Sep 2014 17:56:49 -0700 - -git (1:2.1.0-1) unstable; urgency=low - - * new upstream release (see RelNotes/2.1.0.txt). - - -- Jonathan Nieder Fri, 15 Aug 2014 16:09:26 -0700 - -git (1:2.1.0~rc1-1) unstable; urgency=low - - * new upstream release candidate. - - -- Jonathan Nieder Tue, 05 Aug 2014 13:59:00 -0700 - -git (1:2.0.1-1) unstable; urgency=low - - * new upstream point release. - - -- Jonathan Nieder Wed, 25 Jun 2014 15:09:25 -0700 - -git (1:2.0.0-2) unstable; urgency=low - - * debian/rules: drop obsolete THREADED_DELTA_SEARCH setting. - * debian/rules: add SANE_TOOL_PATH= INSTALL=install TAR=tar to - OPTS to fix the Dyson build (thx Игорь Пашев; closes: - #734097). - * debian/rules: remove NO_PYTHON=1 now that the git_remote_helpers - library has been removed. - * debian/rules: remove git-p4 and its documentation from the git, - git-man, and git-doc packages. It depends on Perforce, which is - not part of Debian. - - -- Jonathan Nieder Tue, 17 Jun 2014 16:17:46 -0700 - -git (1:2.0.0-1) unstable; urgency=low - - * new upstream release (see RelNotes/2.0.0.txt). - - -- Jonathan Nieder Wed, 28 May 2014 16:06:41 -0700 - -git (1:2.0.0~rc4-1) unstable; urgency=low - - * new upstream release candidate. - * remove source-highlight build dependency since the markup - requiring it was removed upstream (thx Anders Kaserog; - LP: #1316810). - * remove git-bzr package to make room for a package built from - https://github.com/felipec/git-remote-bzr. - * debian/control: remove references to git-bzr package. - * debian/control: remove Build-Depends: bzr, python-bzrlib. - * debian/rules: remove rules to build, install, and clean - git-remote-bzr. - * debian/git-doc.docs: do not install git-remote-bzr.html. - * debian/git-remote-bzr.txt, debian/git-bzr.postinst, - debian/git-bzr.prerm, debian/git-bzr.README.Debian: remove. - - -- Jonathan Nieder Wed, 21 May 2014 11:34:56 -0700 - -git (1:2.0.0~rc2-1) unstable; urgency=low - - * new upstream release candidate. - - -- Jonathan Nieder Mon, 05 May 2014 17:25:50 -0700 - -git (1:2.0.0~rc0-2) unstable; urgency=low - - [ Anders Kaseorg ] - * add source-highlight build dependency (closes: #745591). - - -- Jonathan Nieder Wed, 23 Apr 2014 11:09:25 -0700 - -git (1:2.0.0~rc0-1) unstable; urgency=low - - * new upstream release candidate. - * debian/diff/0009-contrib-subtree-unset-prefix-before-....diff: - remove; applied upstream. - * update debian/copyright. - - -- Jonathan Nieder Fri, 18 Apr 2014 17:01:04 -0700 - -git (1:1.9.2-1) unstable; urgency=low - - * new upstream point release. - * wt-status: subject full label string to l10n (thx Raphaël - Hertzog; closes: #725777). - - -- Jonathan Nieder Wed, 09 Apr 2014 15:15:18 -0700 - -git (1:1.9.1-1) unstable; urgency=low - - * new upstream point release. - - [ Jonathan Nieder ] - * git-email: Recommends: libio-socket-ssl-perl (>= 1.951) since - earlier versions do not use OpenSSL's defaults when ca_path - and ca_file are unset. - - [ Gilles Filippini ] - * install git-subtree from contrib (closes: #704652). - * debian/diff/0009-contrib-subtree-unset-prefix-before-proceeding.diff: - new; unset the 'prefix' environment variable before proceeding. - - -- Jonathan Nieder Tue, 18 Mar 2014 15:58:46 -0700 - -git (1:1.9.0-1) unstable; urgency=low - - * new upstream release. - - -- Jonathan Nieder Tue, 18 Feb 2014 08:31:49 -0800 - -git (1:1.9.0~rc3-1) unstable; urgency=low - - * new upstream release candidate. - - -- Jonathan Nieder Fri, 07 Feb 2014 15:53:52 -0800 - -git (1:1.9~rc1-1) unstable; urgency=low - - * new upstream release candidate. - - -- Jonathan Nieder Mon, 27 Jan 2014 14:07:56 -0800 - -git (1:1.9~rc0-1) unstable; urgency=low - - * new upstream release candidate. - * debian/diff: - * 0001-remove-interpreter-line-from-shell-libraries.diff: - remove; applied upstream. - * 0002...0009: rename to 0001-*, ..., 0008-*. - * 0010-git-remote-mediawiki-do-not-remove-installed-...diff: - remove; applied upstream. - * debian/rules install: no more need to include DESTDIR in - mw-to-git INSTLIBDIR. - - -- Jonathan Nieder Mon, 27 Jan 2014 13:05:17 -0800 - -git (1:1.8.5.3-1) unstable; urgency=low - - * new upstream point release. - - -- Jonathan Nieder Thu, 16 Jan 2014 16:18:25 -0800 - -git (1:1.8.5.2-2) unstable; urgency=low - - * /etc/bash_completion.d/git-prompt: check for git-sh-prompt - and do not source it if git is removed but not purged (thx - Craig Small; closes: #726669). - * debian/control: package git Breaks: git-buildpackage versions - that rely on output from 'git status' without the --porcelain - flag (closes: #734223). - - -- Jonathan Nieder Thu, 09 Jan 2014 14:46:23 -0800 - -git (1:1.8.5.2-1) unstable; urgency=low - - * new upstream point release. - - -- Jonathan Nieder Tue, 17 Dec 2013 16:31:01 -0800 - -git (1:1.8.5.1-1) unstable; urgency=medium - - * new upstream point release. - * submodule: do not copy unknown update mode from .gitmodules. - - -- Jonathan Nieder Tue, 03 Dec 2013 14:12:55 -0800 - -git (1:1.8.5-1) unstable; urgency=low - - * new upstream release. - * merge branch debian-experimental. - * git-daemon-sysvinit: advertise GIT_DAEMON_BASE_PATH in - /etc/default/git-daemon (thx Alexander Dahl and Antonio - Ospite; closes: #704985). - - -- Jonathan Nieder Sat, 30 Nov 2013 11:28:02 -0800 - -git (1:1.8.5~rc3-1) experimental; urgency=low - - * new upstream release candidate. - - [ Anders Kaseorg ] - * debian/rules: pass $(OPTS) to contrib/mw-to-git/Makefile - (closes: #729763). - - -- Jonathan Nieder Thu, 21 Nov 2013 16:35:29 -0800 - -git (1:1.8.5~rc2-1) experimental; urgency=low - - * merge branch debian-sid. - * new upstream release candidate. - - [ Thorsten Glaser ] - * package mw-to-git (closes: #718395). - * debian/control: new package git-mediawiki; Depends: - libmediawiki-api-perl (>= 0.39), liblwp-protocol-https-perl, - libdatetime-format-iso8601-perl; package git now Suggests - and git-all Depends: git-mediawiki. - * debian/rules: build and install Git::Mediawiki perl module, - mediawiki remote helper, and 'git mw' command in - git-mediawiki package. - * debian/diff/0010-git-remote-mediawiki-do-not-remove-...diff: - new from upstream: mw-to-git: do not remove installed files - in "clean" target. - * debian/git-mediawiki.docs: install git-remote-mediawiki.txt. - - [ Anders Kaseorg ] - * debian/diff/0003-transport-expose-git_tcp_connect-...diff: - include tcp.h before using tcp functions (closes: #728508). - - [ Jonathan Nieder ] - * debian/diff/0012-cvsserver-Determinize-output-to-...diff: - remove; applied upstream. - - -- Jonathan Nieder Wed, 13 Nov 2013 16:12:29 -0800 - - -git (1:1.8.4.4-1) unstable; urgency=low - - * new upstream point release. - - -- Jonathan Nieder Thu, 21 Nov 2013 17:51:36 -0800 - -git (1:1.8.4.3-1) unstable; urgency=low - - * new upstream point release. - - -- Jonathan Nieder Mon, 11 Nov 2013 15:51:10 -0800 - -git (1:1.8.5~rc0-1) experimental; urgency=low - - * new upstream release candidate. - * debian/diff: - * 0001-hooks-post-receive-email-set-encoding-to-utf-8.diff, - 0002-post-receive-email-defend-against-non-utf8-...diff: - remove; applied upstream. - * 0003...0012: rename to 0001-*, ..., 0010-*. - - -- Jonathan Nieder Wed, 30 Oct 2013 16:01:15 -0700 - -git (1:1.8.4.2-1) unstable; urgency=low - - * new upstream point release. - * debian/diff/0012-cvsserver-Determinize-output-to-...diff: - new from upstream: sort cvsserver output to combat Perl 5.18 - hash randomization (thx Anders Kaseorg; closes: #727226). - - -- Jonathan Nieder Wed, 30 Oct 2013 16:00:07 -0700 - -git (1:1.8.4.1-1) unstable; urgency=low - - * merge branch debian-experimental. - * new upstream point release. - * debian/control: Build-Depends tcl instead of tcl8.5 - (closes: #725961). - - -- Jonathan Nieder Mon, 21 Oct 2013 11:46:45 -0700 - -git (1:1.8.4-1) experimental; urgency=low - - * new upstream release. - - -- Jonathan Nieder Sat, 24 Aug 2013 14:50:38 -0700 - -git (1:1.8.4~rc4-1) experimental; urgency=low - - * new upstream release candidate. - * debian/diff/0012-*, 0013-*: remove; applied upstream. - * debian/rules: define .NOTPARALLEL to avoid races between - "make" child processes (thx Anders Kaseorg; closes: #720274). - - -- Jonathan Nieder Mon, 19 Aug 2013 22:41:08 -0700 - -git (1:1.8.4~rc3-1) unstable; urgency=low - - * new upstream release candidate. - * switch de translation from pure German to German+English. - * debian/diff/: - * 0012-Revert-git-stash-avoid-data-loss-when-....diff: new - from upstream: stash: omit too-slow check for files - replaced by directories before stashing. - * 0013-Revert-Add-new-shortcut-for-HEAD.diff: new from - upstream: treat "@" and names like "refs/heads/@/foo" as - ordinary refnames again. - * debian/control: Vcs-Git: https://repo.or.cz/r/git/debian.git/ - (thx brian m. carlson; closes: #719932). - * debian/git.README.source: suggest developing against - https://repo.or.cz/r/git/debian.git/. - * debian/watch: use xz-compressed tars from kernel.org again. - - -- Jonathan Nieder Sun, 18 Aug 2013 03:41:49 -0700 - -git (1:1.8.4~rc2-1) unstable; urgency=low - - * new upstream release candidate. - * cat-file: do not split --batch input lines on whitespace - (thx Joey Hess; closes: #718517). - - -- Jonathan Nieder Sat, 10 Aug 2013 12:25:45 -0700 - -git (1:1.8.4~rc1-1) unstable; urgency=low - - * new upstream release candidate. - * debian/watch: point to code.google.com again. - * debian/git.preinst: - * check that targets in /var/cache/git/* exist when - creating symlinks from /var/lib/git/ (thx Steve Cotton and - Christoph Anton Mitterer; closes: #718411). - * remove spurious '/var/lib/git/*' symlink from the upgrade - to 1:1.8.4~rc0-1. - - -- Jonathan Nieder Thu, 01 Aug 2013 23:14:58 -0700 - -git (1:1.8.4~rc0-1) unstable; urgency=low - - * new upstream release candidate. - * use /var/lib/git instead of /var/cache/git as default git - project root to comply with the Filesystem Hierarchy Standard - (thx Julian Gilbey; closes: #483788): - * git-daemon.default, git-daemon.in, git-daemon/run: use - base path of /var/lib and projectroot of /var/lib/git. - * gitweb.conf: $projectroot = "/var/lib/git". - * rules: package git: install empty /var/lib/git directory - instead of /var/cache/git. - * git.README.Debian, git-daemon-run.README.Debian, - git-daemon-sysvinit.README.Debian, gitweb.README.Debian: - update for the new project root. - * git.preinst: install symlinks /var/lib/git/* -> - ../../cache/git/*. - * git.NEWS.Debian: advertise the change and explain how to - adapt to it. - * update debian/copyright. - - -- Jonathan Nieder Tue, 30 Jul 2013 19:11:14 -0700 - -git (1:1.8.3.2-1) unstable; urgency=low - - * new upstream point release (see RelNotes/1.8.3.2.txt). - - -- Jonathan Nieder Mon, 01 Jul 2013 19:20:03 -0700 - -git (1:1.8.3.1-1) unstable; urgency=low - - * merge branch debian-experimental - * new upstream point release (see RelNotes/1.8.3.1.txt). - * debian/watch: use xz-compressed tarballs from kernel.org. - - -- Jonathan Nieder Wed, 12 Jun 2013 07:50:53 -0700 - -git (1:1.8.3-1) experimental; urgency=low - - * new upstream release (see RelNotes/1.8.3.txt). - - -- Jonathan Nieder Wed, 29 May 2013 22:32:40 -0700 - -git (1:1.8.3~rc3-1) experimental; urgency=low - - * new upstream release candidate. - - -- Jonathan Nieder Sun, 19 May 2013 11:49:16 -0700 - -git (1:1.8.3~rc2-1) experimental; urgency=low - - * new upstream release candidate. - * gitk: "grep diff" pickaxe variant (closes: #589283). - * debian/rules: install perl modules with correct permissions - (thx Christian Schwartz for suggesting it through lintian). - * move "git svn" perl helpers to the git-svn package. - * debian/rules: install Git::SVN and Git::SVN::* to the - git-svn package, not git. - * debian/control: git-svn: Breaks: and Replaces: old git. - * debian/rules: install perl module manpages to git-man and - git-svn packages, as appropriate. - * debian/rules: mark hooks in /usr/share/git-core/contrib/hooks/ - as executable (thx Olivier Berger; closes: #687391). - * debian/control: drop Depends: and Build-Depends: libc6.1 - (>= 2.10.2-6) [ia64] workaround for #563882, since that bug did - not affect any stable release. - * debian/control: drop dependencies on pre-Debian 5.0 (lenny) - packages. - * do not accept libcurl3-gnutls-dev as a substitute for - libcurl4-gnutls-dev. - * do not accept libsvn-core-perl as a substitute for - libsvn-perl. - * make asciidoc, docbook-xsl, runit, and tk dependencies - unversioned. - * git, git-man, git-cvs, git-svn, git-email, gitk: drop Breaks - and Replaces against cogito (<< 0.16rc2-0). - * git: drop Breaks against old qgit and git-buildpackage. - * git: drop Conflicts against git-core (<< 1:1.5.2~rc3-2.). - * git-gui: no longer Replaces git-core (<< 1:1.5.2.2-3). - * Use source format 3.0 (quilt). - - -- Jonathan Nieder Wed, 15 May 2013 00:20:06 -0700 - -git (1:1.8.3~rc1-1) experimental; urgency=low - - * new upstream release candidate. - * log --pretty: avoid undefined behavior in %>, %<, %><'s - truncation support (closes: #706400). - - -- Jonathan Nieder Fri, 03 May 2013 23:28:04 -0700 - -git (1:1.8.3~rc0-1) experimental; urgency=low - - * new upstream release candidate. - * remote-bzr: respect bzr "author" field in import (closes: - #705245). - * remote-bzr: allow re-add of a deleted file in the same commit - (closes: #704913, #704959). - - -- Jonathan Nieder Mon, 29 Apr 2013 00:29:14 -0700 - -git (1:1.8.2.1-1) experimental; urgency=low - - * new upstream point release (see RelNotes/1.8.2.1.txt). - * debian/implicit: - * check for debian/changelog.upstream. - * %.deb-DEBIAN-md5sums depends on /usr/share/doc/$pkg/doc/, - doc-base/, and lintian/ directories. - * do not remove files named after implicit targets. - * debian/rules: - * respect in DEB_BUILD_OPTIONS=parallel=. - * do not create ./changelog symlink (avoiding a race). - * override implicit git-core.deb-docs target, since git-core does - not have its own doc/ directory. - * debian/README.source: point to git.README.source (thx Helmut - Grohne; closes: #704580) - * debian/git.NEWS.Debian: add leading spaces before tab for - changelog parsers (thx Russ Allbery for suggesting it through - lintian). - - -- Jonathan Nieder Mon, 08 Apr 2013 00:46:02 -0700 - -git (1:1.8.2-1) experimental; urgency=low - - * new upstream release (see RelNotes/1.8.2.txt). - * package the bzr remote helper (closes: #702697). - * debian/control: new package git-bzr; Priority: extra; Provides: - git-remote-bzr; Depends: python, python-bzrlib; Conflicts: - bzr-git; Build-Depends: bzr, python, python-bzrlib for tests; - package git now Suggests and git-all Recommends: git-bzr. - * debian/git-remote-bzr.txt: new; explain usage. - * debian/rules: build git-remote-bzr documentation, munge script - shebang line, and install manpage (git-remote-bzr--git.1.gz) - and script (/usr/lib/git-core/git-remote-bzr--git) in git-bzr - package. - * debian/git-doc.docs: install git-remote-bzr.html. - * debian/git-bzr.postinst, debian/git-bzr.prerm: new; provide - /usr/bin/git-remote-bzr through the alternatives system. - * debian/git-bzr.README.Debian: new; explain how to get started. - * debian/control: Standards-Version: 3.9.4.0. - * debian/rules: define %.install depending on install-arch or - install-indep as appropriate for each package. - * debian/implicit: depend on %.install instead of both install-arch - and install-indep so "debian/rules binary-arch" does not try to - build documentation. - * debian/rules build-indep, install-indep: build documentation even - if asciidoc is not installed. Build-Depends: dpkg-dev (>= 1.16.2). - * debian/rules: handle DEB_BUILD_OPTIONS=parallel=. - - -- Jonathan Nieder Sun, 31 Mar 2013 22:06:58 -0700 - -git (1:1.8.2~rc3-1) experimental; urgency=low - - * new upstream release candidate. - - -- Jonathan Nieder Sat, 09 Mar 2013 00:50:39 -0800 - -git (1:1.8.2~rc2-1) experimental; urgency=low - - * new upstream release candidate. - * skip readlink() of entries in GIT_CEILING_DIRECTORIES after an - empty entry (thx Anders Kaseorg and Michael Haggerty). - * update debian/copyright. - - -- Jonathan Nieder Sun, 03 Mar 2013 15:22:27 -0800 - -git (1:1.8.2~rc1-1) experimental; urgency=low - - * new upstream release candidate. - - -- Jonathan Nieder Sat, 02 Mar 2013 13:27:28 -0800 - -git (1:1.8.2~rc0-1) experimental; urgency=low - - * new upstream release candidate. - * push: require force for refs under refs/tags/. - * push: require force for annotated tags. - * debian/git.NEWS.Debian: advertise upcoming change to default - behavior of argumentless "git push []". - * git-svn: no longer Depends: libwww-perl (thx RjY; closes: - #699536). - * update debian/copyright (closes: #699930). - - -- Jonathan Nieder Mon, 18 Feb 2013 16:52:57 -0800 - -git (1:1.8.1.3-1) experimental; urgency=low - - * new upstream point release. - - -- Jonathan Nieder Thu, 07 Feb 2013 23:08:48 -0800 - -git (1:1.8.1.2-1) experimental; urgency=low - - * new upstream point release. - - -- Jonathan Nieder Sun, 03 Feb 2013 23:01:24 -0800 - -git (1:1.8.1.1-1) experimental; urgency=low - - [ Jonathan Nieder ] - * debian/git.NEWS.Debian: bash completion script moved to - /usr/share/bash-completion/completions/ (thx Philipp Marek; - closes: #698055). - - [ Gerrit Pape ] - * new upstream release. - - -- Gerrit Pape Wed, 16 Jan 2013 08:17:53 +0000 - -git (1:1.8.1-1) experimental; urgency=low - - * new upstream release (see RelNotes/1.8.1.txt). - - -- Jonathan Nieder Mon, 31 Dec 2012 18:40:24 -0800 - -git (1:1.8.1~rc3-1) experimental; urgency=low - - * new upstream release candidate. - * grep: enable perl regex (-P) support (thx Guido Günther; closes: - #669376). - - -- Jonathan Nieder Tue, 25 Dec 2012 23:40:08 -0800 - -git (1:1.8.1~rc0-1) experimental; urgency=low - - * new upstream release candidate. - * debian/control: mark all binary packages Multi-Arch: foreign (thx - Colin Watson; closes: #694651). - - -- Jonathan Nieder Thu, 06 Dec 2012 15:10:21 -0800 - -git (1:1.8.0-1) experimental; urgency=low - - * new upstream release (see RelNotes/1.7.11.txt, RelNotes/1.7.12.txt, - RelNotes/1.8.0.txt) - * git-svn: ignore SIGPIPE so serf can recover from HTTP timeouts - (closes: #526989). - * git-svn: use platform specific auth providers. - * git-svn: handle errors and concurrent commits in dcommit - (closes: #676904). - * am: support --include option. - * grep: add a grep.patternType configuration setting. - * daemon: --access-hook for authentication logging and policy. - * merge-base: expose --is-ancestor helper for scripts. - * branch: support --set-upstream-to with simpler syntax than - --set-upstream. - * format-patch: do not use bogus email addresses in message ids. - * http: trim trailing newline from /etc/mailname. - * do not ignore port in ssh URLs with ipv6 literals - (closes: #646178). - * look in ~/.config/git/config (XDG_CONFIG_HOME can override this) - before ~/.gitconfig for configuration. - * [core] excludesfile and attributes file default to - ~/.config/git/ignore and ~/.config/git/attributes. - * var doc: advertise current DEFAULT_PAGER and DEFAULT_EDITOR - settings (closes: #666250). - * git-blame.el: address elisp warnings from emacs: - * use mapc instead of mapchar (closes: #611931). - * do not use goto-line in lisp code (closes: #611933). - * use with-current-buffer where appropriate (closes: #611932). - * cli: add Italian and Vietnamese translations. - * push: introduce new push.default mode "simple". It will be the - default in the next major release. - - [ Jonathan Nieder ] - * debian/diff: - * 0013...0031: remove; applied upstream. - * 0012-Makefile-add-a-knob-to-turn-off-...diff: remove; fixed - upstream. - * debian/rules: - * install German translation. - * use NO_INSTALL_HARDLINKS=1 instead of NO_HARDLINKS=1 in OPTS - (thx Tomáš Myšík and Anders Kaseorg; see #683568). - * install-arch: sanity-check that built-ins still do not approach - btrfs hardlink limit (see #642603). - * git: install git-prompt.sh from contrib/completion to - /usr/lib/git-core/git-sh-prompt. - * git: install completion script to - /usr/share/bash-completion/completions/{git,gitk} instead of - /etc/bash_completion.d. This allows bash-completion 2.0 to load - it on the fly when completing arguments to git commands. - * debian/control: Breaks: bash-completion (<< 1:1.90-1). - * debian/git.preinst, debian/git.postinst, debian/git.postrm: - remove /etc/bash_completion.d/git on upgrade if unmodified. - * debian/rules, debian/git.conffiles, debian/git-prompt.completion: - /etc/bash_completion.d/git-prompt: new; source - /usr/lib/git-core/git-sh-prompt so .bashrc files that rely on the - completion lib defining __git_ps1 can continue to work (thx Danny - Yates and Anders Kaseorg). - * debian/git.conffiles: remove /etc/bash_completion.d/git. - * update debian/copyright. - * debian/control: gitweb: Recommends: libhttp-date-perl or - libtime-module-perl for If-Modified-Since support; Build-Depends: - same to support test suite. - * debian/implicit: use order-only dependencies so "debian/rules - binary-arch" does not try to build documentation. - - [ Gerrit Pape ] - * new upstream release. - - -- Jonathan Nieder Wed, 31 Oct 2012 17:58:10 -0700 - -git (1:1.7.10.4-2) unstable; urgency=low - - * debian/diff: - * 0013...0030: new from the upstream 'master' branch: git svn: - adapt to svn 1.7 changes: - * normalize paths and URLs passed to Subversion (thx Michael G. - Schwern; closes: #678137) - * use correct "svn cp" syntax when checking git svn's mangling - of @-signs in branch names (svn became stricter). - * commit filetype changes between a regular file and symlink as - replacement (deletion followed by addition) instead of - modification of files. Otherwise, clients pulling the change - with "svn update" hit an assertion failure (svn issue 4091). - * 0031-git-svn-use-YAML-format-...diff: new from 1.7.11: git svn: - use YAML format for mergeinfo cache when possible. - * debian/control: git-svn: Depends: libyaml-perl for platform- and - version-independent .git/svn/.caches format; Build-Depends: - libyaml-perl for tests (thx Tim Retout for the analysis; closes: - #587650). - - -- Jonathan Nieder Fri, 12 Oct 2012 13:27:36 -0700 - -git (1:1.7.10.4-1) unstable; urgency=low - - * new upstream point release (thx Jonathan Nieder). - - -- Gerrit Pape Fri, 08 Jun 2012 00:04:11 +0000 - -git (1:1.7.10.2-1) unstable; urgency=low - - * new upstream point release. - * merge-recursive: don't detect renames of empty files. - * fast-import: tighten parsing of datarefs. - * diff -c -U0: fix segfault showing start of file. - * debian/rules: do not install preliminary German translation. - - -- Jonathan Nieder Fri, 11 May 2012 20:20:15 -0500 - -git (1:1.7.10-1) unstable; urgency=low - - * new upstream release. - * merge: use editor by default in interactive sessions - * submodules: use relative paths to git dir and worktree. - * fast-import: reject "ls" of path with empty components. - * cli: add Chinese, Dutch, Portuguese, and Swedish translations. - * am: officially deprecate -b/--binary option. - * debian/diff: - * 0005-gitk-use-symbolic-font-names-sans-and-monospace-when-.diff, - 0006-gitk-Skip-over-AUTHOR-COMMIT_DATE-when-searching-all-.diff: - remove; applied upstream. - * 0007...0014: rename to 0005-*, ... 0012-*. - * debian/git.README.Debian: make paths in inetd(8) hint - consistent with git-daemon-run and git-daemon-sysvinit setup. - * debian/control: package git: Suggests: gettext-base for translated - output in shell scripts. - - -- Jonathan Nieder Fri, 06 Apr 2012 22:28:18 -0500 - -git (1:1.7.9.5-1) unstable; urgency=low - - * new upstream point release. - * debian/control: git-daemon-sysvinit: Priority: extra (thx Jonathan - Nieder; closes: #661317). - - -- Gerrit Pape Wed, 28 Mar 2012 12:30:35 +0000 - -git (1:1.7.9.4-1) unstable; urgency=low - - * new upstream point release. - * commit: skip intent-to-add entries instead of erroring out. - * grep -I: let diff attribute override binary file detection. - * clone, daemon, http-backend, transport: look for .../foo before - .../foo.git in response to requests for .../foo. - * rev-list: enable or disable --verify-objects behavior based on - the command line instead of uninitialized memory. - * checkout -b: allow switching out of an unborn branch (closes: - #506480). - * debian/diff: clean up patches for upstream. - * 0001-hooks-post-receive-email-set-encoding-to-utf-8.diff: - hooks/post-receive-email: set content-transfer-encoding as well. - * 0002-post-receive-email-defend-against-non-utf8-...diff: new; - hooks/post-receive-email: avoid mixed-encoding messages when - i18n.logoutputencoding is not utf8 (thx Alexey Shumkin). - * 0002-remove-shebang-...diff: rename to 0003-remove-...diff; - remove #! line from sh-i18n and rebase--* shell libraries, too - (lintian); fix tests' --valgrind support to detect shell - libraries without the #! line (thx Jeff King). - * 0003-pre-rebase-hook-capture-...diff: simplify (thx Junio C - Hamano); rename to 0004-*. - * 0004-gitk-use-symbolic-font-names-...diff: rename to 0005-*; use - non-symbolic font names on platforms like Mac OS X, Windows, and - tk <= 8.4 that lack fontconfig support. - * 0005...0008, 0010: rename to 0006-*, ..., 0009-*, 0011-*; - clarify descriptions. - * 0009-tcp-unify-ipv4-and-ipv6-code-paths.diff, 0011-*: combine; - rename to 0010-*. - * 0012-transport-optionally-honor-DNS-SRV-records.diff, 0013-*: - combine; rename to 0011-*. - * 0014, 0015: rename to 0013-*, 0014-*. - * debian/git-daemon.init: respect GIT_DAEMON_ENABLE in restart and - reload actions (thx Jonathan McCrohan; closes: #663522). - * debian/control: git-gui: point to aspell for spell checking support - in the package description; Suggests: aspell (thx Jonathan Ballet, - closes: #656061). - * debian/control: add Vcs-Browser: http://repo.or.cz/w/git/debian.git - (thx Jonathan McCrohan; closes: #663451). - * debian/control: Standards-Version: 3.9.3.1. - * debian/copyright: adopt copyright-format 1.0. - - -- Jonathan Nieder Wed, 14 Mar 2012 02:40:00 -0500 - -git (1:1.7.9.1-1) unstable; urgency=low - - * new upstream point release. - * merge: do not launch an editor on "--no-edit $tag" (thx Guido - Günther; closes: #659255). - - -- Jonathan Nieder Tue, 14 Feb 2012 15:32:48 -0600 - -git (1:1.7.9-1) unstable; urgency=low - - * merge branch debian-experimental. - * new upstream release (closes: #657262). - * debian/diff/0016-unix-socket-handle-long-socket-...diff: remove; - applied upstream. - * debian/changelog: add missing parenthesis to 1:1.7.9~rc1-1 entry. - - -- Jonathan Nieder Fri, 27 Jan 2012 21:23:27 -0600 - -git (1:1.7.9~rc1-1) experimental; urgency=low - - * new upstream release candidate. - * debian/diff: - * 0014-Makefile-add-a-knob-to-...diff: rename to 0015-*. - * 0014-srv-be-more-tolerant-of-broken-DNS-replies.diff: new; srv: - convert some error conditions to warnings (closes: #649781). - * 0016-unix-socket-handle-long-socket-pathnames.diff: new from - upstream; credential-cache: handle long socket pathnames (closes: - #655288). - - -- Jonathan Nieder Fri, 13 Jan 2012 16:10:44 -0600 - -git (1:1.7.9~rc0-1) experimental; urgency=low - - * new upstream release candidate. - * update debian/copyright. - - -- Jonathan Nieder Fri, 06 Jan 2012 17:06:55 -0600 - -git (1:1.7.8.3-1) unstable; urgency=medium - - * new upstream point release. - * debian/git.preinst: on upgrade from git <= 1:1.7.7-1, replace - /usr/lib/git-core/git with a copy of itself. This prevents "are the - same file" errors when replacing hard links to the old copy with - symlinks using "mv" (thx Jon Dowland and Anders Kaseorg; closes: - #654596). - - -- Jonathan Nieder Fri, 06 Jan 2012 16:45:46 -0600 - -git (1:1.7.8.2-1) unstable; urgency=low - - * merge branch debian-experimental. - * new upstream release. - - -- Jonathan Nieder Thu, 29 Dec 2011 01:30:43 -0600 - -git (1:1.7.8~rc3-1) experimental; urgency=low - - * new upstream release candidate. - - -- Jonathan Nieder Fri, 18 Nov 2011 04:09:51 -0600 - -git (1:1.7.8~rc2-1) experimental; urgency=low - - [ Jonathan Nieder ] - * new upstream release candidate. - * merge branch debian-sid. - * update debian/copyright. - * debian/git.preinst: replace hard links to /usr/lib/git-core/git with - symlinks before upgrading from git <= 1:1.7.7-1 (thx Antti Kultanen; - closes: #645009). - - [ Gerrit Pape ] - * merge branch debian-sid. - - -- Gerrit Pape Wed, 16 Nov 2011 09:55:47 +0000 - -git (1:1.7.7.3-1) unstable; urgency=low - - * new upstream point release. - - -- Gerrit Pape Mon, 14 Nov 2011 10:22:34 +0000 - -git (1:1.7.7.2-1) unstable; urgency=low - - * new upstream point release. - * debian/rules: add separate build-arch and build-indep targets - (thx Roger Leigh for suggesting it through lintian). - * debian/rules: drop CFLAGS=-O0 workaround for ancient hppa code - generation bug (see #426302). - * debian/rules: use dpkg-buildflags to retrieve compiler flags - (including hardening options). Build-Depends: dpkg-dev (>= 1.15.7). - - -- Jonathan Nieder Tue, 01 Nov 2011 23:41:55 -0500 - -git (1:1.7.8~rc0-1) experimental; urgency=low - - * merge branch debian-sid. - * new upstream release candidate. - * debian/diff/0001-...diff, 0002-...diff, 0003-...diff: remove; - applied upstream (thx Jonathan Nieder). - - -- Gerrit Pape Mon, 31 Oct 2011 09:45:53 +0000 - -git (1:1.7.7.1-1) unstable; urgency=low - - * new upstream point release. - * debian/diff/0003-Makefile-do-not-set-setgid-bit-on-dir...diff: - remove; applied upstream. - - -- Gerrit Pape Mon, 24 Oct 2011 20:27:20 +0000 - -git (1:1.7.7-2) unstable; urgency=low - - [ Jonathan Nieder ] - * debian/git.postinst: check if /usr/share/doc/git/contrib/hooks is a - symlink before changing it to one (thx Євгеній Мещеряков; closes: - #645005). - * debian/diff: - * 0001-ident-check-etc-mailname-if-author-email-is-unknown.diff, - 0007-Makefile-do-not-use-setgid-bit-on-...diff: remove; obsolete. - * 0002...0006, 0008...0015: rename to 0005-*, ..., 0017-*. - * 0001...0004: new from the upstream 'master' branch: - * ident: check /etc/mailname if email is unknown - * ident: do not retrieve default ident when unnecessary - * init --shared: do not set setgid bit on directories on - GNU/kFreeBSD - * Makefile: fix permissions of mergetools/ when building from - source extracted with permissive umask - * 0018-Makefile-add-a-knob-to-turn-off-hardlinks-...diff: new; - Makefile: add a knob to disable hardlinks within bindir and - gitexecdir. - * debian/rules: add NO_HARDLINKS=1 to OPTS (thx Bastian Blank; - closes: #642603). - * debian/rules: do not rely on umask to set contrib permissions. - * update debian/copyright. - * debian/watch, debian/copyright: point to code.google.com for now. - The upstream tarballs haven't been added back to kernel.org yet. - * debian/changelog.upstream, debian/versions.upstream: include - v1.7.6.4. - - [ Simon Chopin ] - * debian/git.postinst: fix fresh install contrib/hooks cleaning - (#645005). - - -- Gerrit Pape Thu, 13 Oct 2011 00:04:49 +0000 - -git (1:1.7.7-1) unstable; urgency=low - - * new upstream release. - * merge branch debian-experimental. - * debian/rules, debian/git.postinst: move contrib hooks from - /usr/share/doc/git-core/ into /usr/share/git-core/; provide symlink - for backward compatibility (closes: #640949). - - -- Gerrit Pape Sun, 09 Oct 2011 21:00:07 +0000 - -git (1:1.7.7~rc1-1) experimental; urgency=low - - * merge branch debian-sid. - * new upstream release candidate. - * debian/rules: git: skip directories in /usr/lib/git-core/ and - /usr/bin/ when stripping programs. - - -- Gerrit Pape Wed, 14 Sep 2011 14:23:10 +0000 - -git (1:1.7.6.3-1) unstable; urgency=low - - * merge branch debian-experimental. - * new upstream point release. - * debian/diff: - * 0007-...diff, ..., 0014-...diff: slightly rework as 0008...0015-* - to provide better error reporting (thx Jonathan Nieder). - * 0015-Makefile-do-not-use-setgid-bit-on-...diff: rename to 0007-*. - - -- Gerrit Pape Wed, 14 Sep 2011 11:33:23 +0000 - -git (1:1.7.6-1) experimental; urgency=low - - * new upstream release. - * debian/diff: - * 0012-daemon-check-for-errors...diff: clarify patch description. - * 0013-transport-learn-to-honor-DNS-SRV...diff: rename to 0014-*. - * 0013-tcp-make-dns_resolve-return-an-error-code.diff: new; make - dns_resolve() pass on return value from getaddrinfo. - * 0014-transport-honor-DNS-SRV-records.diff: fix two regressions - introduced by this patch when it was added in 1:1.7.6~rc1-1. - * use descriptive messages like "Unable to look up - git.example.com: Out of memory" to report errors from the - resolver, instead of "unable to connect to a socket (success)". - * tolerate alias (CNAME) records in the DNS reply for - _git._tcp., instead of confusing them for invalid SRV - records and erroring out. - * 0015-Makefile-do-not-use-setgid...diff: new; Makefile: set - DIR_HAS_BSD_GROUP_SEMANTICS on GNU/kFreeBSD. - - -- Jonathan Nieder Tue, 28 Jun 2011 12:54:58 -0500 - -git (1:1.7.6~rc2-1) experimental; urgency=low - - * new upstream release candidate. - - [ Daniel Baumann ] - * add an init.d script for git-daemon (closes: #422139). - * debian/control, debian/rules: new package git-daemon-sysvinit; - Depends: adduser; Conflicts: git-daemon-run; package git now - Suggests and git-all Recommends: git-daemon-run | - git-daemon-sysvinit. - * debian/git-daemon.init: new; script to start or stop git-daemon. - * debian/git-daemon.default: new; provide some default settings and - disable the daemon by default on first installation. - * debian/git-daemon-sysvinit.README.Debian: new; explain how to get - started. - * debian/git-daemon-sysvinit.conffiles: new; treat - /etc/default/git-daemon, /etc/init.d/git-daemon as conffiles. - * debian/git-daemon-sysvinit.postinst: new; add gitdaemon system - user; register and invoke init script to start git-daemon. - * debian/git-daemon-sysvinit.prerm: new; stops git-daemon. - * debian/git-daemon-sysvinit.postrm: new; unregisters init script. - - [ Jonathan Nieder ] - * debian/diff/: - * 0009-daemon-move-...diff, 0011-tcp-...diff: move fallback - definition of HOST_NAME_MAX to new use sites (fixes FTBFS on - kfreebsd). - * 0012-transport-learn-to-honor...diff: rename to 0013-*. - * 0012-daemon-check-for-errors-retrieving-canonical-IP-addre.diff: - new; daemon: check for errors when retrieving IP address for use - by the --interpolated-path feature. - - -- Jonathan Nieder Fri, 17 Jun 2011 15:56:12 -0500 - -git (1:1.7.6~rc1-1) experimental; urgency=low - - * new upstream release candidate. - * debian/diff/0007-...diff, ..., 0012-transport-learn...diff: new; - teach the git client to pay attention to SRV records (thx Julien - Cristau; closes: #627839). - * debian/rules: add USE_SRV_RR=1 to OPTS. - * debian/rules: add htmldir=/usr/share/doc/git/html to OPTS and - DOC_OPTS. - - -- Jonathan Nieder Thu, 09 Jun 2011 19:05:55 -0500 - -git (1:1.7.5.4-1) unstable; urgency=low - - * new upstream point release. - - [ Gerrit Pape ] - * debian/changelog.upstream, debian/versions.upstream: update upstream - changelog. - - [ Jonathan Nieder ] - * debian/changelog.upstream.sh: use set -e. - * debian/git-daemon/run: use SO_REUSEADDR when binding the listening - socket so the server can restart without waiting for old connections - to time out (thx Daniel Kahn Gillmor; closes: #609405). - * debian/git-daemon-run.postrm purge: terminate the git-daemon/log - service, even if there is an active connection using it, before - deleting logs and the gitlog user (thx Daniel Kahn Gillmor; closes: - #627314). - - -- Jonathan Nieder Tue, 07 Jun 2011 13:23:58 -0500 - -git (1:1.7.5.3-1) unstable; urgency=low - - * new upstream point release. - * debian/diff/0007-...diff, 0008-...diff, 0009-...diff, 0010-...diff: - remove; included upstream. - * debian/control: Package: git-cvs: make cvs dependency unversioned; - Package: git-gui: make tk dependency unversioned (thx Jonathan - Nieder). - - -- Gerrit Pape Fri, 27 May 2011 13:00:05 +0000 - -git (1:1.7.5.1-1) unstable; urgency=low - - * new upstream point release. - * merge branch debian-experimental. - * debian/diff/: - - 0009-upload-pack-start-pack-objects-before-async-rev-...diff: - remove; applied upstream. - - 0007, 0008 (the add -p split-and-edit fix): rename to 0009-*, - 0010-*. - - 0007-add-p-q-should-really-quit.diff, 0008-t3701-...diff: new - from upstream; tests: check that the add -p split-and-edit bug - has not resurfaced. - * debian/control: package git: no longer Conflicts: but Breaks: - git-core from Debian 5.0 (lenny) to simplify the upgrade path - (thx Russ Allbery for suggesting it through lintian). - * debian/control: package git: Conflicts: git-core from - Debian 4.0 (etch) which provided /usr/bin/git through the - alternatives system. - * debian/control: Standards-Version: 3.9.2.0. - - -- Jonathan Nieder Thu, 05 May 2011 03:41:36 -0500 - -git (1:1.7.5-1) experimental; urgency=low - - * new upstream release. - * 0009-upload-pack-start-pack-objects-before-async-rev-list.diff: - new from upstream; upload-pack: start pack-objects which reads - pack_pipe before writing to it to avoid deadlock (closes: - #607346). - * debian/changelog.upstream, debian/versions.upstream: do not skip - versions not packaged for Debian (thx Gerrit Pape). - - -- Jonathan Nieder Tue, 26 Apr 2011 21:49:48 -0500 - -git (1:1.7.5~rc3-1) experimental; urgency=low - - * new upstream release candidate. - * merge branch debian-sid. - * 0007-gitk-Take-only-numeric-version-components-when-comput.diff: - remove; applied upstream. - - -- Gerrit Pape Wed, 20 Apr 2011 07:46:58 +0000 - -git (1:1.7.4.4-1) unstable; urgency=low - - * new upstream point release. - * debian/diff/0008...0064: remove; applied upstream. - * debian/diff/0008-add...diff, 0009-add-p-work...diff: new from - upstream; add -p: do not error out for attempts to stage hunks - after splitting and editing them. This fixes a regression - introduced by v1.7.4.3~10^2 (apply: do not patch lines that were - already patched, 2011-03-04). - * debian/git-doc.doc-base.git-index-format: new; catalog - .git/index file format document. - * debian/git.preinst, debian/git.postinst, debian/git.postrm: - don't use dpkg-maintscript-helper, avoiding a dependency on - recent dpkg (thx Anders Kaseorg and Marc Haber; closes: #618708). - * debian/git-daemon-run.postrm: terminate the git-daemon/log - service before deleting the gitlog user (closes: #610099). - - -- Jonathan Nieder Fri, 15 Apr 2011 00:00:03 -0500 - -git (1:1.7.4.1-5) unstable; urgency=low - - * merge branch debian-experimental. - * debian/diff/0008...0064: new from the upstream 'maint' branch: - (see RelNotes/1.7.4.2.txt for details) - * revert "core.abbrevguard: Ensure short object names stay - unique a bit longer" - * parse_tag_buffer(): do not prefixcmp() out of range - * pull: do not display fetch usage on --help-all - * gitweb: address warnings from perl 5.13 - * gitweb: replace tabs with spaces when highlighting syntax - * merge: honor prepare-commit-msg hook - * diff: handle diffstat of rewritten binary files - * config: add "[push] default = upstream" synonym for - "[push] default = tracking" - * diffcore: properly honor the difference between -M and -C - * diffcore: improve similarity heuristics for rename detection - * patch-id: do not trip over "no newline" marker - * various documentation, usage string, and code clarity - improvements - - -- Jonathan Nieder Wed, 16 Mar 2011 21:01:53 -0500 - -git (1:1.7.4.1-4) experimental; urgency=low - - * git-el.postinst: check if /usr/share/doc/git/contrib/emacs is a - symlink before changing it to one (closes: #617631). - * git-el.postinst: remove spurious .../contrib/emacs.old and - /usr/share/git-core/emacs/emacs symlinks. - * package git: do not run emacs-package-remove on upgrade (it's not - needed). - - git.postinst: do not run "emacs-package-remove git". - - debian/control: git no longer Depends: emacsen-common (closes: - #617784). - * git-el.emacsen-install, git-el.emacsen-remove: - - use printf instead of echo. - - only remove the lisp (.el) and bytecode (.elc) files that we - install. - - make output less noisy --- for example, do not say "+ set +x". - - -- Jonathan Nieder Sun, 13 Mar 2011 05:03:44 -0500 - -git (1:1.7.4.1-3) unstable; urgency=low - - [ Anders Kaseorg ] - * Loosen versioned replaces/conflicts on git-core, to fix upgrades from - lucid. - - [ Jonathan Nieder ] - * README.emacs: git-blame.el does not print a summary in the echo - area (documents: #611935). - * Move emacs support files to a separate git-el package. - * Make git depend on emacsen-support, so it can reliably clean up - the old emacs support files on upgrade (closes: #614578) - * git-el.emacsen-install: Overwrite .el symlinks if they already - exist (closes: #614659). - * git-el.emacsen-remove: Do not complain if the site-lisp - directory is nonempty or is already missing. - * debian/control: git-man: Section: doc. - - -- Jonathan Nieder Fri, 04 Mar 2011 18:26:27 -0600 - -git (1:1.7.4.1-1) unstable; urgency=low - - * new upstream release (closes: #600566, #575917, #578752, #583693, - #583699, #588103, #507476, #540001, #524309, #581691, #600785, - #577471, #607044, #606975, #610423, #610481). - - [ Anders Kaseorg ] - * debian/git.docs, debian/rules: deal with RelNotes subdirectory. - * debian/diff/0007-gitk-Take-only-numeric-...diff: new; gitk: do - not error out when git version number contains "-rc". - - [ Jonathan Nieder ] - * add myself as uploader. - * debian/diff/0003, 0007, 0010-0034: remove, applied upstream. - * debian/rules: accept patches with .patch suffix, too (thx Anders - Kaseorg). - * debian/rules: use patch -N -r- so patch application is idempotent. - * update debian/copyright. - * debian/diff/0001-ident-check-etc-mailname...diff: avoid calls to - gethostbyname when mailname is not an fqdn (closes: #611608). - * debian/diff/0005-gitk-use-...diff: new; gitk: use standard desktop - fonts by default. The appearance for users that already have a - generated ~/.gitk file is not affected (closes: #466471). - * debian/diff/0006-gitk-...diff: new; gitk: avoid spurious matches - in "All fields" search (thx Frédéric Brière, closes: #465776). - * debian/control: git-cvs: recommend cvs2git for one-time conversions - (closes: #585725). - * debian/control: git-core: explain that it still may be needed (thx - Denis Laxalde). - * debian/control: gitweb: allow lynx-cur to satisfy dependency on a - CGI implementation (thx Ivan Shmakov). - * debian/control, debian/rules: new architecture-independent package - git-man: manual pages that were previously in the main git package. - * debian/rules: do not build documentation on autobuilders (closes: - #499002). - * debian/control: Build-Depends-Indep: asciidoc, xmlto, docbook-xsl. - * debian/rules: git-gui: install git-gui--askpass helper to - /usr/lib/git-core (closes: #598245). - * debian/rules: git-doc: install symlink to html documentation in - /usr/share/doc/git (thx Ian Jackson). - * debian/watch: new; point to upstream sources. - * debian/implicit: create DEBIAN/md5sums with correct permissions. - * debian/diff/0003-remove-shebang...diff: new; do not start shell - libraries with #!/bin/sh. - * debian/rules: do not try to strip scripts even if they begin - with "# " in place of "#!". - * debian/diff/0004-pre-rebase-hook-capture...diff: new; - hooks/pre-rebase: use a < Tue, 15 Feb 2011 19:27:38 -0600 - -git (1:1.7.2.3-2.2) unstable; urgency=medium - - * Non-maintainer upload. - * debian/diff/0034-gitweb-Introduce-esc_attr...diff: new from - upstream: gitweb: do not parrot filenames or other arguments given - in a request without proper quoting (closes: #607248, - CVE-2010-3906). - - -- Jonathan Nieder Thu, 16 Dec 2010 01:00:30 -0600 - -git (1:1.7.2.3-2.1) unstable; urgency=low - - * Non-maintainer upload. - * debian/diff/0010...0033: new from the upstream 'maint' branch: - * cache_tree_free: Fix small memory leak. - * diff.c: call regfree to free memory allocated by regcomp. - * gitweb: allow configurations that change with each request - (fixes a regression from v1.7.2-rc2 in some gitolite setups). - * Documentation: 19 formatting fixes (thx Frédéric Brière, - closes: #540001, #600422). - * setup: make sure git dir path is in a permanent buffer. - * do not depend on signed integer overflow. - * debian/control: gitweb: weaken dependencies to allow configurations - using mod_perl or fastcgi rather than CGI; explain dependencies in - the package description (thx Servilio Afre Puentes, - closes: #600413). - - -- Jonathan Nieder Thu, 18 Nov 2010 19:04:09 -0600 - -git (1:1.7.2.3-2) unstable; urgency=low - - * merge branch debian-experimental. - * debian/gitweb.NEWS.Debian: typo (thx Jonathan Nieder). - - -- Gerrit Pape Sun, 17 Oct 2010 20:07:22 +0000 - -git (1:1.7.2.3-1) experimental; urgency=low - - * new upstream release. - * post-receive-email: document command-line mode (closes: #428413). - * add-interactive: Clarify “remaining hunks in the file” - (closes: #526014). - * rebase -i -p: document shortcomings (closes: #532775). - * GIT-VERSION-GEN: restrict tags used (closes: #473604). - * git svn: avoid unnecessary '/' in paths for SVN (thx Jon Dowland, - closes: #546733, #572847). - * git svn: avoid uninitialized var in 'reset' (thx Jens Seidel, - closes: #578908). - * debian/diff/0003-git-submodule.sh-properly-initialize-shell-...diff, - debian/diff/0004-Check-size-of-path-buffer-before-...diff: remove; - applied upstream. - * debian/diff/0001-Revert-gitweb-Use-diff_opts-while...diff: new; - prevent gitweb from serving rename patches that GNU patch 2.6.1 - cannot apply. - * debian/diff/0002-Revert-Merge-branch-jn-gitweb-plackup.diff: new; - install gitweb.css et al in /usr/share/gitweb, not a new static/ - subdirectory. - * debian/diff/0003-Do-not-unquote-into-in-URLs.diff: new from - upstream; do not unquote + into space character in URLs. - * debian/diff/0001-bug-448655-check-etc-mailname-...diff: rename to - debian/diff/0004-bug-448655-check-etc-mailname-if-author...diff. - * debian/diff/0002-bug-506445-hooks-post-receive-...diff: rename to - debian/diff/0005-bug-506445-hooks-post-receive-...diff; adapt. - * debian/diff/0006-instaweb-ignore-GITWEB_CONFIG_SYSTEM.diff: new; - instaweb: ignore /etc/gitweb.conf; - debian/diff/0007-gitweb-skip-logo-in-atom-feed-when...diff, ..., - debian/diff/0009-instaweb-disable-logo-and-favicon...diff: new; - instaweb: avoid 404 errors due to nonexistent image files (thx Uwe - Kleine-König, closes: #592733). - * update debian/copyright. - * debian/rules, debian/git.README.Debian, debian/gitweb.conf: - install gitweb.js, add an Alias for it to the VirtualHost example, - and configure gitweb to look for it in the right place (closes: - #555047). - * debian/gitweb.NEWS.Debian: mention the new gitweb.js file. - * debian/control: gitweb: Depends: apache2 | httpd-cgi (closes: - #559890). - * debian/gitweb.conf: use relative links for gitweb.css et al - (thx Alban Browaeys, closes: #568343). - * debian/control: package git: no longer Conflicts: git - (<< 4.3.20-11). - * debian/control: package git: Breaks: packages from Debian 5.0 - (lenny) relying on removed features such as dashed-form commands in - $PATH (thx Adrian Bunk, closes: #561701); no longer Conflicts: but - Breaks: ancient qgit for the same reason. - * debian/gitweb.README.Debian: copy-edit. - * debian/git.README.Debian: retitle to "Git for Debian" (thx - Christoph Anton Mitterer, closes: #590129). - * debian/control: Homepage: http://git-scm.com/ (closes: #553220). - * debian/control: package git no longer Depends: libdigest-sha1-perl - (thx Ansgar Burchardt, closes: #591039). - * debian/control: Build-Depends: libio-pty-perl for better test - coverage. - - -- Jonathan Nieder Fri, 03 Sep 2010 22:34:30 -0500 - -git (1:1.7.1-1.1) unstable; urgency=high - - * Non-maintainer upload. - * debian/diff/0004-Check-size-of-path-buffer-before-writing-...diff: - new, cherry-picked from 3c9d041: setup: Check size of path buffer - before writing into it (closes: #590026, CVE-2010-2542). - - -- Jonathan Nieder Sun, 25 Jul 2010 18:01:15 -0500 - -git (1:1.7.1-1) unstable; urgency=low - - * debian/diff/0003-t-t7400-submodule-basic.sh-debug-output-...diff: - remove; obsolete. - * debian/diff/0003-git-submodule.sh-properly-initialize-shell-...diff: - new; git-submodule.sh: properly initialize shell variables (closes: - #569594). - * debian/rules: no longer set ARCH='$(ARCH)' in environment for make - test. - * new upstream release. - * merge branch debian-experimental. - - -- Gerrit Pape Sun, 25 Apr 2010 23:35:50 +0000 - -git (1:1.7.0.5-2~dbg0) unstable; urgency=low - - * debian/diff/0003-t7400-submodule-basic.sh-alpha-s390-skip-...diff: - remove; more archs are affected (additionally hppa, armel). - * debian/diff/0003-t-t7400-submodule-basic.sh-debug-output-...diff: - new; t/t7400-submodule-basic.sh: debug output for t7400.24 'update - --init'. - - -- Gerrit Pape Fri, 23 Apr 2010 12:15:18 +0000 - -git (1:1.7.0.5-1) unstable; urgency=low - - * debian/git-core.postinst: new; replace /usr/share/doc/git-core with - symlink /usr/share/doc/git-core -> git on upgrade from <= 1.7.0.4-2 - (closes: #578298). - * debian/diff/0003-t7400-submodule-basic.sh-alpha-s390-skip-...diff: - new; t7400-submodule-basic.sh: alpha, s390: skip 'update --init' - test (workaround: #569594). - * debian/control: no longer Replaces, Conflicts: git-completion (thx - Jonathan Nieder, closes: #577730). - * new upstream point release. - * debian/rules: set ARCH='$(ARCH)' in environment for make test. - - -- Gerrit Pape Tue, 20 Apr 2010 23:41:04 +0000 - -git (1:1.7.1~rc1-1.1) experimental; urgency=low - - * debian/control: typo (thx Jonathan Nieder). - * debian/git-daemon-run.postinst: remove fixup for #522348. - - -- Gerrit Pape Sun, 11 Apr 2010 23:22:46 +0000 - -git (1:1.7.1~rc1-1) experimental; urgency=low - - * new upstream release candidate. - * merge branch debian-sid. - - -- Gerrit Pape Sun, 11 Apr 2010 15:28:28 +0000 - -git (1:1.7.0.4-2) unstable; urgency=low - - * debian/rules: package git: no longer install /usr/share/doc/git-core - -> git symlink; git-core: no longer install /usr/lib/git-core -> git - symlink (closes: #576906). - * debian/control: package git: Replaces:, Conflicts: git-core (<= - 1:1.7.0.4-1). - * debian/rules: make /usr/share/gitweb/index.cgi -> - ../../lib/cgi-bin/gitweb.cgi symlink relative (lintian). - * debian/control: package git-core: minor update to the long - description. - * debian/git.README.source: add note about the - mailing list. - * debian/rules: target binary-indep: add missing dependency to - git-core.deb-DEBIAN. - * debian/implicit: no longer create DEBIAN/md5sums. - * debian/rules: revert the /usr/lib/git-core -> /usr/lib/git rename - (keeping upstream's default). - - -- Gerrit Pape Sat, 10 Apr 2010 23:16:54 +0000 - -git (1:1.7.0.4-2~exp0) experimental; urgency=low - - [ Gerrit Pape ] - * debian/control, debian/rules, debian/git-core.*: change source and - binary package name from git-core to git; keep now obsolete empty - git-core package that depends on git for upgrade (see - http://lists.debian.org/debian-devel/2009/09/thrd2.html#00661). - * debian/control: package git: Replaces: git-core, Conflicts: git-core - (<= 1:1.7.0.3-1), Provides: git-core. - * debian/git.NEWS.Debian: talk about the package name change, and the - possible hazzle when upgrading with GNU Interactive Tools installed - since etch and no git-core installed. - * debian/control, debian/rules: new package git-all: dummy package - which brings in all subpackages (following upstream's RPMs). - - [ Jonathan Nieder ] - * debian/git.README.source: adjust for the package name change. - * debian/rules: install symbolic link git -> git-core in /usr/lib - to simplify upgrades. - * debian/git-daemon/run: use $(git --exec-path) instead of hard-coding - the path to the git-daemon binary. - - -- Gerrit Pape Sat, 03 Apr 2010 15:07:19 -0500 - -git-core (1:1.7.0.4-1) unstable; urgency=low - - * debian/git-daemon-run.postrm: purge: don't warn if the git-daemon - service is already removed; use -f option to userdel, on fast-purge - the log service daemon might still run for a short time (closes: - #575434). - * new upstream point release. - - -- Gerrit Pape Thu, 01 Apr 2010 20:42:19 +0000 - -git-core (1:1.7.0.3-1) unstable; urgency=low - - * debian/control: Standards-Version: 3.8.4.0. - * debian/changelog: note fixes from Jonathan Nieder in 1.7.0.2-1. - * new upstream point release. - - -- Gerrit Pape Mon, 22 Mar 2010 09:19:06 +0000 - -git-core (1:1.7.0.2-1) unstable; urgency=low - - * new upstream point release. - - [ Jonathan Nieder ] - * am: remove rebase-apply directory before gc (thx Mark Brown, - closes: #570966). - * git-imap-send: Convert LF to CRLF before storing patch to draft box - (closes: #572598). - * sha1_file: be paranoid when creating loose objects (closes: - #569505). - - -- Gerrit Pape Thu, 18 Mar 2010 20:44:12 +0000 - -git-core (1:1.7.0-1) unstable; urgency=low - - * debian/git-core.README.source: typos. - * new upstream release. - * Documentation: Update git core tutorial clarifying reference to - scripts (closes: ##560795). - * merge branch debian-experimental. - - -- Gerrit Pape Tue, 16 Feb 2010 08:51:32 +0000 - -git-core (1:1.7.0~rc2-1) experimental; urgency=low - - * new upstream release candidate. - - -- Gerrit Pape Fri, 12 Feb 2010 14:30:12 +0000 - -git-core (1:1.7.0~rc1-1) experimental; urgency=low - - * new upstream release candidate. - * debian/diff/0003-git-cvsserver-allow-regex-metacharacters...diff: - remove; applied upstream. - * debian/rules: NO_PYTHON=1. Packaging the git_remote_helpers - Python module will require more work. - * update debian/copyright (closes: #557065). - * debian/rules: set prefix=/usr when building man pages (closes: - #567404). - - -- Jonathan Nieder Sat, 30 Jan 2010 17:46:04 -0600 - -git-core (1:1.6.6.2-1) unstable; urgency=medium - - * new upstream point release. - * debian/diff/0003-git-cvsserver-allow-regex-metacharacters...diff: - remove; applied upstream. - * debian/rules: stop ignoring test suite failures on ia64, since - #563882 has been fixed. Build-Depends: and Depends: - libc6.1 (>= 2.10.2-6) [ia64] for the fix (closes: #568915). - * update debian/copyright (closes: #557065). - * debian/rules: set prefix=/usr when building man pages (closes: - #567404). - - -- Jonathan Nieder Thu, 11 Feb 2010 21:48:55 -0600 - -git-core (1:1.6.6.1-1) unstable; urgency=low - - [ Gerrit Pape ] - * new upstream point release. - * Document git-blame triple -C option (thx Ramkumar Ramachandra, - closes: #476604). - * debian/diff/0003-git-cvsserver-allow-regex-metacharacters...diff: - new; git-cvsserver: allow regex metacharacters in CVSROOT (fixes - build/selftest failure if the build directory pathname contains a +). - * debian/gitweb.apache2.conf, debian/gitweb.postinst: new; make gitweb - work out of the box with Apache (thx Charles Plessy). - * debian/gitweb.README.Debian, debian/gitweb.conf, debian/rules: make - gitweb work out of the box with Apache (thx Charles Plessy, closes: - #497809). - * debian/gitweb.conffiles: add /etc/apache2/conf.d/gitweb. - - [ Jonathan Nieder ] - * debian/rules: ignore test suite failures on ia64 (workaround: - #563882). - - -- Gerrit Pape Wed, 27 Jan 2010 13:30:29 +0000 - -git-core (1:1.6.6-1) unstable; urgency=low - - * new upstream release. - - -- Gerrit Pape Mon, 04 Jan 2010 16:01:36 +0000 - -git-core (1:1.6.6~rc2-1) experimental; urgency=low - - * new upstream release candidate. - * merge branch debian-sid. - - -- Gerrit Pape Thu, 17 Dec 2009 10:13:09 +0000 - -git-core (1:1.6.5.7-1) unstable; urgency=low - - * new upstream point release. - - -- Gerrit Pape Thu, 17 Dec 2009 09:39:55 +0000 - -git-core (1:1.6.6~rc1-1) experimental; urgency=low - - * merge branch debian-sid. - * new upstream release candidate. - - -- Gerrit Pape Fri, 04 Dec 2009 00:17:27 +0000 - -git-core (1:1.6.5.4-1) unstable; urgency=low - - * new upstream point release. - - -- Gerrit Pape Thu, 03 Dec 2009 22:48:57 +0000 - -git-core (1:1.6.6~rc0-1) experimental; urgency=low - - * new upstream release candidate. - * debian/diff/0001-bug-369742-pager.c-fallback-to-pager-...diff, - debian/diff/0002-bug-438793-494505-fallback-to-editor-...diff, - debian/diff/0004-bug-477337-git-svn.perl-fallback-to...diff: - remove; obsolete. - * debian/rules: add DEFAULT_PAGER=pager, DEFAULT_EDITOR=editor to - OPTS. - - -- Gerrit Pape Thu, 26 Nov 2009 00:17:59 +0000 - -git-core (1:1.6.5.3-1) unstable; urgency=low - - [ Tanguy Ortolo ] - * debian/git-core.README.Debian, debian/control: git-daemon-run: - document that git-daemon is not provided by this package; add hint - on how to enable git-daemon through inetd(8) (closes: #554215). - - [ Jonathan Nieder ] - * debian/rules: drop misleading PPC_SHA1, ARM_SHA1 settings (closes: - #555039). - * debian/rules: log $(CC) version, not gcc (closes: #555040). - * debian/rules: allow clean as non-root (closes: #555041). - * debian/rules: drop obsolete WITH_P4IMPORT setting (closes: - #555051). - * debian/rules: TCLTK_PATH=wish (closes: #555027). - - [ Gerrit Pape ] - * new upstream point release. - * ls-files: unbreak "ls-files -i" (closes: #553296). - * Require a struct remote in transport_get(); Allow curl helper to - work without a local repository (closes: #553507). - * help -a: do not unnecessarily look for a repository (closes: - #539273). - * thx Jonathan Nieder. - - -- Gerrit Pape Tue, 17 Nov 2009 21:01:46 +0000 - -git-core (1:1.6.5.2-1) unstable; urgency=low - - * restore temporary lost changes from version 1:1.6.3.3-2 (closes: - #530693). - * new upstream point release. - * grep: do not segfault when -f is used (closes: 551071). - - -- Gerrit Pape Mon, 26 Oct 2009 12:05:18 +0000 - -git-core (1:1.6.5-1) unstable; urgency=low - - * new upstream release. - * git-doc: html no longer uses "{plus}" where it should be "+" - (closes: #529255). - * debian/git-core.README.source: new; document how to use the - Debian package source. - * debian/implicit: update to revision 60d9070. - - -- Gerrit Pape Tue, 13 Oct 2009 00:23:00 +0000 - -git-core (1:1.6.4.3-1) unstable; urgency=low - - * new upstream release (closes: #546709). - * git-cvsserver: no longer use deprecated 'git-subcommand' commands - (closes: #536067). - * branch debian-sid: git cherry-pick 098082f, 318b847, 1f9b620 (thx - Anders Kaseorg; closes: #546499). - - -- Gerrit Pape Wed, 16 Sep 2009 11:03:45 +0000 - -git-core (1:1.6.3.3-2) unstable; urgency=low - - [ Anders Kaseorg ] - * Fix manpage formatting: set ASCIIDOC_NO_ROFF instead of - DOCBOOK_XSL_173 (based on the instructions in Documentation/Makefile) - and don’t override the internal Makefile variable ASCIIDOC_EXTRA - (closes: #530693, #521954, #533320). - - [ Gerrit Pape ] - * debian/control: Standards-Version: 3.8.2.0. - - -- Gerrit Pape Mon, 29 Jun 2009 00:06:59 +0000 - -git-core (1:1.6.3.3-1) unstable; urgency=high - - * new upstream point release. - * daemon: Strictly parse the "extra arg" part of the command - (closes: #532935; CVE-2009-2108). - * debian/rules: add NO_CROSS_DIRECTORY_HARDLINKS=1 to OPTS. - * debian/diff/0006-bug-520116-Makefile-do-not-install-cross...diff: - remove; obsolete. - - -- Gerrit Pape Tue, 23 Jun 2009 08:49:17 +0000 - -git-core (1:1.6.3.1-1) unstable; urgency=low - - * new upstream point release. - - -- Gerrit Pape Thu, 14 May 2009 21:35:01 +0000 - -git-core (1:1.6.3-1) unstable; urgency=low - - * new upstream release. - * merge branch debian-experimental. - - -- Gerrit Pape Fri, 08 May 2009 07:57:39 +0000 - -git-core (1:1.6.3~rc3-1) experimental; urgency=low - - * new upstream release candidate. - - -- Gerrit Pape Wed, 29 Apr 2009 21:58:10 +0000 - -git-core (1:1.6.3~rc1-1) experimental; urgency=low - - * new upstream release candidate. - * merge branch debian-sid. - - -- Gerrit Pape Mon, 20 Apr 2009 21:44:09 +0000 - -git-core (1:1.6.2.4-1) unstable; urgency=low - - * new upstream point release. - - -- Gerrit Pape Mon, 20 Apr 2009 20:22:02 +0000 - -git-core (1:1.6.3~rc0-1) experimental; urgency=low - - * new upstream release candidate. - * merge branch debian-sid. - - -- Gerrit Pape Tue, 14 Apr 2009 23:06:38 +0000 - -git-core (1:1.6.2.3-1) unstable; urgency=low - - * new upstream point release. - * debian/control: Standards-Version: 3.8.1.0. - * debian/control: change subversion to Subversion in description. - * debian/control: Section: vcs (except for git-doc). - - -- Gerrit Pape Tue, 14 Apr 2009 22:46:43 +0000 - -git-core (1:1.6.2.2-1) unstable; urgency=low - - * new upstream point release. - * debian/diff/0006-bug-520116-Makefile-do-not-install-cross...diff: - new; Makefile: do not install cross-directory hardlink (thx Jonathan - Nieder, closes: #520116). - * debian/git-daemon/run: run /usr/lib/git-core/git-daemon instead of - 'git daemon' (closes: #522348). - * debian/git-daemon-run.postinst: on upgrade from >> 1:1.6.0, fixup - #522348. - * debian/git-core.emacsen-startup: remove the line - '(add-to-list 'vc-handled-backends 'git)' (closes: #519728). - - -- Gerrit Pape Sun, 05 Apr 2009 20:49:25 +0000 - -git-core (1:1.6.2.1-1) unstable; urgency=low - - * new upstream point release. - * debian/git-core.emacsen-startup: no longer refer to vc-git.el - (closes: #519728). - - -- Gerrit Pape Mon, 16 Mar 2009 22:18:05 +0000 - -git-core (1:1.6.2-1) unstable; urgency=medium - - * new upstream release. - * merge branch debian-experimental. - * debian/diff/0006-Install-builtins-with-the-user-and-group-of...diff, - debian/diff/0007-git-quiltimport-preserve-standard-input-to...diff: - remove; applied upstream. - - -- Gerrit Pape Wed, 04 Mar 2009 22:44:43 +0000 - -git-core (1:1.6.2~rc2-1) experimental; urgency=low - - * merge branch debian-sid. - * new upstream release candidate. - - -- Gerrit Pape Thu, 26 Feb 2009 22:15:13 +0000 - -git-core (1:1.6.1.3-2) unstable; urgency=high - - * debian/diff/0006-Install-builtins-with-the-user-and-group-of...diff: - new from upstream git: Install builtins with the user and group of - the installing personality. - * debian/diff/0007-git-quiltimport-preserve-standard-input-to...diff: - new from upstream git: git-quiltimport: preserve standard input to - be able to read user input (closes: #515910). - - -- Gerrit Pape Thu, 26 Feb 2009 22:01:37 +0000 - -git-core (1:1.6.2~rc1-1) experimental; urgency=low - - * new upstream release candidate. - * debian/git-core.docs, debian/git-doc.docs, debian/rules: move - Documentation/RelNotes* from git-doc to the git-core package - (closes: #514866). - - -- Gerrit Pape Tue, 17 Feb 2009 20:20:03 +0000 - -git-core (1:1.6.2~rc0-1) experimental; urgency=low - - * new upstream release candidate. - * merge branch debian-sid. - - -- Gerrit Pape Tue, 10 Feb 2009 00:06:02 +0000 - -git-core (1:1.6.1.3-1) unstable; urgency=low - - * new upstream point release. - - -- Gerrit Pape Mon, 09 Feb 2009 21:31:39 +0000 - -git-core (1:1.6.1.2-1) experimental; urgency=low - - * new upstream release. - * don't fail to clone over http if connection is rate limited - (closes: #512795). - * git svn info no longer fails (closes: #499243). - * debian/rules: ASCIIDOC_EXTRA='-a asciidoc7compatible -a docbook-xsl-172' - and DOCBOOK_XSL_173=Yes when building documentation (thx Niko Tyni - for the patch, closes: #497883). - * merge branch debian-lenny. - * debian/diff/0005-gitweb-do-not-run-git-diff-that-is-Porcelain.diff: - remove; fixed upstream. - - -- Gerrit Pape Mon, 02 Feb 2009 23:26:45 +0000 - -git-core (1:1.5.6.5-3) unstable; urgency=high - - * debian/rules: no longer install symlink /etc/init.d/git-daemon -> - /usr/bin/sv (closes: #511687). - * debian/git-daemon-run.README.Debian: document how to create the - symlink manually to have an LSB compatible /etc/init.d/git-daemon - interface to control the service. - - -- Gerrit Pape Mon, 02 Feb 2009 20:56:15 +0000 - -git-core (1:1.6.0.6-1) experimental; urgency=low - - * debian/control: git-email: Recommends: libnet-smtp-ssl-perl, - libauthen-sasl-perl (thx Kees Cook, closes: #505636). - * debian/diff/0005-bug-506445-hooks-post-receive-email-set-...diff: - new; hooks/post-receive-email: set encoding to utf-8 (thx Alexander - Gerasiov, closes: #506445). - * new upstream point release (closes: #504641). - * gitweb: do not run "git diff" that is Porcelain. - - -- Gerrit Pape Sat, 20 Dec 2008 11:03:49 +0000 - -git-core (1:1.5.6.5-2) unstable; urgency=high - - * debian/diff/0005-gitweb-do-not-run-git-diff-that-is-Porcelain.diff: - new; fix possible gitweb vulnerability: calling "git diff": Jakub - says that legacy-style URI to view two blob differences are never - generated since 1.4.3. This codepath runs "git diff" Porcelain from - the gitweb, which is a no-no. It can trigger diff.external command - that is specified in the configuration file of the repository being - viewed. - - -- Gerrit Pape Wed, 17 Dec 2008 09:27:01 +0000 - -git-core (1:1.6.0.4-1) experimental; urgency=low - - * new upstream point release. - * debian/control: git-email: minor update to the long description - (thx Gerfried Fuchs, closes: #501559). - * debian/rules: TCLTK_PATH=/usr/bin/wish instead of wish8.5 in OPTS. - * debian/control: git-gui, gitk: Depends: tk (>= 8.4) instead of - tk8.5 (thx Adeodato Simó, closes: #503113). - * debian/rules: move the /usr/bin/git-cvsserver program into the - git-cvs package. - - -- Gerrit Pape Tue, 11 Nov 2008 22:36:05 +0000 - -git-core (1:1.6.0.3-1) experimental; urgency=low - - * debian/control: minor update to long descriptions (thx Reuben - Thomas, closes: #499065). - * debian/git-core.emacsen-startup: new; emacsen-startup configuration - file (thx Jari Aalto, closes: #472197). - * debian/rules: install emacsen-startup configuration file into the - git-core package (thx Eddy Mulyono, closes: #446027). - * new upstream point release. - * debian/git-core.conffiles: add /etc/emacs/site-start.d/50git-core.el - - -- Gerrit Pape Tue, 04 Nov 2008 20:26:56 +0000 - -git-core (1:1.6.0.2-1) experimental; urgency=low - - * new upstream point release. - * debian/git-core.NEWS.Debian: new; mention that most of the programs - now are installed outside the default $PATH; the "git-xyzzy" form - in scripts and on the command line is no longer supported in 1.6.0. - * debian/git-core.README.Debian: fix paths in config example (thx - Michael Biebl for the patch, closes: #498741). - * debian/git-core.README.Debian: typo (thx Vincent Bernat for the - patch, closes: #496834). - - -- Gerrit Pape Wed, 24 Sep 2008 20:55:26 +0000 - -git-core (1:1.6.0.1-1) experimental; urgency=low - - * new upstream point release (closes: #496155). - * merge branch debian-sid. - - -- Gerrit Pape Wed, 27 Aug 2008 07:53:36 +0000 - -git-core (1:1.6.0-1) experimental; urgency=low - - * new upstream release. - * svnimport: newer libsvn wants us to ask for the root with "", - not "/" (closes: #492522, #490400). - * Keep some git-* programs in $(bindir); Move all dashed-form - commands to libexecdir (closes: #461212). - * bash: Add more option completions for 'git log' (closes: - #490220). - * Fix buffer overflow in prepare_attr_stack; Fix buffer overflow - in git diff; Fix buffer overflow in git-grep (closes: #494097). - * 0002-bug-438793-git-sh-setup.sh-builtin-tag.c-fallback.diff: redo - as 0002-bug-438793-494505-fallback-to-editor-not-vi.diff (thx - Jonathan Nieder for the patch, closes: #494505). - * debian/rules: add gitexecdir=/usr/lib/git-core to OPTS; adapt - several paths (thx Jonathan Nieder for a patch, closes: #480396). - * debian/gitweb.NEWS.Debian: new; talk about files moved from - /var/www/ to /usr/share/gitweb/ (see #479479; closes: #494467). - * debian/git-daemon/run: run git daemon instead of git-daemon - (dash-less form). - * debian/git-daemon-run.postinst: add gitdaemon system user. - * debian/git-daemon/run: utilize chpst to run git daemon as user - gitdaemon (thx Daniel Kahn Gillmor, closes: #494991). - - -- Gerrit Pape Sun, 24 Aug 2008 22:31:44 +0000 - -git-core (1:1.5.6.5-1) unstable; urgency=high - - * new upstream point release. - * Fix buffer overflow in prepare_attr_stack; Fix buffer overflow - in git diff; Fix buffer overflow in git-grep (CVE-2008-3546; - closes: #494097). - * debian/diff/0005-bug-494097-CVE-2008-3546.diff: remove; obsolete. - - -- Gerrit Pape Sun, 24 Aug 2008 19:22:02 +0000 - -git-core (1:1.5.6.3-1.1) unstable; urgency=high - - * Non-maintainer upload by the Security Team. - * Fix various stack-based buffer overflows when processing overly long - repository pathnames which can be exploited to execute arbitrary code if - a victim is tricked into using git-grep or git-diff on a crafted - repository (CVE-2008-3546; Closes: #494097). - - -- Nico Golde Sat, 09 Aug 2008 13:53:13 +0200 - -git-core (1:1.5.6.3-1) unstable; urgency=low - - * new upstream point release. - * debian/diff/0005-git-svn.perl-workaround-assertions-in-svn...diff: - remove; applied upstream (opens: #490400). - * debian/control: Standards-Version: 3.8.0.1. - - -- Gerrit Pape Thu, 17 Jul 2008 07:40:08 +0000 - -git-core (1:1.5.6.2-1) unstable; urgency=low - - * new upstream point release (closes: #489431). - * debian/copyright: apply patch from Ansgar Burchardt: adopt proposed - machine-readable format; clarify some license information (thx, - closes: #488351). - * debian/rules: package gitweb: install gitweb.css, git-favicon.png, - git-logo.png into /usr/share/gitweb/ instead of /var/www/ (closes: - #479479). - * debian/control: package git-arch: no longer Suggests: bazaar - (closes: #486726). - * debian/diff/0005-git-svn.perl-workaround-assertions-in-svn...diff: - new; git-svn.perl: workaround assertions in svn library 1.5.0 - (closes: #489108). - - -- Gerrit Pape Sun, 06 Jul 2008 18:35:27 +0000 - -git-core (1:1.5.6-1) unstable; urgency=low - - * new upstream release. - * merge branch debian-experimental. - - -- Gerrit Pape Thu, 19 Jun 2008 07:38:31 +0000 - -git-core (1:1.5.6~rc3-1) experimental; urgency=low - - * debian/git-daemon-run.postrm: remove log files on purge. - * new upstream release candidate. - * debian/control: package git-core: no longer Depends: cpio, no - longer Recommends: curl. - - -- Gerrit Pape Sun, 15 Jun 2008 11:14:49 +0000 - -git-core (1:1.5.6~rc2-1) experimental; urgency=low - - * new upstream release candidate. - * merge branch debian-sid. - * debian/rules: do not build manpages twice (thx Jonathan Nieder). - - -- Gerrit Pape Mon, 09 Jun 2008 12:02:43 +0000 - -git-core (1:1.5.5.4-1) unstable; urgency=low - - * new upstream point release. - * debian/rules: enable DOCBOOK_XSL_172 build variable, fixing man page - breakage (thx Jonathan Nieder, closes: #476634). - * debian/control: Build-Depends: docbook-xsl (>> 1.72) (thx Jonathan - Nieder). - - -- Gerrit Pape Mon, 09 Jun 2008 11:51:19 +0000 - -git-core (1:1.5.6~rc1-1) experimental; urgency=low - - * new upstream release candidate. - * git-svn fails in prop_walk if $self->{path} is not empty (closes: - 477393). - * gitweb: Fix "next" link on bottom of page (closes: #481902). - * merge branch debian-sid. - * debian/rules: add THREADED_DELTA_SEARCH=1 to OPTS (closes: #483534). - - -- Gerrit Pape Thu, 05 Jun 2008 10:14:14 +0000 - -git-core (1:1.5.5.3-1) unstable; urgency=low - - * new upstream point release. - * commit --interactive: properly update the index before commiting - (closes: #480429). - * debian/diff/0005-git-bisect.sh-don-t-accidentally-override...diff: - remove; applied upstream. - * debian/diff/0005-bug-477337-git-svn.perl-fallback-to-pager...diff: - new; git-svn.perl: fallback to 'pager' not 'less' if PAGER is unset - (closes: #477337). - - -- Gerrit Pape Wed, 28 May 2008 19:32:57 +0000 - -git-core (1:1.5.6~rc0-1) experimental; urgency=low - - * merge branch debian-sid. - * new upstream release candidate. - * debian/diff/0004-gitweb-fallback-to-system-wide-config-file...diff: - remove; fixed upstream. - * debian/diff/0005-git-bisect.sh-don-t-accidentally-override...diff: - remove; applied upstream. - - -- Gerrit Pape Mon, 26 May 2008 16:53:38 +0000 - -git-core (1:1.5.5.2-1) unstable; urgency=low - - * new upstream point release. - * diff-options.txt: document the new "--dirstat" option (closes: - #476437). - * debian/diff/0005-git-bisect.sh-don-t-accidentally-override...diff: - new: git-bisect.sh: don't accidentally override existing branch - "bisect" (closes: #478647). - - -- Gerrit Pape Mon, 26 May 2008 16:41:45 +0000 - -git-core (1:1.5.5.1-1) unstable; urgency=low - - * new upstream point release. - - -- Gerrit Pape Mon, 21 Apr 2008 18:24:34 +0000 - -git-core (1:1.5.5-1) unstable; urgency=low - - * new upstream release. - * gitk: Fix changing colors through Edit->Preferences (closes: #472615). - * Revert "gitweb: Add 'status_str' to parse_difftree_raw_line output" - (closes: #469083). - * merge branch debian/experimental. - - -- Gerrit Pape Tue, 08 Apr 2008 20:26:25 +0000 - -git-core (1:1.5.5~rc3-2) experimental; urgency=low - - * debian/diff/0004-gitweb-fallback-to-system-wide-config-file-if-defaul.diff: - amend: properly apply GITWEB_CONFIG_SYSTEM to gitweb.cgi. - - -- Gerrit Pape Fri, 04 Apr 2008 20:40:48 +0000 - -git-core (1:1.5.5~rc3-1) experimental; urgency=low - - * new upstream release candidate. - * debian/diff/0004-gitweb-fallback-to-system-wide-config-file-if-defaul.diff: - new: gitweb: fallback to system-wide config file if default config does - not exist (closes: #450592). - * debian/rules: remove GITWEB_CONFIG=/etc/gitweb.conf from OPTS. - - -- Gerrit Pape Thu, 03 Apr 2008 19:43:33 +0000 - -git-core (1:1.5.5~rc2-1) experimental; urgency=low - - * new upstream release candidate. - * t9600-cvsimport.sh: set HOME before checking for cvsps availability - (closes: #471969). - * imap-send: properly error out if imap.host is not set in config - (closes: #472632). - * merge branch debian-sid. - - -- Gerrit Pape Fri, 28 Mar 2008 08:53:30 +0000 - -git-core (1:1.5.4.5-1) unstable; urgency=low - - * new upstream point release (closes: #473071). - - -- Gerrit Pape Fri, 28 Mar 2008 08:26:39 +0000 - -git-core (1:1.5.5~rc1-1) experimental; urgency=low - - * new upstream release candidate. - - -- Gerrit Pape Sun, 23 Mar 2008 11:55:21 +0000 - -git-core (1:1.5.5~rc0-1) experimental; urgency=low - - * new upstream release candidate. - * git-pull documentation: warn about the option order (closes: #463853). - * hash-object: cleanup handling of command line options (closes: - #464432). - * debian/diff/0004-gitk-properly-deal-with-tag-names-containing-sl.diff: - remove; applied upstream. - - -- Gerrit Pape Wed, 19 Mar 2008 07:45:01 +0000 - -git-core (1:1.5.4.4-1) unstable; urgency=low - - * new upstream point release. - * templates/Makefile: don't depend on local umask setting (closes: - #467518). - * Fix random crashes in http_cleanup() (closes: #468836). - * send-email: fix In-Reply-To regression (closes: #468153). - * git-merge.sh: better handling of combined --squash,--no-ff,--no-commit - options (closes: #468568). - - -- Gerrit Pape Mon, 10 Mar 2008 10:38:51 +0000 - -git-core (1:1.5.4.3-1) unstable; urgency=low - - * new upstream point release. - * git-clone.sh: properly configure remote even if remote's head is - dangling (closes: #466581). - * debian/diff/0004-gitk-properly-deal-with-tag-names-containing-sl.diff: - new: from upstream master: gitk: properly deal with tag names containing / - (slash) (closes: #464104). - * debian/git-daemon-run.postrm: adapt paths in /var/. - - -- Gerrit Pape Sun, 24 Feb 2008 16:19:02 +0000 - -git-core (1:1.5.4.2-2) unstable; urgency=low - - * debian/rules: git-daemon-run: no longer include symlinks for ./supervise/ - subdirectories, update-service now takes care of this. - * debian/git-daemon-run.postinst: remove ad re-add git-daemon service on - upgrade from <= 1.5.4.2-1. - - -- Gerrit Pape Mon, 18 Feb 2008 22:22:14 +0000 - -git-core (1:1.5.4.2-1) unstable; urgency=low - - * new upstream point release. - * cvsimport: have default merge regex also match beginning of commit - message (thx Frédéric Brière, closes: #463468). - * builtin-commit: remove .git/SQUASH_MSG upon successful commit (closes: - #464656). - * debian/rules: change TCLTK_PATH to /usr/bin/wish8.5 in OPTS. - * debian/control: Build-Depends: tcl8.5; git-gui, gitk: Depends: tk8.5 - (closes: #456423). - * debian/git-daemon-run.postinst, debian/git-daemon-run.postrm, - debian/git-daemon-run.prerm: use runit's update-service program to - add/remove the git daemon service, instead of dealing with symlinks in - /var/service/ directly. - * debian/control: package git-daemon: Depends: runit (>= 1.8.0-2) (1st - version that provides the update-service program). - - -- Gerrit Pape Sun, 17 Feb 2008 18:48:00 +0000 - -git-core (1:1.5.4.1-1) unstable; urgency=medium - - * debian/control: Build-Depends: cvsps (for selftests, thx Marco Rodrigues, - closes: #463896). - * new upstream point release. - - -- Gerrit Pape Mon, 11 Feb 2008 12:00:03 +0000 - -git-core (1:1.5.4-1) unstable; urgency=low - - * merge branch debian-experimental. - * new upstream release. - * debian/git-core.README.Debian: add Alias'es for git-favicon.png and - git-logo.png to the VirtualHost example (thx Frederic Briere, closes: - #463732). - * debian/rules: target build-arch-stamp: re-run selftests with --verbose - on test failures. - - -- Gerrit Pape Sun, 03 Feb 2008 05:01:16 +0000 - -git-core (1:1.5.4~rc5-1) experimental; urgency=low - - * new upstream release candidate. - - -- Gerrit Pape Mon, 28 Jan 2008 11:01:08 +0000 - -git-core (1:1.5.4~rc4-1) experimental; urgency=low - - * new upstream release candidate. - * debian/diff/0003-bug-448655-check-etc-mailname-if-author-email-is-un.diff: - adapt; don't warn if /etc/mailname does not exist (closes: #461844). - * debian/rules: install /usr/share/gitk/ into the gitk package, not - git-core. - - -- Gerrit Pape Mon, 21 Jan 2008 21:15:21 +0000 - -git-core (1:1.5.4~rc3-1) experimental; urgency=low - - * merge branch debian-sid. - * new upstream release candidate. - * "git pull --tags": error out with a better message (closes: #456035). - * gitk: use user-configured background in view definition dialog - (closes: #457124). - * debian/control: Build-Depends: cvs, libdbd-sqlite3-perl (for selftests). - - -- Gerrit Pape Sat, 12 Jan 2008 15:09:23 +0000 - -git-core (1:1.5.3.8-1) unstable; urgency=low - - * debian/control: for all packages: Suggests: git-doc instead of - Recommends: (thx Andrew Moise, closes: #455369). - * debian/control: add Vcs-Git: http://smarden.org/git/git.git/. - * new upstream point release. - - -- Gerrit Pape Tue, 08 Jan 2008 21:01:35 +0000 - -git-core (1:1.5.4~rc2-1) experimental; urgency=low - - * new upstream release candidate. - * shortlog manpage documentation: work around asciidoc markup issues - (closes: #447911). - * Fix $EDITOR regression introduced by rewrite in C (closes: #446845). - - -- Gerrit Pape Thu, 27 Dec 2007 08:45:01 +0000 - -git-core (1:1.5.4~rc1-1) experimental; urgency=low - - * new upstream release candidate. - * gitweb: Teach "a=blob" action to be more lenient about blob/file mime - type (closes: #435610). - - -- Gerrit Pape Thu, 20 Dec 2007 09:07:10 +0000 - -git-core (1:1.5.4~rc0-1) experimental; urgency=low - - * new upstream release candidate. - * build with correct version information (on amd64, closes: #454935, - #454408). - * git-reset: add -q option to operate quietly (closes: #444933). - * gitk: disable colours when calling git log (closes: #454420). - * "git svnimport" was removed in favor of "git svn" (closes: #436930, - #447325, #447965, #451037). - * git-commit: allow grouping of short options (closes: #407241). - * debian/diff/0004-contrib-hooks-post-receive-email-make-subject-prefix.diff, - debian/diff/0005-Don-t-cache-DESTDIR-in-perl-perl.mak.diff: remove; - applied upstream. - * debian/rules: install git-gui's lib/ directory plus subdirectory - properly. - * debian/control: Build-Depends: gettext. - - -- Gerrit Pape Thu, 13 Dec 2007 14:08:45 +0000 - -git-core (1:1.5.3.7-1) unstable; urgency=low - - * new upstream point release. - * debian/diff/0005-Don-t-cache-DESTDIR-in-perl-perl.mak.diff: new; don't - cache DESTDIR in perl/perl.mak (#452077). - * debian/rules: remove $(MAKE) -C perl clean to remove the perl/perl.mak - again, this is now handled through debian/diff/0005 (thx Pierre - Habouzit, #452077). - - -- Gerrit Pape Mon, 3 Dec 2007 10:17:11 +0000 - -git-core (1:1.5.3.6-1.1) unstable; urgency=low - - * Non-maintainer upload: Gerrit is currently changing home, and this bug is - preventing people from installing git, I took the initiative to fix it - before his return. - * debian/rules: force a $(MAKE) -C perl clean to remove the perl/perl.mak - that remembers our DESTDIR and makes perl modules be installed in - debian/git-core/ in the install-indep target again - (closes: #452077, #452078, #452080, #452111, #452324). - - -- Pierre Habouzit Thu, 22 Nov 2007 00:40:08 +0100 - -git-core (1:1.5.3.6-1) unstable; urgency=low - - * debian/implicit: add proper dependencies to support 'parallel build' - through make -j (thx Daniel Schepler for the patch). - * debian/rules: support 'nocheck' in DEB_BUILD_OPTIONS to skip running - the selftests. - * debian/diff/0003-bug-448655-check-etc-mailname-if-author-email-is-un.diff: - new; check /etc/mailname if author email is unknown (closes: #448655). - * debian/gitweb.docs: new; install gitweb/README. - * new upstream point release. - * git-cvsimport: really convert underscores in branch names to dots with - -u (closes: #446495). - * git-mailsplit: with maildirs not only process cur/, but also new/ - (closes: #447396). - * debian/diff/0004-contrib-hooks-post-receive-email-make-subject-prefix.diff: - new; cherry-pick'ed from master: contrib/hooks/post-receive-email: make - subject prefix configurable (closes: #428418). - - -- Gerrit Pape Mon, 19 Nov 2007 12:32:11 +0000 - -git-core (1:1.5.3.5-1) unstable; urgency=low - - * new upstream point release. - * git-config: handle --file option with relative pathname properly; - git-config: print error message if the config file cannot be read; - git-config: don't silently ignore options after --list (closes: - #445208). - - -- Gerrit Pape Thu, 01 Nov 2007 08:35:46 +0000 - -git-core (1:1.5.3.4-1) unstable; urgency=low - - * new upstream point release (closes: #445188). - - -- Gerrit Pape Thu, 04 Oct 2007 08:27:01 +0000 - -git-core (1:1.5.3.3-1) unstable; urgency=low - - * new upstream point release. - - -- Gerrit Pape Sun, 30 Sep 2007 09:25:06 +0000 - -git-core (1:1.5.3.2-1) unstable; urgency=low - - * new upstream point release. - * git-svn: fix "Malformed network data" with svn:// servers (closes: - #430091, #436142). - * git-commit: Allow partial commit of file removal (closes: #437817). - * git-gui: lib/index.tcl: handle files with % in the filename properly - (closes: #441167). - * git-clone: improve error message if curl program is missing or not - executable (closes: #440976). - * debian/git-daemon-run.postinst: use 'sv -v term git-daemon' instead of - 'sv restart git-daemon' to restart git-daemon service if it was running. - * debian/control: git-core: no longer Suggests: cogito, which was removed. - * debian/diff/genindex.diff: apply and remove. - * debian/gitweb.conf: comment out $home_link, and set to gitweb.cgi's - default (thx Ansgar Burchardt for the patch, closes: 441694). - - -- Gerrit Pape Thu, 20 Sep 2007 07:28:41 +0000 - -git-core (1:1.5.3.1-1) unstable; urgency=low - - * new upstream point release. - * debian/control: git-daemon-run: improve long description (closes: - #440699). - * debian/git-daemon-run.README.Debian: improve. - * debian/control: git-svn: improve long description. - * debian/control: git-cvs: improve long description. - * debian/control: git-core: improve long description (closes: #412560). - - -- Gerrit Pape Tue, 04 Sep 2007 18:18:33 +0000 - -git-core (1:1.5.3-1) unstable; urgency=low - - * merge branch debian-experimental. - * new upstream release. - * debian/control: git-email: move libemail-valid-perl from Depends: to - Recommends: (thx Uwe Kleine-Koenig, closes: #439902). - * debian/control: git-email: no longer Depends: libmail-sendmail-perl (thx - Uwe Kleine-Koenig). - - -- Gerrit Pape Sun, 02 Sep 2007 16:41:54 +0000 - -git-core (1:1.5.3~rc7-1) experimental; urgency=low - - * new upstream release candidate. - * debian/diff/0002-git-merge-do-up-to-date-check-also-for-all-strategie.diff: - remove; included upstream. - - -- Gerrit Pape Wed, 29 Aug 2007 12:22:16 +0000 - -git-core (1:1.5.3~rc6-1) experimental; urgency=low - - * new upstream release candidate. - * git-am: initialize variable $resume on startup (closes: #435807). - * debian/diff/0002-git-merge-do-up-to-date-check-also-for-all-strategie.diff: - new; http://article.gmane.org/gmane.comp.version-control.git/55981. - * debian/diff/0003-git-sh-setup.sh-fallback-to-editor-not-vi-if-VI.diff: - new; git-sh-setup.sh: fallback to 'editor' not 'vi' if $VISUAL and $EDITOR - are unset (thx Mike Hommey, closes: #438793). - * merge branch debian-sid. - - -- Gerrit Pape Sun, 26 Aug 2007 09:54:16 +0000 - -git-core (1:1.5.2.5-2) unstable; urgency=low - - * debian/git-core.conffiles: new; add /etc/bash_completion.d/git. - - -- Gerrit Pape Sun, 26 Aug 2007 09:49:39 +0000 - -git-core (1:1.5.2.5-1) unstable; urgency=low - - * debian/control: fix typo in Build-Depends: libcurl4-gnutls-dev | - libcurl3-gnutls-dev (thx Mikael Eriksson, closes: #433196). - * new upstream point release. - * debian/rules: add TCLTK_PATH=/usr/bin/wish8.4 to OPTS (closes: #438662). - * dbian/control: git-core: Depends: cpio (closes: #438057). - * debian/git-core.README.Debian: fix typos (closes: #438932). - * debian/versions.upstream, debian/changelog.upstream: adapt. - * debian/rules, debian/control: install git-completion.bash from contrib as - /etc/bash_completion.d/git; git-core: Conflicts:, Provides:, Replaces: - git-completion (closes: #437532, thx Sebastian Harl). - - -- Gerrit Pape Sat, 25 Aug 2007 17:56:20 +0000 - -git-core (1:1.5.3~rc4-1) experimental; urgency=low - - * new upstream release candidate. - - -- Gerrit Pape Sat, 04 Aug 2007 13:02:05 +0000 - -git-core (1:1.5.3~rc3-1) experimental; urgency=low - - * new upstream release candidate. - * debian/versions.upstream, debian/changelog.upstream: adapt. - - -- Gerrit Pape Fri, 27 Jul 2007 11:13:52 +0000 - -git-core (1:1.5.3~rc2-1) experimental; urgency=low - - * new upstream release candidate. - * debian/diff/????-Pack-objects-properly-initialize-the-depth-value.diff: - remove; obsolete. - * debian/control, debian/rules: remove git-p4 package again, moved into - contrib/ upstream; see /usr/share/doc/git-core/contrib/p4import/. - * debian/versions.upstream, debian/changelog.upstream: adapt. - - -- Gerrit Pape Fri, 20 Jul 2007 08:47:45 +0000 - -git-core (1:1.5.3~rc1-1) experimental; urgency=low - - * new upstream release candidate. - * git-commit: don't add multiple Signed-off-by: from the same identity - (closes: #430851). - * Fix core.sharedRepository = 2 (closes: #432698). - * merge branch debian-sid. - * debian/versions.upstream, debian/changelog.upstream: adapt. - * debian/diff/0002-gitk-properly-resolve-ambiguity-if-argument-is-both.diff: - remove; doesn't apply anymore. - * debian/diff/0002-Pack-objects-properly-initialize-the-depth-value.diff: - new; on upstream advice. - - -- Gerrit Pape Sat, 14 Jul 2007 11:45:27 +0000 - -git-core (1:1.5.2.4-1) unstable; urgency=low - - * new upstream point release. - * debian/rules: build documentation with ASCIIDOC8=YesPlease (closes: - #432560). - * debian/control: Build-Depends: asciidoc (>> 8.0.0). - * debian/diff/????-git-gui-properly-popup-error-if-gitk-should-be-start.diff: - remove; merged upstream. - * debian/control: Build-Depends: libcurl4-gnutls-dev | libcurl3-gnutsl-dev - (closes: #432812). - * debian/versions.upstream, debian/changelog.upstream: adapt. - - -- Gerrit Pape Fri, 13 Jul 2007 19:13:38 +0000 - -git-core (1:1.5.3~rc0-1) experimental; urgency=low - - * new upstream release candidate. - * debian/changelog.upstream.sh: run git shortlog with option --no-merges. - * debian/versions.upstream, debian/changelog.upstream: update. - * debian/diff/0003-git-svn-trailing-slash-in-prefix-is-mandatory-with.diff, - debian/diff/0004-git-cvsimport-force-checkout-of-working-tree-after-i.diff: - remove; applied upstream. - * debian/diff/00*.diff: adapt. - * debian/rules: put git-gui, git-citool man pages into package git-gui. - - -- Gerrit Pape Tue, 03 Jul 2007 10:01:12 +0000 - -git-core (1:1.5.2.3-1) unstable; urgency=low - - * new upstream point release. - * debian/control: package git-gui: Replaces: git-core (<< 1:1.5.2.2-3) - (thx Frank Lichtenheld, closes: #431481). - * debian/versions.upstream, debian/changelog.upstream: update. - - -- Gerrit Pape Tue, 03 Jul 2007 08:26:11 +0000 - -git-core (1:1.5.2.2-3) unstable; urgency=low - - * debian/rules: move /usr/share/git-gui/ from git-core package into - git-gui package (thx Ansgar Burchardt, closes: #430530). - * debian/diff/0004-git-cvsimport-force-checkout-of-working-tree-after-i.diff: - new; git-cvsimport: force checkout of working tree after initial import - (closes: #430903). - * debian/diff/0005-git-gui-properly-popup-error-if-gitk-should-be-start.diff: - new; git-gui: properly popup error if gitk should be started but is not - installed (#429810). - * debian/control: git-gui: Recommends: gitk (closes: #429810). - * debian/rules: workaround #427907: compile with -O0 instead of -O2 on hppa - (#429389). - - -- Gerrit Pape Fri, 29 Jun 2007 12:54:39 +0000 - -git-core (1:1.5.2.2-2) unstable; urgency=low - - * debian/control: all Architecture: all packages: Depends: git-core (>> - ${source:Upstream-Version}, git-core (<< ${source:Upstream-Version}-.) - instead of (= ${source:Version}) to support binNMUs (closes: #423041, - #430128). - - -- Gerrit Pape Sat, 23 Jun 2007 14:02:36 +0000 - -git-core (1:1.5.2.2-1) unstable; urgency=low - - * new upstream point release. - * Fix typo in remote branch example in git user manual (closes: #427502). - * debian/diff/0003-git-branch-track-fix-tracking-branch-computation.diff: - remove; applied upstream. - * debian/versions.upstream: new; ordered list of upstream versions, - starting with 1.0.0. - * debian/changelog.upstream.sh: new; create changelog.upstream from git - shortlog using debian/versions.upstream. - * debian/changelog.upstream: re-created through changelog.upstream.sh. - * debian/diff/0003-git-svn-trailing-slash-in-prefix-is-mandatory-with.diff: - new; git-svn: trailing slash in prefix is mandatory with --branches/-b - (closes: #429443). - - -- Gerrit Pape Tue, 19 Jun 2007 17:32:30 +0000 - -git-core (1:1.5.2.1-2) unstable; urgency=low - - * debian/diff/0003-git-branch-track-fix-tracking-branch-computation.diff: - new; from upstream master: git-branch --track: fix tracking branch - computation. - - -- Gerrit Pape Fri, 8 Jun 2007 09:04:47 +0000 - -git-core (1:1.5.2.1-1) unstable; urgency=low - - * new upstream point release. - * Create a new manpage for the gitignore format, and reference it - elsewhere (thx Josh Triplett, closes: #427078). - * debian/diff/0002-gitk-properly-resolve-ambiguity-if-argument-is-both.diff: - new; properly resolve ambiguity if argument is both, revision and - filename (closes: #425491). - * debian/control: git-core: Conflicts: git (<< 4.3.20-11) (/usr/bin/git - transition). - * debian/git-daemon-run.README.Debian: new (#422139). - * debian/control: all Architecture: all packages: Depends: git-core - (= ${source:Version}) instead of (>= ...); this makes it no longer - support binNMUs (closes: #425494, reopens: #423041). - - -- Gerrit Pape Sun, 03 Jun 2007 10:09:53 +0000 - -git-core (1:1.5.2-1) unstable; urgency=low - - * merge branch debian-experimental. - * new upstream release. - * gitweb: choose appropriate view for file type if a= parameter missing - (closes: #410465). - * git fetch -q is supported (closes: #423165). - * /usr/bin/git transition (thx Ian Beckwith!). - * debian/git-core.preinst: new; remove /usr/bin/git alternative if - upgrading from versions older than 1:1.5.2~rc3-2. - * debian/git-core.prerm, debian/git-core.postinst: remove; no longer - handle /usr/bin/git alternative through update-alternatives. - * debian/rules: no longer install git program as git-scm. - - -- Gerrit Pape Wed, 30 May 2007 12:38:45 +0000 - -git-core (1:1.5.2~rc3-2) experimental; urgency=low - - * debian/diff/0000-maint-branch-from-20070514.diff: remove; obsolete. - * debian/control: package git-p4: Section: contrib/devel (closes: - #422755). - * debian/control: package git-p4: Depends: git-core (>= ${source:Version}) - instead of (= ${Source-Version}) (to support binNMUs). - - -- Gerrit Pape Tue, 15 May 2007 21:33:06 +0000 - -git-core (1:1.5.1.4-2) unstable; urgency=low - - * debian/diff/0000-maint-branch-from-20070514.diff: new; snapshot upstream - maint branch 20070514: - * includes git-svn fixes (closes: #423599, #423226). - * deian/rules: reverse order when applying diffs (fix typo). - * debian/control: all Architecture: all packages: Depends: git-core (>= - ${source:Version}) instead of (= ${Source-Version}) (to support binNMUs, - closes: #423041). - - -- Gerrit Pape Mon, 14 May 2007 13:15:50 +0000 - -git-core (1:1.5.2~rc3-1) experimental; urgency=low - - * new upstream release candidate. - * debian/diff/0002-Optimize-directory-listing-with-pathspec-limiter.diff: - remove; included upstream. - * debian/control: Build-Depends: tcl8.4 (for gitgui). - * debian/rules: add symlink /etc/init.d/git-daemon -> /usr/bin/sv to - git-daemon-run package (#422139). - - -- Gerrit Pape Mon, 14 May 2007 10:10:02 +0000 - -git-core (1:1.5.1.4-1) unstable; urgency=medium - - * new upstream point release. - * debian/diff/pager-vs-less.diff: rename to - 0001-pager.c-fallback-to-pager-not-less-if-PAGER-is.diff; adapt. - * debian/diff/0002-Optimize-directory-listing-with-pathspec-limiter.diff: - new: Optimize directory listing with pathspec limiter (closes: #420671). - * debian/git-daemon-run.postinst: restart git-daemon service if it was - running. - - -- Gerrit Pape Wed, 09 May 2007 08:48:50 +0000 - -git-core (1:1.5.2~rc2-1) experimental; urgency=low - - * new upstream release candidate. - - -- Gerrit Pape Mon, 07 May 2007 18:02:53 +0000 - -git-core (1:1.5.2~rc1-1) experimental; urgency=low - - * new upstream release candidate. - * debian/control, debian/rules: new package git-p4: tools for importing - development history from perforce repositories. - * debian/rules: add WITH_P4IMPORT=1 to OPTS; no longer install - git-p4import.py into /usr/share/doc/git-core/contrib/; add OPTS to - make clean in target clean:; add PYTHON_PATH=/usr/bin/python to OPTS. - - -- Gerrit Pape Tue, 01 May 2007 12:28:15 +0000 - -git-core (1:1.5.1.3-1) unstable; urgency=low - - * new upstream point release. - * git-add tried to optimize by finding common leading directories - across its arguments but botched, causing very confused behaviour - (closes: #420671). - * Documentation/git-reset.txt: suggest git commit --amend in example - (closes: #420112). - * unofficial rpm.spec file shipped with git was letting ETC_GITCONFIG - set to /usr/etc/gitconfig. Tweak the official Makefile to make it - harder for distro people to make the same mistake, by setting the - variable to /etc/gitconfig if prefix is set to /usr (closes: - #420675). - * debian/changelog.upstream: upstream changes taken from mailing list - announcement. - - -- Gerrit Pape Tue, 01 May 2007 08:59:06 +0000 - -git-core (1:1.5.1.2-1) unstable; urgency=low - - * new upstream point release. - * debian/changelog.upstream: upstream changes taken from mailing list - announcement. - - -- Gerrit Pape Sun, 22 Apr 2007 13:31:05 +0000 - -git-core (1:1.5.1.1-1) unstable; urgency=low - - * new upstream point release. - * debian/changelog.upstream: upstream changes taken from mailing list - announcement. - * debian/diff/0010-rename-contrib-hooks-post-receieve-email-to-contrib.diff: - remove; applied upstream. - - -- Gerrit Pape Thu, 12 Apr 2007 09:05:44 +0000 - -git-core (1:1.5.1-1) unstable; urgency=low - - * new upstream release. - * git-svn got almost a rewrite (closes: #416372). - * debian/diff/git-cvsserver-update-hook.diff: remove; included upstream. - * debian/diff/Documentation-git-svnimport.txt-fix-typo.diff, - debian/diff/http-fetch-don-t-use-double-slash-as-directory-sepa.diff, - debian/diff/Documentation-git-rev-parse.txt-fix-example-in-SPEC.diff: - remove; applied upstream. - * debian/diff/GNU-Hurd.diff: remove; obsolete. - * debian/git-daemon-run.postrm: check for deluser being available, if - not, print warning and don't remove system user (closes: #416755). - * debian/changelog.upstream: upstream changes taken from mailing list - announcement, and git shortlog. - * debian/diff/0010-rename-contrib-hooks-post-receieve-email-to-contrib.diff: - new; rename contrib/hooks/post-receieve-email to contrib/hooks/post- - receive-email. - - -- Gerrit Pape Wed, 4 Apr 2007 11:56:18 +0000 - -git-core (1:1.5.0.6-1) unstable; urgency=low - - * new upstream point release. - * debian/diff/http-fetch-don-t-use-double-slash-as-directory-sepa.diff: - new, cherry-pick'ed from upstream master: http-fetch: don't use - double-slash as directory separator in URLs (closes: #409887). - * debian/diff/Documentation-git-svnimport.txt-fix-typo.diff: new: - Documentation/git-svnimport.txt: fix typo. - * debian/diff/Documentation-git-rev-parse.txt-fix-example-in-SPEC.diff: - new Documentation/git-rev-parse.txt: fix example in SPECIFYING RANGES - (closes: #404795). - * debian/changelog.upstream: upstream changes taken from mailing list - announcements. - - -- Gerrit Pape Thu, 29 Mar 2007 10:51:00 +0000 - -git-core (1:1.5.0.5-1) unstable; urgency=low - - * new upstream point release. - * debian/rules: make sure subdirectories of /usr/share/doc/git-core/ are - mode 0755 (closes: #415328); remove .gitignore file(s) from - /usr/share/doc/git-core/ (closes: #413913). - * debian/control: git-svn: Depends: libterm-readkey-perl (thx Pierre - Habouzit, closes: #415475). - * debian/changelog.upstream: upstream changes taken from mailing list - announcements. - - -- Gerrit Pape Wed, 21 Mar 2007 17:02:27 +0000 - -git-core (1:1.5.0.3-1) unstable; urgency=low - - * new upstream point release. - * debian/diff/cvsexportcommit-.msg.diff: remove; applied upstream. - * debian/git-core.docs, debian/git-doc.docs: add RelNotes. - * debian/changelog.upstream: upstream changes taken from mailing list - announcements. - - -- Gerrit Pape Mon, 5 Mar 2007 19:44:05 +0000 - -git-core (1:1.5.0.2-1) unstable; urgency=low - - * new upstream point release. - * debian/control: git-core: Conflicts: qgit (<< 1.5.5) (closes: #412452). - * debian/changelog.upstream: upstream changes taken from mailing list - announcements. - * debian/diff/cvsexportcommit-.msg.diff: new; don't cleanup .msg if not - yet committed to cvs (closes: #412732). - - -- Gerrit Pape Wed, 28 Feb 2007 15:50:53 +0000 - -git-core (1:1.5.0.1-1) unstable; urgency=low - - * new upstream point release. - * debian/diff/git-cvsserver-update-hook.diff: new from upstream pu branch: - Have git-cvsserver call hooks/update before really altering the ref. - * debian/control: git-cvs: Depends: libdbd-sqlite3-perl (git-cvsserver). - - -- Gerrit Pape Sun, 25 Feb 2007 11:38:34 +0000 - -git-core (1:1.5.0-1) experimental; urgency=low - - * new upstream release. - * debian/diff/archimport-empty-dir.diff: remove; applied upstream. - * debian/diff/pager-vs-less.diff, debian/diff/Add-install-lib-target.diff: - adapt. - * debian/control: new package git-gui, the git graphical user interface; - git-core: no longer Depends:, Build-Depends: rcs; git-core: Suggests: - git-gui. - * debian/rules: new package git-gui. - * debian/changelog.upstream: upstream changes taken from mailing list - announcements and git shortlog. - * debian/git-daemon/run: don't limit git-daemon's memory resources. - * debian/control, debian/rules: remove git-core-dev package again, - libgit.a is not a publically usable/useful library at this moment, as - its internal API is not cast in stone yet. - * debian/diff/Add-install-lib-target.diff: remove; there's no git-core-dev - package. - - -- Gerrit Pape Fri, 16 Feb 2007 07:18:44 +0000 - -git-core (1:1.5.0~rc3-1) experimental; urgency=low - - * new upstream release candidate. - * debian/diff/Add-install-lib-target.diff: new; add install-lib target to - install libgit.a library plus header files (thx Luca Falavigna). - * debian/rules: new package git-core-dev; remove obsolete - WITH_SEND_EMAIL=1, OPTIMIZE="..." from $(OPTS); remove - WITH_OWN_SUBPROCESS_PY=1 from $(OPTS), it's no longer necessary (thx - Luca Falavigna; closes: #403731); make git-p4import.pl available through - /usr/share/doc/git-core/contrib/ (closes: #403387); minor cleanup. - * debian/control: new package git-core-dev (thx Luca Falavigna; closes: - #407722); no longer Build-Depends: python; git-core: no longer Recommends: - python, Suggests: git-core-dev; update short and long descriptions - (closes: #406323); git-arch: Depends: tla, instead of Suggests:. - * debian/diff/GNU-Hurd.diff: adapt. - * debian/diff/archimport-empty-dir.diff: new; git-archimport: initial import - needs empty directory (closes: #400508). - * debian/gitweb.README.Debian: typo. - - -- Gerrit Pape Sat, 3 Feb 2007 09:32:48 +0000 - -git-core (1:1.4.4.4-1) unstable; urgency=low - - * new upstream release, important fixes: - * pack-check.c::verify_packfile(): don't run SHA-1 update on huge data. - * Fix infinite loop when deleting multiple packed refs. - * diff --check: fix off by one error. - * debian/diff/0001-spurious-.sp-in-manpages.diff: remove; included in - upstream version. - * debian/changelog.upstream: upstream changes taken from mailing list - announcement. - - -- Gerrit Pape Tue, 9 Jan 2007 19:43:56 +0000 - -git-core (1:1.4.4.3-1) unstable; urgency=medium - - * new upstream release (closes: #404796); important fixes: - * Make sure the empty tree exists when needed in merge-recursive; the - error message may make the user think that their database is corrupt - when its actually not. - * Don't use memcpy when source and dest. buffers may overlap. - * cvsserver: Avoid miscounting bytes in Perl v5.8.x; this breaks the - counting of bytes for the CVS protocol, resulting in the client - expecting less data than we actually send, and storing truncated files. - * debian/diff/0001-spurious-.sp-in-manpages.diff: new from upstream git; - work around spurious .sp in manpages (closes: #388370). - * debian/changelog.upstream: upstream changes taken from mailing list - announcement. - - -- Gerrit Pape Fri, 29 Dec 2006 07:38:15 +0000 - -git-core (1:1.4.4.2-1) unstable; urgency=low - - * new upstream release. - * fixes FTBFS on m68k (thx Roman Zippel, closes: #402022). - * 0001-archive-zip-don-t-use-sizeof-struct.diff, - 0002-git-svn-error-out-from-dcommit-on-a-parent-less-commit.diff, - 0003-git-svn-correctly-handle-revision-0-in-SVN-repositories.diff, - 0004-git-svn-preserve-uncommitted-changes-after-dcommit.diff, - 0005-Increase-length-of-function-name-buffer.diff: remove; obsolete. - * debian/changelog.upstream: upstream changes taken from mailing list - announcements and git log | git shortlog. - - -- Gerrit Pape Fri, 8 Dec 2006 19:13:49 +0000 - -git-core (1:1.4.4.1-1) unstable; urgency=low - - * new upstream release (closes: #400191). - * 0001-archive-zip-don-t-use-sizeof-struct.diff: new from upstream git; - replaces debian/diff/not-packed-structs.diff. - * 0002-git-svn-error-out-from-dcommit-on-a-parent-less-commit.diff, - 0003-git-svn-correctly-handle-revision-0-in-SVN-repositories.diff, - 0004-git-svn-preserve-uncommitted-changes-after-dcommit.diff, - 0005-Increase-length-of-function-name-buffer.diff: new from upstream - git. - * debian/diff/genindex.diff: new; support subdirs in gitweb example index - generator (thx David Nusinow; closes: #400284). - * debian/diff/GNU-Hurd.diff, debian/diff/pager-vs-less.diff: adapt. - - -- Gerrit Pape Sun, 26 Nov 2006 14:31:39 +0000 - -git-core (1:1.4.4-2) unstable; urgency=low - - * debian/diff/not-packed-structs.diff: new; don't use sizeof(struct ...), - size doesn't match on arm (fixes selftests failure on arm). - - -- Gerrit Pape Wed, 22 Nov 2006 23:31:11 +0000 - -git-core (1:1.4.4-1) unstable; urgency=low - - * new upstream release (closes: #399575). - * debian/changelog.upstream: upstream changes taken from mailing list - announcements. - * debian/control: Build-Depends: unzip (for selftests). - - -- Gerrit Pape Tue, 21 Nov 2006 09:43:37 +0000 - -git-core (1:1.4.3.5-1) unstable; urgency=low - - * new upstream release. - * debian/changelog.upstream: upstream changes taken from mailing list - announcements. - - -- Gerrit Pape Mon, 13 Nov 2006 17:46:50 +0000 - -git-core (1:1.4.3.3-2) unstable; urgency=medium - - * debian/git-daemon-run.postinst: don't make the log service system user - gitlog member of group adm, but nogroup; gitlog's home directory is - /nonexistent (thx Florian Weimer, closes: #396687). - * debian/git-daemon/log/run: make /var/log/git-daemon log directory mode - 2750, owner gitlog:adm. - * debian/changelog.upstream: upstream changes taken from mailing list - announcements. - - -- Gerrit Pape Mon, 6 Nov 2006 20:12:08 +0000 - -git-core (1:1.4.3.3-1) unstable; urgency=low - - * new upstream release. - * debian/diff/0001-Set-HOME-for-selftests.diff: remove; applied upstream. - * debian/control: git-core: Depends: libdigest-sha1-perl (closes: #395304, - thx Ichthyostega). - - -- Gerrit Pape Tue, 31 Oct 2006 07:31:21 +0000 - -git-core (1:1.4.3.2-1) unstable; urgency=low - - * new upstream release. - * debian/diff/gitweb.conf.diff: remove; obsolete. - * debian/changelog.upstream: upstream changes taken from mailing list - announcements. - * debian/rules: add 'GITWEB_CONFIG=/etc/gitweb.conf mandir=/usr/share/man - OPTIMIZE="-O2 -g -Wall" INSTALLDIRS=vendor' to build OPTS, adapt paths; - git-arch: don't include git-archive, git-upload-archive; gitweb: install - git-logo.png, git-favicon.png; git-core: properly install new Git.pm - plus man page. - * debian/diff/0001-Set-HOME-for-selftests.diff: new; set $HOME for - selftests (fixes build/selftest failures). - * debian/control: git-core: Depends: liberror-perl. - - -- Gerrit Pape Tue, 24 Oct 2006 16:32:35 +0000 - -git-core (1:1.4.2.3-2) unstable; urgency=low - - * debian/control: new package git-daemon-run: provide a git-daemon - service; git-core: no longer Suggests: runit, Depends: adduser, the - git-daemon-run package now Depends: runit, adduser. - * debian/debian/git-core.postinst, debian/git-daemon-run.postrm, - debian/git-daemon-run.prerm: new; manage gitlog user and git-daemon - service (closes: #388144). - * debian/git-core.postinst: no longer adduser gitlog, git-daemon-run - package does now. - * debian/git-core.postrm: remove; obsolete. - * debian/rules: install git-daemon service directory in the new - git-daemon-run package instead of the git-core package. - * debian/git-core.conffiles: rename to debian/git-daemon-run.conffiles. - * debian/git-core.README.Debian: adapt. - * debian/control: git-core: Suggests: git-daemon-run. - - -- Gerrit Pape Sun, 8 Oct 2006 09:29:50 +0000 - -git-core (1:1.4.2.3-1) unstable; urgency=medium - - * new upstream release. - * debian/changelog.upstream: upstream changes taken from mailing list - announcements. - * debian/diff/t3403-skip-3-7.diff: remove; git-am is fixed upstream. - * debian/gitweb.conf: add $stylesheet = "/gitweb.css" (thx Christian - Kujau, closes: #383065). - - -- Gerrit Pape Sun, 8 Oct 2006 07:31:03 +0000 - -git-core (1:1.4.2.1-1) unstable; urgency=low - - * new upstream release (closes: #386820, #387405). - * debian/changelog.upstream: upstream changes taken from mailing list - announcements. - * debian/diff/GNU-Hurd.diff: new; make the build process detect and - support the Debian GNU/Hurd architecture (thx Cyril Brulebois, closes: - #379841). - * debian/diff/GNU-kFreeBSD.diff: remove; applied upstream. - * debian/rules: gitweb: install gitweb.css into /var/www/ instead of - /usr/share/doc/gitweb/ (thx Matthijs Melchior, closes: #383065). - * debian/gitweb.docs: remove; obsolete. - * debian/examples/index.aux-generation: example script to generate an - optional index.aux file for the use with gitweb (thx Matthew Wilcox, - #383219). - * debian/gitweb.examples: new; install debian/examples/index.aux-generation - (#383219). - * debian/git-core.README.Debian: new; hints on how to set up a - git.example.org server providing git://, rsync://, http:// access to - repositories from Matthew Wilcox (thx!, closes: #383219). - * debian/gitweb.README.Debian: cleanup; refer to git-core.README.Debian. - * debian/control: git-svn: Depends: libsvn-perl | libsvn-core-perl (thx - Peter Samuelson); git-core, git-doc: Suggests: gitweb; gitweb: - Recommends: git-doc. - * debian/diff/pager-vs-less.diff, debian/diff/gitweb.conf.diff: adapt. - * debian/git-daemon/: new; git-daemon service directory for the use with - runit. - * debian/control: Build-Depends: subversion, libsvn-perl | libsvn-core-perl - (for git-svn selftests); git-core: Suggests: runit, Depends: adduser. - * debian/diff/t3403-skip-3-7.diff: new; skip selftests 3,7 in t3403 as - they fail without a terminal connected. - * debian/git-core.conffiles: new; add /etc/sv/git-daemon/run, - /etc/sv/git-daemon/log/run. - - -- Gerrit Pape Fri, 15 Sep 2006 12:46:58 +0000 - -git-core (1:1.4.1.1-1) unstable; urgency=low - - * new upstream release. - * debian/diff/GNU-kFreeBSD.diff: new; make the build process detect and - support the Debian GNU/kFreeBSD architecture (thx Petr Salinger, closes: - #380209). - - -- Gerrit Pape Sat, 29 Jul 2006 15:31:04 +0000 - -git-core (1:1.4.1-2) unstable; urgency=low - - * adopt package gitweb, now included in git-core upstream source (thx - Andres Salomon): - * debian/control, debian/rules: build gitweb package. - * debian/copyright: adapt. - * debian/gitweb.README.Debian, debian/gitweb.conf, debian/gitweb.docs: - new; taken from Andres' gitweb package. - * debian/diff/gitweb.conf.diff: new; adapt Andres' gitweb.conf.patch. - * debian/gitweb.conffiles: new; /etc/gitweb.conf. - * debian/changelog: use epoch 1 to supersede gitweb-264 package version. - * debian/rules: set DESTDIR in environment, not build flags. - - -- Gerrit Pape Thu, 27 Jul 2006 21:44:06 +0000 - -git-core (1.4.1-1) unstable; urgency=low - - * new upstream release. - * debian/changelog.upstream: upstream changes taken from mailing list - announcement. - * debian/rules: user same build flags and prefix to $(MAKE) in build - and install target to prevent rebuild in install target. - - -- Gerrit Pape Tue, 11 Jul 2006 21:38:33 +0000 - -git-core (1.4.0-1) unstable; urgency=low - - * new upstream release. - * debian/changelog.upstream: new; upstream changes taken from mailing - list announcement. - * debian/rules: install debian/changelog.upstream as upstream changelog. - * debian/diff/pager-vs-less.diff: adapt. - * debian/control: Standards-Version: 3.7.2.0. - - -- Gerrit Pape Wed, 14 Jun 2006 17:04:56 +0000 - -git-core (1.3.3-2) unstable; urgency=medium - - * debian/control: git-core: Depends: perl-modules (closes: #369737). - * debian/diff/pager-vs-less.diff: new; fallback to `pager` not `less` - if $PAGER is unset (closes: #369742). - - -- Gerrit Pape Sat, 10 Jun 2006 11:18:48 +0000 - -git-core (1.3.3-1) unstable; urgency=low - - * new upstream release. - - -- Gerrit Pape Thu, 25 May 2006 10:46:00 +0000 - -git-core (1.3.2-1) unstable; urgency=low - - * new upstream release. - - -- Gerrit Pape Wed, 10 May 2006 20:41:39 +0000 - -git-core (1.3.1-1) unstable; urgency=low - - * new upstream release (closes: #364678). - * debian/rules: install contrib/ directory into /usr/share/doc/git-core/. - - -- Gerrit Pape Mon, 1 May 2006 13:01:42 +0000 - -git-core (1.2.6-1) unstable; urgency=low - - * new upstream release. - * debian/control: git-cvs: Depends: cvsps (>> 2.1-0). - - -- Gerrit Pape Sun, 16 Apr 2006 14:37:53 +0000 - -git-core (1.2.4-1) unstable; urgency=low - - * new upstream release (closes: #354563). - - -- Gerrit Pape Fri, 3 Mar 2006 21:33:58 +0000 - -git-core (1.2.1-1) unstable; urgency=low - - * new upstream release (closes: #353041). - * debian/control: git-core: Recommends: ssh-client instead of - openssh-client (closes: #350708). - - -- Gerrit Pape Thu, 16 Feb 2006 09:33:42 +0000 - -git-core (1.1.5-1) unstable; urgency=high - - * new upstream release. - * checkout: do not make a temporary copy of symlink target. - If the index records an insanely long symbolic link, copying - into the temporary would overflow the buffer (noticed by Mark - Wooding). (closes: #350274). - - -- Gerrit Pape Sat, 28 Jan 2006 20:16:44 +0000 - -git-core (1.1.3-1) unstable; urgency=low - - * new upstream release. - - -- Gerrit Pape Mon, 16 Jan 2006 10:19:37 +0000 - -git-core (1.0.8-1) unstable; urgency=low - - * new upstream point release. - * debian/diff/t6001-rev-lisge-order.sh.diff: remove; applied upstream. - * debian/control: Build-Depends: libcurl3-gnutls-dev | libcurl3-dev, - python, asciidoc (>> 7.0.2-3) (ease backport to sarge, thx Norbert - Tretkowski, closes: #344929). - - -- Gerrit Pape Mon, 9 Jan 2006 19:19:36 +0000 - -git-core (1.0.6-1) unstable; urgency=low - - * new upstream point release. - * debian/diff/t6001-rev-list-merge-order.sh.diff: new: fix skipping - merge-order test with NO_OPENSSL=1. - * debian/rules: re-enable git-rev-list --merge-order selftests. - * debian/control: git-svn: Depends: libwww-perl (closes: #345045). - - -- Gerrit Pape Mon, 2 Jan 2006 20:25:57 +0000 - -git-core (1.0.5-1) unstable; urgency=low - - * new upstream point release. - * debian/rules: don't take upstream changelog from upstream - debian/changelog. - * debian/changelog.upstream: remove again. - - -- Gerrit Pape Tue, 27 Dec 2005 13:25:53 +0000 - -git-core (1.0.3-1) unstable; urgency=low - - * new upstream point release. - * debian/changelog.upstream: new: upstream changelog taken from upstream - debian/changelog. - * debian/rules: install debian/changelog.upstream as upstream changelog; - remove obsolete VERSION variable. - - -- Gerrit Pape Fri, 23 Dec 2005 14:58:14 +0000 - -git-core (1.0.0-1) unstable; urgency=medium - - * new upstream release: GIT 1.0.0. - - -- Gerrit Pape Wed, 21 Dec 2005 16:17:18 +0000 - -git-core (0.99.9n-1) unstable; urgency=low - - * new upstream version: GIT 0.99.9n aka 1.0rc6. - * debian/rules: rename git program in git-core package to git-scm, - handle /usr/bin/git program through update-alternatives (as suggested - by Ian Beckwith, see #342363). - * debian/control: git-core: Conflicts: git (<< 4.3.20-8) (closes: - #342363). - * debian/git-core.postinst, debian/git-core.prerm: new: run - update-alternatives --install /usr/bin/git git /usr/bin/git-scm with - priority 70 on configure, and --remove on remove respectively. - - -- Gerrit Pape Thu, 15 Dec 2005 11:24:51 +0000 - -git-core (0.99.9m-1) unstable; urgency=low - - * new upstream version: GIT 0.99.9m aka 1.0rc5. - * sets PYTHONPATH for selftests (fixes autobuild test failures). - * switch from tarball-in-tarball approach to original upstream tarball. - * debian/changelog: add changelog history, Junio C Hamano, Ryan Anderson, - Eric Biederman previously were maintaining this package unofficially. - * debian/control: Build-Depends: rcs (for selftests); git-core: - Recommends: patch, less, Suggests: cogito; git-arch: Suggests: tla, - bazzar; git-cvs: Depends: cvsps, Suggests: cvs; git-svn: Depends: - libsvn-core-perl (closes:#342617), Suggests: subversion; git-email: - Depends: libmail-sendmail-perl, libemail-valod-perl; update short - description (lots taken from upstream unofficial package, thx). - * debian/git-core.docs, debian/git-doc.docs: adapt. - * debian/rules: adapt; remove target unpack; add target patch; adapt - target clean. - - -- Gerrit Pape Wed, 14 Dec 2005 19:48:41 +0000 - -git-core (0.99.9l-1) unstable; urgency=low - - * new upstream version. - * debian/rules: apply diffs with patch -p1. - * debian/control, debian/rules: split off git-arch, git-cvs, git-svn, - git-email packages, as suggested by upstream: - http://article.gmane.org/gmane.comp.version-control.git/13185 - * debian/git-doc.docs: get docs from temporary install directory; - include *.txt docs. - * debian/control: git-doc: Section: doc; Suggests: git-core, git-arch, - git-cvs, git-svn, git-email, gitk; git-core: Suggests: git-arch, - git-cvs, git-svn, git-email, gitk. - - -- Gerrit Pape Mon, 5 Dec 2005 18:04:37 +0000 - -git-core (0.99.9k-1) unstable; urgency=low - - * new upstream version. - * debian/implicit: update to revision 1.11. - * debian/git-doc.docs: add git/Documentation/howto, - git/Documentation/technical (closes: #341178). - - -- Gerrit Pape Tue, 29 Nov 2005 21:45:53 +0000 - -git-core (0.99.9j-1) unstable; urgency=low - - * initial version. - * debian/control: git-core: Replaces: cogito (<< 0.16rc2-0); cogito >= - 0.16rc2-0 no longer includes the git core components, but depends on - the git-core package (see #338789). - - -- Gerrit Pape Fri, 18 Nov 2005 22:26:36 +0000 - -git-core (0.99.9j-0) unstable; urgency=low - - * GIT 0.99.9j aka 1.0rc3 - - -- Junio C Hamano Wed, 16 Nov 2005 20:39:55 -0800 - -git-core (0.99.9i-0) unstable; urgency=low - - * GIT 0.99.9i aka 1.0rc2 - - -- Junio C Hamano Mon, 14 Nov 2005 18:38:27 -0800 - -git-core (0.99.9h-0) unstable; urgency=low - - * GIT 0.99.9h - - -- Junio C Hamano Fri, 11 Nov 2005 22:33:18 -0800 - -git-core (0.99.9g-0) unstable; urgency=low - - * GIT 0.99.9g - - -- Junio C Hamano Wed, 9 Nov 2005 21:01:55 -0800 - -git-core (0.99.9f-0) unstable; urgency=low - - * GIT 0.99.9f - - -- Junio C Hamano Tue, 8 Nov 2005 01:21:52 -0800 - -git-core (0.99.9e-0) unstable; urgency=low - - * GIT 0.99.9e - - -- Junio C Hamano Sun, 6 Nov 2005 18:37:18 -0800 - -git-core (0.99.9d-0) unstable; urgency=low - - * GIT 0.99.9d - - -- Junio C Hamano Sat, 5 Nov 2005 11:46:37 -0800 - -git-core (0.99.9c-0) unstable; urgency=low - - * GIT 0.99.9c - - -- Junio C Hamano Thu, 3 Nov 2005 15:44:54 -0800 - -git-core (0.99.9b-0) unstable; urgency=low - - * GIT 0.99.9b - - -- Junio C Hamano Tue, 1 Nov 2005 21:39:39 -0800 - -git-core (0.99.9a-0) unstable; urgency=low - - * GIT 0.99.9a - - -- Junio C Hamano Sun, 30 Oct 2005 15:03:32 -0800 - -git-core (0.99.9.GIT-2) unstable; urgency=low - - * Build Dependency did not include libexpat-dev. - - -- Junio C Hamano Sun, 13 Nov 2005 01:55:34 -0800 - -git-core (0.99.9.GIT-1) unstable; urgency=low - - * Do not scatter txt and html documentation into feature - subpackages. Do place man pages into them. - * Capture more cvs stuff into git-cvs package. - - -- Junio C Hamano Tue, 8 Nov 2005 01:19:06 -0800 - -git-core (0.99.9.GIT-0) unstable; urgency=low - - * Test Build. - - -- Junio C Hamano Sat, 5 Nov 2005 11:18:13 -0800 - -git-core (0.99.9-1) unstable; urgency=low - - * Split the git-core binary package into core, doc, and foreign SCM - interoperability modules. - - -- Junio C Hamano Sat, 5 Nov 2005 11:18:13 -0800 - -git-core (0.99.9-0) unstable; urgency=low - - * GIT 0.99.9 - - -- Junio C Hamano Sat, 29 Oct 2005 14:34:30 -0700 - -git-core (0.99.8-0) unstable; urgency=low - - * GIT 0.99.8 - - -- Junio C Hamano Sun, 2 Oct 2005 12:54:26 -0700 - -git-core (0.99.7-0) unstable; urgency=low - - * GIT 0.99.7 - - -- Junio C Hamano Sat, 10 Sep 2005 18:36:39 -0700 - -git-core (0.99.6-0) unstable; urgency=low - - * GIT 0.99.6 - - -- Junio C Hamano Wed, 24 Aug 2005 23:09:35 -0700 - -git-core (0.99.5-1) unstable; urgency=low - - * Enable git-send-email on Debian. There is no reason to shy - away from it, since we have the necessary Perl modules available. - - -- Junio C Hamano Thu, 25 Aug 2005 14:16:59 -0700 - -git-core (0.99.5-0) unstable; urgency=low - - * GIT 0.99.5 - - -- Junio C Hamano Wed, 10 Aug 2005 22:05:00 -0700 - -git-core (0.99.4-4) unstable; urgency=low - - * Mark git-tk as architecture neutral. - - -- Junio C Hamano Fri, 12 Aug 2005 13:25:00 -0700 - -git-core (0.99.4-3) unstable; urgency=low - - * Split off gitk. - * Do not depend on diff which is an essential package. - * Use dh_movefiles, not dh_install, to stage two subpackages. - - -- Matthias Urlichs Thu, 11 Aug 2005 01:43:24 +0200 - -git-core (0.99.4-2) unstable; urgency=low - - * Git 0.99.4 official release. - - -- Junio C Hamano Wed, 10 Aug 2005 15:00:00 -0700 - -git-core (0.99.4-1) unstable; urgency=low - - * Pass prefix down to the submake when building. - - -- Junio C Hamano Sat, 6 Aug 2005 13:00:00 -0700 - -git-core (0.99-2) unstable; urgency=low - - * Conflict with the GNU Interactive Tools package, which also installs - /usr/bin/git. - * Use the Mozilla SHA1 code and/or the PPC assembly in preference to - OpenSSL. This is only a partial fix for the license issues with OpenSSL. - * Minor tweaks to the Depends. - - -- Ryan Anderson Sat, 23 Jul 2005 14:15:00 -0400 - -git-core (0.99-1) unstable; urgency=low - - * Update deb package support to build correctly. - - -- Ryan Anderson Thu, 21 Jul 2005 02:03:32 -0400 - -git-core (0.99-0) unstable; urgency=low - - * Initial deb package support - - -- Eric Biederman Tue, 12 Jul 2005 10:57:51 -0600 diff --git a/debian/changelog.upstream b/debian/changelog.upstream index ae3794a4..b22e60d6 100644 --- a/debian/changelog.upstream +++ b/debian/changelog.upstream @@ -1,3 +1,1532 @@ +Version v2.53.0; changes since v2.53.0-rc2: +------------------------------------------- + +Aindriú Mac Giolla Eoin (2): + l10n: ga.po: Update Irish translation for Git 2.53 + l10n: ga.po: Fix git-po-helper warnings + +Alexander Shopov (1): + l10n: bg.po: Updated Bulgarian translation (6091t) + +Bagas Sanjaya (1): + l10n: po-id for 2.53 + +Carlo Marcelo Arenas Belón (1): + RelNotes: fully spell negation + +Emir SARI (1): + l10n: tr: Update Turkish translations + +Jean-Noël Avila (1): + l10n: fr: v2.53 + +Jiang Xin (3): + l10n: zh_CN: fix inconsistent use of standard vs. wide colons + l10n: zh_CN: updated translation for 2.53 + l10n: zh_CN: standardize glossary terms + +Junio C Hamano (3): + RelNotes: a few spelling fixes + RelNotes: correct "fast-import" option name + Git 2.53 + +Peter Krefting (1): + l10n: sv.po: Update Swedish translation + +Yi-Jyun Pan (1): + l10n: zh_TW.po: update Git 2.53 translation + + +Version v2.53.0-rc2; changes since v2.53.0-rc1: +----------------------------------------------- + +Alexander Shopov (2): + git-gui i18n: Update Bulgarian translation (557t) + git-gui i18n: Update Bulgarian translation (558t) + +Bill Zissimopoulos (1): + mingw: compute the correct size for symlinks in `mingw_lstat()` + +D. Ben Knoble (1): + replay: drop rev-list formatting options from manual + +Jean-Noël Avila (1): + lint-gitlink: preemptively ignore all /ifn?def|endif/ macros + +Jiang Xin (1): + help: report on whether or not gettext is enabled + +Johannes Schindelin (4): + mingw: try to create symlinks without elevated permissions + mingw: emulate `stat()` a little more faithfully + mingw: special-case index entries for symlinks with buggy size + ci(*-leaks): skip the git-svn tests to save time + +Johannes Sixt (1): + git-gui: mark *.po files at any directory level as UTF-8 + +Junio C Hamano (5): + ci: skip CVS and P4 tests in leaks job, too + A few on top of -rc1 + A bit more before -rc2 + Revert "Merge branch 'cs/rebased-subtree-split'" + Git 2.53-rc2 + +Karsten Blees (14): + mingw: don't call `GetFileAttributes()` twice in `mingw_lstat()` + mingw: implement `stat()` with symlink support + mingw: drop the separate `do_lstat()` function + mingw: let `mingw_lstat()` error early upon problems with reparse points + mingw: teach dirent about symlinks + mingw: factor out the retry logic + mingw: change default of `core.symlinks` to false + mingw: add symlink-specific error codes + mingw: handle symlinks to directories in `mingw_unlink()` + mingw: support renaming symlinks + mingw: allow `mingw_chdir()` to change to symlink-resolved directories + mingw: implement `readlink()` + mingw: implement basic `symlink()` functionality (file symlinks only) + mingw: add support for symlinks to directories + +Kristoffer Haugsbakk (1): + .mailmap: fix and expand mappings for Jean-Noël Avila + +Patrick Steinhardt (5): + builtin/pack-objects: exclude promisor objects with "--stdin-packs" + repack-geometry: extract function to compute repacking split + repack-promisor: extract function to finalize repacking + repack-promisor: extract function to remove redundant packs + builtin/repack: handle promisor packs with geometric repacking + +Phillip Wood (1): + mailmap: add an entry for Phillip Wood + +Pushkar Singh (1): + Documentation/config: fix replacement for --get-urlmatch + +Ramsay Jones (2): + t9700/test.pl: fix path type expectation on cygwin + t0610-reftable-basics: mitigate a flaky test on cygwin + +René Scharfe (11): + environment: move access to core.maxTreeDepth into repo settings + tree: add repo_parse_tree*() + add-interactive: use repo_parse_tree_indirect() + bloom: use repo_parse_tree() + delta-islands: use repo_parse_tree() + pack-bitmap-write: use repo_parse_tree() + path-walk: use repo_parse_tree_gently() + tree: use repo_parse_tree() + tree: stop using the_repository + cocci: convert parse_tree functions to repo_ variants + cocci: remove obsolete the_repository rules + +Sam Bostock (1): + doc: fix `update-ref` `symref-create` formatting + +Taylor Blau (2): + t/t5319-multi-pack-index.sh: drop early 'test_done' + midx-write.c: assume checksum-invalid MIDXs require an update + +Tian Yuchen (1): + t1005: modernize "! test -f" to "test_path_is_missing" + + +Version v2.53.0-rc1; changes since v2.53.0-rc0: +----------------------------------------------- + +Andrew Chitester (1): + t1420: modernize the lost-found test + +Colin Stagner (1): + contrib/subtree: detect rewritten subtree commits + +Derrick Stolee (1): + builtin.h: update documentation + +Elijah Newren (1): + fsck: snapshot default refs before object walk + +Jeff King (3): + t/perf/perf-lib: fix assignment of TEST_OUTPUT_DIRECTORY + t/perf/run: preserve GIT_PERF_* from environment + cat-file: only use bitmaps when filtering + +Johannes Schindelin (3): + mingw: do resolve symlinks in `getcwd()` + init: do parse _all_ core.* settings early + strbuf_readlink(): support link targets that exceed 2*PATH_MAX + +Julia Evans (4): + doc: git-reset: reorder the forms + doc: git-reset: clarify intro + doc: git-reset: clarify `git reset [mode]` + doc: git-reset: clarify `git reset ` + +Junio C Hamano (3): + Revert "Merge branch 'ar/run-command-hook'" + Merge a handful more topics after -rc0 + Git 2.53-rc1 + +K Jayatheerth (1): + t7101: modernize test path checks + +KJ Tsanaktsidis (1): + http-backend: write newlines to stderr when responding with errors + +Karsten Blees (2): + strbuf_readlink(): avoid calling `readlink()` twice in corner-cases + trim_last_path_component(): avoid hard-coding the directory separator + +Kristoffer Haugsbakk (6): + doc: patch-id: don’t use semicolon between bullet points + doc: patch-id: capitalize Git version + patch-id: use “patch ID” throughout + doc: patch-id: use definite article for the result + doc: patch-id: spell out the git-diff-tree(1) form + doc: patch-id: --verbatim locks in --stable + +Michael Lyons (2): + doc: blame-options: convert to new doc format + doc: git-blame: convert to new doc format + +Patrick Steinhardt (34): + packfile: create store via its owning source + packfile: pass source to `prepare_pack()` + packfile: refactor kept-pack cache to work with packfile stores + packfile: refactor misleading code when unusing pack windows + packfile: move packfile store into object source + packfile: only prepare owning store in `packfile_store_get_packs()` + packfile: only prepare owning store in `packfile_store_prepare()` + packfile: inline `find_kept_pack_entry()` + packfile: refactor `find_pack_entry()` to work on the packfile store + packfile: move MIDX into packfile store + object-file: always set OI_LOOSE when reading object info + packfile: always declare object info to be OI_PACKED + packfile: extend `is_delta` field to allow for "unknown" state + packfile: always populate pack-specific info when reading object info + packfile: disentangle return value of `packed_object_info()` + packfile: skip unpacking object header for disk size requests + packfile: drop repository parameter from `packed_object_info()` + refs/files: simplify iterating through root refs + refs/files: move fsck functions into global scope + refs/files: remove `refs_check_dir` parameter + refs/files: remove useless indirection + refs/files: extract function to check single ref + refs/files: improve error handling when verifying symrefs + refs/files: perform consistency checks for root refs + fsck: drop unused fields from `struct fsck_ref_report` + refs/files: extract generic symref target checks + refs/files: introduce function to perform normal ref checks + refs/reftable: adapt includes to become consistent + refs/reftable: extract function to retrieve backend for worktree + refs/reftable: fix consistency checks with worktrees + refs/reftable: introduce generic checks for refs + builtin/fsck: move generic object ID checks into `refs_fsck()` + builtin/fsck: move generic HEAD check into `refs_fsck()` + builtin/fsck: drop `fsck_head_link()` + +Pushkar Singh (1): + t1410: use test helpers in reflog rewind test + +Torsten Bögershausen (2): + utf8.c: prepare workaround for iconv under macOS 14/15 + utf8.c: enable workaround for iconv under macOS 14/15 + +brian m. carlson (1): + gitfaq: document using stash import/export to sync working tree + + +Version v2.53.0-rc0; changes since v2.52.0: +------------------------------------------- + +Aaron Plattner (2): + object: apply skip_hash and discard_tree optimizations to unknown blobs too + packfile: skip hash checks in add_promisor_object() + +Adrian Ratiu (3): + run-command: add first helper for pp child states + reference-transaction: use hook API instead of run-command + hook: allow overriding the ungroup option + +Antonin Delpeuch (2): + xdiff: add 'minimal' to XDF_DIFF_ALGORITHM_MASK + blame: make diff algorithm configurable + +Christian Couder (3): + fast-import: refactor finalize_commit_buffer() + commit: refactor verify_commit_buffer() + fast-import: add 'strip-if-invalid' mode to --signed-commits= + +D. Ben Knoble (1): + rust: build correctly without GNU sed + +David Macek (1): + wincred: avoid memory corruption + +Derrick Stolee (6): + scalar: annotate config file with "set by scalar" + scalar: use index.skipHash=true for performance + scalar: remove stale config values + scalar: alphabetize and simplify config + scalar: document config settings + diff: avoid segfault with freed entries + +Deveshi Dwivedi (1): + t5403: use test_path_is_file instead of test -f + +Elijah Newren (5): + t6429: update comment to mention correct tool + merge-ort: remove debugging crud + merge-ort: fix failing merges in special corner case + Documentation/git-replay.adoc: fix errors around revision range + merge-ort: fix corner case recursive submodule/directory conflict handling + +Emily Shaffer (8): + run-command: add stdin callback for parallelization + hook: provide stdin via callback + hook: convert 'post-rewrite' hook in sequencer.c to hook API + transport: convert pre-push to hook API + run-command: allow capturing of collated output + hooks: allow callers to capture output + receive-pack: convert update hooks to new API + receive-pack: convert receive hooks to hook API + +Ezekiel Newren (10): + doc: define unambiguous type mappings across C and Rust + xdiff: use ptrdiff_t for dstart/dend + xdiff: make xrecord_t.ptr a uint8_t instead of char + xdiff: use size_t for xrecord_t.size + xdiff: use unambiguous types in xdl_hash_record() + xdiff: split xrecord_t.ha into line_hash and minimal_perfect_hash + xdiff: make xdfile_t.nrec a size_t instead of long + xdiff: make xdfile_t.nreff a size_t instead of long + xdiff: change rindex from long to size_t in xdfile_t + xdiff: rename rindex -> reference_index + +Greg Funni (4): + win32: return error if SleepConditionVariableCS fails + win32: pthread_cond_init should return a value + repository: remove duplicate free of cache->squash_msg + refs: dereference the value of the required pointer + +Jean-Noël Avila (11): + doc: convert git fetch to synopsis style + doc: convert git pull to synopsis style + doc: convert git push to synopsis style + doc: pull-fetch-param typofix + doc: fix asciidoc markup issues in several files + doc: correct minor wording issues + doc: fix t0450-txt-doc-vs-help to select only first synopsis block + doc: convert git-status to synopsis style + doc: convert git-status tables to AsciiDoc format + doc: convert git stage to use synopsis block + doc: convert git-remote to synopsis style + +Jeff King (16): + attr: avoid recursion when expanding attribute macros + read-cache: drop submodule check from add_to_cache() + compat/mmap: mark unused argument in git_munmap() + pack-bitmap: handle name-hash lookups in incremental bitmaps + Makefile: turn on NO_MMAP when building with ASan + cache-tree: avoid strtol() on non-string buffer + fsck: assert newline presence in fsck_ident() + fsck: avoid strcspn() in fsck_ident() + fsck: remove redundant date timestamp check + fsck: avoid parse_timestamp() on buffer that isn't NUL-terminated + t: enable ASan's strict_string_checks option + unit-test: ignore --no-chain-lint + ci(windows-meson-test): handle options and output like other test jobs + test-mktemp: plug memory and descriptor leaks + t5551: handle trailing slashes in expected cookies output + t5563: add missing end-of-line in HTTP header + +Jiang Xin (2): + t/unit-tests: add UTF-8 width tests for CJK chars + builtin/repo: fix table alignment for UTF-8 characters + +Johannes Schindelin (18): + make strip: include `scalar` + cmake: stop trying to build the reftable and xdiff libraries + mingw: avoid the comma operator + ci: bump actions/setup-go from 5 to 6 + ci(dockerized): do show the result of failing tests again + last-modified: support sparse checkouts + t9700: accommodate for Windows paths + apply: symbolic links lack a "trustable executable bit" + mingw: special-case `open(symlink, O_CREAT | O_EXCL)` + t0001: handle `diff --no-index` gracefully + t0301: another fix for Windows compatibility + t0600: fix incomplete prerequisite for a test case + t1006: accommodate for symlink support in MSYS2 + t1305: skip symlink tests that do not apply to Windows + t6423: introduce Windows-specific handling for symlinking to /dev/null + t7800: work around the MSYS path conversion on Windows + test_detect_ref_format: fix comment + .mailmap: replace Karsten Blees' default address + +Johannes Sixt (4): + Revert "gitk: Only restore window size from ~/.gitk, not position" + gitk: persist position and size of the Tags and Heads window + gitk: fix a 'continue' statement outside a loop to 'return' + gitk: show unescaped file names on 'rename' and 'copy' lines + +Julia Evans (3): + doc: add an explanation of Git's data model + doc: remove stray text in Git data model + doc: git-pull: fix 'git --rebase abort' typo + +Junio C Hamano (45): + t7004: do not chdir around in the main process + .gitattributes: remove misspelled no-op whitespace attribute + whitespace: correct bit assignment comments + diff: emit_line_ws_markup() if/else style fix + diff: correct suppress_blank_empty hack + diff: keep track of the type of the last line seen + diff: refactor output of incomplete line + diff: call emit_callback ecbdata everywhere + diff: update the way rewrite diff handles incomplete lines + apply: revamp the parsing of incomplete lines + whitespace: allocate a few more bits and define WS_INCOMPLETE_LINE + apply: check and fix incomplete lines + diff: highlight and error out on incomplete lines + attr: enable incomplete-line whitespace error for this project + Start 2.53 cycle + config: mark otherwise unused function as file-scope static + The second batch + The third batch + config: really pretend missing :(optional) value is not there + config: really treat missing optional path as not configured + submodule add: sanity check existing .gitmodules + The fourth batch + The fifth batch + The sixth batch + completion: clarify support for short options and arguments + connect: plug protocol capability leak + The seventh batch + Makefile: help macOS novices by mentioning MacPorts + FLEX_ARRAY: require platforms to support the C99 syntax + coccicheck: emit the contents of cocci patch + cocci: use MEMZERO_ARRAY() a bit more + The eighth batch + The ninth batch + The 10th batch + commit: document that $command.signoff will not be added + odb: do not use "blank" substitute for NULL + signoff-option: linkify the reference to gitfaq + The 11th batch + The 12th batch + The 13th batch + The 14th batch + The 15th batch + The 16th batch + The 17th batch + Git 2.53-rc0 + +Justin Tobler (8): + docs: clarify git-rev-list(1) --filter behavior + builtin/repo: group per-type object values into struct + strbuf: split out logic to humanise byte values + builtin/repo: humanise count values in structure output + builtin/repo: add inflated object info to keyvalue structure output + builtin/repo: add inflated object info to structure table + builtin/repo: add disk size info to keyvalue stucture output + builtin/repo: add object disk size info to structure table + +K Jayatheerth (1): + pull: move options[] array into function scope + +Karthik Nayak (11): + refs: move to using the '.optimize' functions + refs: rename 'pack_refs_opts' to 'refs_optimize_opts' + t/pack-refs-tests: move the 'test_done' to callees + reftable/stack: return stack segments directly + reftable/stack: add function to check if optimization is required + refs: add a `optimize_required` field to `struct ref_storage_be` + maintenance: add checking logic in `pack_refs_condition()` + maintenance: add 'is-needed' subcommand + fetch: extract out reference committing logic + fetch: fix non-conflicting tags not being committed + fetch: fix failed batched updates skipping operations + +Koji Nakamaru (1): + osxkeychain: avoid incorrectly skipping store operation + +Kristoffer Haugsbakk (14): + doc: commit: link to git-status(1) on all format options + doc: warn against --committer-date-is-author-date + branch: advice using git-help(1) instead of man(1) + doc: join default pre-commit paragraphs + doc: send-email: fix broken list continuation + doc: replay: mention no output on conflicts + replay: improve --contained and add to doc + doc: replay: link section using markup + replay: remove dead code and rearrange + replay: find *onto only after testing for ref name + replay: die descriptively when invalid commit-ish is given + replay: improve code comment and die message + replay: die if we cannot parse object + t3650: add more regression tests for failure conditions + +Lucas Seiki Oshiro (5): + repo: factor out field printing to dedicated function + repo: add --all to git-repo-info + repo: remove blank line from Documentation/git-repo.adoc + repo: use [--format=... | -z] instead of [-z] in git-repo-info synopsis + repo: add -z as an alias for --format=nul to git-repo-structure + +Matthew Hughes (2): + config: document 'gui.GCWarning' + docs: note the type of core.attributesfile + +Patrick Steinhardt (85): + packfile: use a `strmap` to store packs by name + packfile: move the MRU list into the packfile store + http: refactor subsystem to use `packfile_list`s + packfile: fix approximation of object counts + builtin/pack-objects: simplify logic to find kept or nonlocal objects + packfile: move list of packs into the packfile store + packfile: always add packfiles to MRU when adding a pack + packfile: track packs via the MRU list exclusively + odb: fix subtle logic to check whether an alternate is usable + odb: introduce `odb_source_new()` + odb: adjust naming to free object sources + object-file: move `fetch_if_missing` + object-file: introduce `struct odb_source_loose` + object-file: move loose object cache into loose source + object-file: hide internals when we need to reprepare loose sources + object-file: move loose object map into loose source + object-file: read objects via the loose object source + object-file: rename `has_loose_object()` + object-file: refactor freshening of objects + object-file: rename `write_object_file()` + object-file: refactor writing objects via a stream + refs: introduce wrapper struct for `each_ref_fn` + refs: introduce `.ref` field for the base iterator + refs: fully reset `struct ref_iterator::ref` on iteration + refs: refactor reference status flags + refs: expose peeled object ID via the iterator + upload-pack: convert to use `reference_get_peeled_oid()` + ref-filter: propagate peeled object ID + builtin/show-ref: convert to use `reference_get_peeled_oid()` + refs: drop `current_ref_iter` hack + refs: drop infrastructure to peel via iterators + object: add flag to `peel_object()` to verify object type + refs: don't store peeled object IDs for invalid tags + ref-filter: detect broken tags when dereferencing them + ref-filter: parse objects on demand + ref-filter: fix stale parsed objects + object: fix performance regression when peeling tags + path: move `enter_repo()` into "setup.c" + setup: convert `set_git_dir()` to have file scope + odb: adopt logic to close object databases + odb: refactor `odb_clear()` to `odb_free()` + streaming: rename `git_istream` into `odb_read_stream` + streaming: drop the `open()` callback function + streaming: propagate final object type via the stream + streaming: explicitly pass packfile info when streaming a packed object + streaming: allocate stream inside the backend-specific logic + streaming: create structure for in-core object streams + streaming: create structure for loose object streams + streaming: create structure for packed object streams + streaming: create structure for filtered object streams + streaming: move zlib stream into backends + packfile: introduce function to read object info from a store + streaming: rely on object sources to create object stream + streaming: get rid of `the_repository` + streaming: make the `odb_read_stream` definition public + streaming: move logic to read loose objects streams into backend + streaming: move logic to read packed objects streams into backend + streaming: refactor interface to be object-database-centric + streaming: move into object database subsystem + streaming: drop redundant type and size pointers + odb: move logic to disable ref updates into repo + oidset: introduce `oidset_equal()` + builtin/index-pack: fix deferred fsck outside repos + t/helper: stop setting up `the_repository` repeatedly + http-push: stop setting up `the_repository` for each reference + odb: handle initialization of sources in `odb_new()` + chdir-notify: add function to unregister listeners + odb: handle changing a repository's commondir + odb: handle recreation of quarantine directories + t/unit-tests: update clar to 39f11fe + t/unit-tests: demonstrate use of integer comparison assertions + gitattributes: disable blank-at-eof errors for clar test expectations + midx: fix `BUG()` when getting preferred pack without a reverse index + midx-write: extract function to test whether MIDX needs updating + midx-write: skip rewriting MIDX with `--stdin-packs` unless needed + odb: refactor parsing of alternates to be self-contained + odb: resolve relative alternative paths when parsing + odb: move computation of normalized objdir into `alt_odb_usable()` + odb: stop splitting alternate in `odb_add_to_alternates_file()` + odb: remove mutual recursion when parsing alternates + odb: drop forward declaration of `read_info_alternates()` + odb: read alternates via sources + odb: write alternates via sources + builtin/gc: fix condition for whether to write commit graphs + odb: properly close sources before freeing them + +Paul Tarjan (1): + t7800: fix racy "difftool --dir-diff syncs worktree" test + +Phillip Wood (3): + worktree list: fix column spacing + worktree list: quote paths + replay: do not copy "gpgsign-sha256" header + +Pushkar Singh (1): + t1300: use test helpers instead of `test` command + +Queen Ediri Jessa (1): + doc: clarify server behavior for invalid 'want' lines in HTTP protocol + +René Scharfe (35): + diff: disable rename detection with --quiet + wrapper: simplify xmkstemp() + config: fix suggestion for failed set of multi-valued option + config: fix short help of unset flags + diff-index: don't queue unchanged filepairs with diff_change() + wrapper: add git_mkdtemp() + compat: use git_mkdtemp() + compat: remove mingw_mktemp() + banned.h: ban mktemp(3) + compat: remove gitmkdtemp() + replay: move onto NULL check before first use + t4014: support Git version strings with spaces + diff-files: fix copy detection + revision: export commit_stack + log: use commit_stack + midx: use commit_stack + name-rev: use commit_stack + remote: use commit_stack for local_commits + remote: use commit_stack for sent_tips + remote: use commit_stack for src_commits + test-reach: use commit_stack + commit: add commit_stack_init() + pack-bitmap-write: use commit_stack + shallow: use commit_stack + commit: add commit_stack_grow() + commit-graph: use commit_stack + commit-reach: use commit_stack + macOS: make Homebrew use configurable + macOS: use iconv from Homebrew if needed and present + show-branch: use prio_queue + config: use git_parse_int() in git_config_get_expiry_in_days() + tag: use algo of repo parameter in parse_tag_buffer() + tag: support arbitrary repositories in gpg_verify_tag() + tag: support arbitrary repositories in parse_tag() + tag: stop using the_repository + +Sam Bostock (1): + bundle-uri: validate that bundle entries have a uri + +Siddharth Asthana (3): + replay: use die_for_incompatible_opt2() for option validation + replay: make atomic ref updates the default behavior + replay: add replay.refAction config option + +Tobias Boesch (1): + gitk: add external diff file rename detection + +Toon Claes (6): + last-modified: fix use of uninitialized memory + meson: ignore subprojects/.wraplock + meson: only detect ICONV_OMITS_BOM if possible + meson: use is_cross_build() where possible + git-compat-util: introduce MEMZERO_ARRAY() macro + contrib/coccinelle: pass include paths to spatch(1) + +Yee Cheng Chin (1): + xdiff: optimize patience diff's LCS search + +brian m. carlson (4): + object-file: disallow adding submodules of different hash algo + t0614: use numerical comparison with test_line_count + t5564: fix test hang under zsh's sh mode + checkout: quote invalid treeish in error message + + +Version v2.52.0; changes since v2.52.0-rc2: +------------------------------------------- + +Aindriú Mac Giolla Eoin (1): + l10n: ga.po: Update Irish translation for Git 2.52 + +Alexander Shopov (1): + l10n: bg.po: Updated Bulgarian translation (6065t) + +Arkadii Yakovets (1): + l10n: uk: add 2.52 translation + +Bagas Sanjaya (1): + l10n: po-id for 2.52 + +Emir SARI (1): + l10n: tr: Update Turkish translations + +Jean-Noël Avila (1): + l10n: fr: version 2.52 + +Junio C Hamano (2): + Use Perforce arm64 binary on macOS CI jobs + Git 2.52 + +Peter Krefting (1): + l10n: sv.po: Update Swedish translation + +Taylor Blau (1): + RelNotes: fix typo in release notes for 2.52.0 + +Teng Long (1): + l10n: zh_CN: updated translation for 2.52 + +Toon Claes (1): + last-modified: implement faster algorithm + +Vũ Tiến Hưng (1): + l10n: Updated translation for vi-2.52 + +Yi-Jyun Pan (1): + l10n: zh_TW.po: update Git 2.52 translation + + +Version v2.52.0-rc2; changes since v2.52.0-rc1: +----------------------------------------------- + +Christian Couder (5): + gpg-interface: simplify ssh fingerprint parsing + gpg-interface: use left shift to define GPG_VERIFY_* + fast-export: mark strings for translation + fast-import: mark strings for translation + gpg-interface: mark a string for translation + +D. Ben Knoble (7): + parseopt: fix :(optional) at command line to only ignore missing files + doc: clarify command equivalence comment + parseopt: use boolean type for a simple flag + config: use boolean type for a simple flag + parseopt: restore const qualifier to parsed filename + perl: also mark git-contacts executable + meson: make GIT_HTML_PATH configurable + +Johannes Schindelin (1): + ci: update {download,upload}-artifact Action versions + +Junio C Hamano (2): + parseopt: remove unreachable code + Git 2.52-rc2 + +Peter Krefting (1): + refs: add missing space in messages + +Thomas Uhle (1): + wincred: align Makefile with other Makefiles in contrib + + +Version v2.52.0-rc1; changes since v2.52.0-rc0: +----------------------------------------------- + +Christian Couder (1): + SubmittingPatches: add section about AI + +Eric W. Biederman (1): + t1016-compatObjectFormat: really freeze time for reproduciblity + +Jeff King (2): + doc: document backslash in gitignore patterns + test-tool: fix leak in delete-gpgsig command + +Junio C Hamano (3): + A bit more before rc1 + GitHub CI: macos-13 images are no more + Git 2.52-rc1 + +Justin Tobler (7): + builtin/repo: rename repo_info() to cmd_repo_info() + ref-filter: allow NULL filter pattern + ref-filter: export ref_kind_from_refname() + builtin/repo: introduce structure subcommand + builtin/repo: add object counts in structure output + builtin/repo: add keyvalue and nul format for structure stats + builtin/repo: add progress meter for structure stats + +Kristoffer Haugsbakk (1): + doc: git-checkout: fix placeholder markup + +Queen Ediri Jessa (1): + MyFirstContribution: add note on confirming patches + +Ruoyu Zhong (1): + bisect: update usage and docs to match each other + +Thomas Uhle (1): + contrib/credential: add install target + +Todd Zullinger (2): + t/lib-gpg: add prepare_gnupghome() to create GNUPGHOME dir + t/lib-gpg: call prepare_gnupghome() in GPG2 prereq + +Xinyu Ruan (1): + refs: add missing remove_on_disk implementation for debug backend + + +Version v2.52.0-rc0; changes since v2.51.2: +------------------------------------------- + +Adam Dinwoodie (2): + t/t1517: mark tests that fail with GIT_TEST_INSTALLED + git-gui: sync Makefiles with git.git + +Aditya Garg (2): + send-email: add ability to send a copy of sent emails to an IMAP folder + send-email: enable copying emails to an IMAP folder without actually sending them + +Alexander Monakov (1): + xdiff: optimize xdl_hash_record_verbatim + +Ayush Chandekar (2): + environment: remove the global variable 'merge_log_config' + builtin/fmt-merge-msg: stop depending on 'the_repository' + +Christian Couder (14): + promisor-remote: refactor to get rid of 'struct strvec' + promisor-remote: allow a server to advertise more fields + promisor-remote: use string constants for 'name' and 'url' too + promisor-remote: refactor how we parse advertised fields + promisor-remote: use string_list_split() in filter_promisor_remote() + promisor-remote: allow a client to check fields + promisor-remote: use string_list_split() in mark_remotes_as_accepted() + gpg-interface: refactor 'enum sign_mode' parsing + fast-import: add '--signed-commits=' option + doc: git-tag: stop focusing on GPG signed tags + lib-gpg: allow tests with GPGSM or GPGSSH prereq first + t9350: properly count annotated tags + fast-export: handle all kinds of tag signatures + fast-import: add '--signed-tags=' option + +Colin Stagner (1): + contrib/subtree: fix split with squashed subtrees + +D. Ben Knoble (10): + parse-options: refactor flags for usage_with_options_internal + builtin: also setup gently for --help-all + t7005: use modern test style + t7005: stop abusing --exec-path + t7005: sanitize test environment for subsequent tests + t3903: reduce dependencies on previous tests + t3905: remove unneeded blank line + stash: refactor private config globals + stash: honor stash.index in apply, pop modes + doc: explain the impact of stash.index on --autostash options + +Daniele Sassoli (1): + doc: add discord to ways of getting help + +Derrick Stolee (9): + ls-files: conditionally leave index sparse + sparse-checkout: remove use of the_repository + sparse-checkout: add basics of 'clean' command + sparse-checkout: match some 'clean' behavior + dir: add generic "walk all files" helper + sparse-checkout: add --verbose option to 'clean' + sparse-index: point users to new 'clean' action + t: expand tests around sparse merges and clean + sparse-index: improve advice message instructions + +Emily Yang (1): + commit-graph: add new config for changed-paths & recommend it in scalar + +Eric Sunshine (1): + gitk: fix MacOS 10.14 "Mojave" crash on launch + +Ezekiel Newren (14): + xdiff: delete static forward declarations in xprepare + xdiff: delete local variables and initialize/free xdfile_t directly + xdiff: delete unnecessary fields from xrecord_t and xdfile_t + xdiff: delete superfluous function xdl_get_rec() in xemit + xdiff: delete local variables that alias fields in xrecord_t + xdiff: delete struct diffdata_t + xdiff: delete redundant array xdfile_t.ha + xdiff: delete fields ha, line, size in xdlclass_t in favor of an xrecord_t + xdiff: delete chastore from xdfile_t + xdiff: rename rchg -> changed in xdfile_t + make: delete XDIFF_LIB, add xdiff to LIB_OBJS + make: delete REFTABLE_LIB, add reftable to LIB_OBJS + xdiff: add macros DISCARD(0), KEEP(1), INVESTIGATE(2) in xprepare.c + xdiff: change type of xdfile_t.changed from char to bool + +Greg Hurrell (2): + git-jump: make `diff` work with filenames containing spaces + mailmap: consolidate multiple addresses into one + +Heiko Voigt (1): + git-gui: provide question helper for retry fallback on Windows + +Jean-Noël Avila (10): + doc: test linkgit macros for well-formedness + doc: check well-formedness of delimited sections + doc: check for absence of multiple terms in each entry of desc list + doc: check for absence of the form --[no-]parameter + doc:git-for-each-ref: fix styling and typos + doc lint: check that synopsis manpages have synopsis inlines + doc: convert git-stash.adoc to synopis style + doc: convert git tag to synopsis style + doc: convert git worktree to synopsis style + doc: do not break sentences into "lego" pieces + +Jeff King (36): + combine-diff: zero memory used for callback filepairs + diff: teach tree-diff a max-depth parameter + describe: pass oid struct by const pointer + describe: error if blob not found + describe: catch unborn branch in describe_blob() + t5510: make confusing config cleanup more explicit + t5510: stop changing top-level working directory + t5510: prefer "git -C" to subshell for followRemoteHEAD tests + refs: do not clobber dangling symrefs + describe: handle blob traversal with no commits + describe: pass commit to describe_commit() + color: use GIT_COLOR_* instead of numeric constants + color: return enum from git_config_colorbool() + grep: don't treat grep_opt.color as a strict bool + diff: simplify color_moved check when flushing + diff: don't use diff_options.use_color as a strict bool + diff: pass o->use_color directly to fill_metainfo() + diff: stop passing ecbdata->use_color as boolean + pretty: use format_commit_context.auto_color as colorbool + color: use git_colorbool enum type to store colorbools + color: return bool from want_color() + add-interactive: retain colorbool values longer + config: store want_color() result in a separate bool + stash: tell setup_revisions() to free our allocated strings + revision: manage memory ownership of argv in setup_revisions() + revision: add wrapper to setup_revisions() from a strvec + treewide: use setup_revisions_from_strvec() when we have a strvec + treewide: pass strvecs around for setup_revisions_from_strvec() + revision: retain argv NULL invariant in setup_revisions() + diff: send external diff output to diff_options.file + diff: drop save/restore of color_moved in dry-run mode + diff: replace diff_options.dry_run flag with NULL file + diff: drop dry-run redirection to /dev/null + diff: simplify run_external_diff() quiet logic + match_pathname(): reorder prefix-match check + match_pathname(): give fnmatch one char of prefix context + +Johannes Schindelin (5): + git gui: set GIT_ASKPASS=git-gui--askpass if not set yet + git-gui--askyesno: allow overriding the window title + git-gui--askyesno (mingw): use Git for Windows' icon, if available + mingw: avoid relative `#include`s + mingw: order `#include`s alphabetically + +Johannes Sixt (2): + git-gui: fix error handling of Revert Changes command + t7500: fix tests with absolute path following ":(optional)" on Windows + +Jonathan Tan (1): + mailmap: change primary address for Jonathan Tan + +Julia Evans (26): + doc: git-add: clarify intro & add an example + doc: git-add: simplify discussion of ignored files + doc: git-rebase: start with an example + doc: git rebase: dedup merge conflict discussion + doc: git rebase: clarify arguments syntax + doc: git-rebase: move --onto explanation down + doc: git-rebase: update discussion of internals + doc: rephrase the purpose of the staging area + doc: git-checkout: clarify intro sentence + doc: git-checkout: clarify ARGUMENT DISAMBIGUATION + doc: git-checkout: clarify `git checkout ` + doc: git-checkout: clarify `-b` and `-B` + doc: git-checkout: deduplicate --detach explanation + doc: git-checkout: split up restoring files section + doc: git-checkout: clarify restoring files section + doc: git-push: create PUSH RULES section + doc: git-push: rewrite refspec specification + doc: git-push: clarify intro + doc: add an UPSTREAM BRANCHES section to pull/push/fetch + doc: git-push: clarify "where to push" + doc: git-push: clarify "what to push" + doc: git-push: add explanation of `git push origin main` + doc: git-pull: move and params + doc: git-pull: clarify options for integrating remote branch + doc: git-pull: delete the example + doc: git-pull: clarify how to exit a conflicted merge + +Junio C Hamano (53): + string-list: report programming error with BUG + string-list: align string_list_split() with its _in_place() counterpart + string-list: unify string_list_split* functions + string-list: optionally trim string pieces split by string_list_split*() + diff: simplify parsing of diff.colormovedws + string-list: optionally omit empty string pieces in string_list_split*() + string-list: split-then-remove-empty can be done while splitting + wt-status: avoid strbuf_split*() + clean: do not pass strbuf by value + clean: do not use strbuf_split*() [part 1] + clean: do not pass the whole structure when it is not necessary + clean: do not use strbuf_split*() [part 2] + merge-tree: do not use strbuf_split*() + notes: do not use strbuf_split*() + config: do not use strbuf_split() + environment: do not use strbuf_split*() + sub-process: do not use strbuf_split*() + trace2: trim_trailing_newline followed by trim is a no-op + trace2: do not use strbuf_split*() + abbrev: allow extending beyond 32 chars to disambiguate + Start 2.52 cycle, the first batch + The second batch + The third batch + The fourth batch + The fifth batch + The sixth batch + The seventh batch + The eighth batch + The ninth batch + The tenth batch + initial branch: give hints after switching the default name + The twelfth batch + t7500: make each piece more independent + The thirteenth batcn + The fourteenth batch + t7500: fix GIT_EDITOR shell snippet + config: values of pathname type can be prefixed with :(optional) + parseopt: values of pathname type can be prefixed with :(optional) + The fifteenth batch + The sixteenth batch + The seventeenth batch + t1016: make sure to use specified GPG + The eighteenth batch + The nineteenth batch + The twentieth batch + The twenty-first batch + The twenty-second batch + The twenty-third batch + The twenty-fourth batch + The 25th batch + The 26th batch + The 27th batch + Git 2.52-rc0 + +Justin Tobler (10): + bulk-checkin: introduce object database transaction structure + bulk-checkin: remove global transaction state + bulk-checkin: require transaction for index_blob_bulk_checkin() + bulk-checkin: use repository variable from transaction + bulk-checkin: remove ODB transaction nesting + builtin/update-index: end ODB transaction when --verbose is specified + bulk-checkin: drop flush_odb_transaction() + object-file: relocate ODB transaction code + object-file: update naming from bulk-checkin + odb: add transaction interface + +KIYOTA Fumiya (1): + completion: complete some 'git log' options + +Karthik Nayak (9): + Documentation: note styling for bit fields + refs/ref-cache: fix SEGFAULT when seeking in empty directories + refs: remove unused headers + refs: move consistency check msg to generic layer + reftable: check for trailing newline in 'tables.list' + Documentation/fsck-msgids: remove duplicate msg id + fsck: order 'fsck_msg_type' alphabetically + reftable: add code to facilitate consistency checks + refs/reftable: add fsck check for checking the table name + +Kristoffer Haugsbakk (5): + range-diff: rename other_arg to log_arg + revision: add rdiff_log_arg to rev_info + format-patch: handle range-diff on notes correctly for single patches + doc: patch-id: convert to the modern synopsis style + RelNotes: sync with Git 2.51.1 fixups + +Lidong Yan (2): + bloom: enable bloom filter with wildcard pathspec in revision traversal + diff: stop output garbled message in dry run mode + +Lucas Seiki Oshiro (7): + repo: declare the repo command + repo: add the field references.format + repo: add the field layout.bare + repo: add the field layout.shallow + repo: add the --format flag + repo: add the flag -z as an alias for --format=nul + repo: add the field objects.format + +Mark Levedahl (15): + git-gui: simplify PATH de-duplication + git-gui: simplify using nice(1) + gitk: use themed spinboxes + gitk: make sha1but a ttk::button + gitk: use config variables to define and load a theme + gitk: do not invoke tk_setPalette + gitk: use text labels for commit ID buttons + gitk: use text labels for next/prev search buttons + gitk: eliminate Interface color option from gui + gitk: eliminate unused ui color variables + gitk: add proc run_themeloader + gitk: add theme selection to color configuration page + gitk: make configuration dialog resizing useful + gitk: separate code blocks for configuration dialog + gitk: set minimum size on configuration dialog + +Meet Soni (19): + doc: factor out common option + builtin/for-each-ref: align usage string with the man page + builtin/for-each-ref: factor out core logic into a helper + builtin/refs: add list subcommand + t6300: refactor tests to be shareable + t: add test for git refs list subcommand + builtin/refs: add 'exists' subcommand + t1403: split 'show-ref --exists' tests into a separate file + t1422: refactor tests to be shareable + t: add test for git refs exists subcommand + refs: add a generic 'optimize' API + files-backend: implement 'optimize' action + reftable-backend: implement 'optimize' action + builtin/pack-refs: convert to use the generic refs_optimize() API + builtin/pack-refs: factor out core logic into a shared library + doc: pack-refs: factor out common options + builtin/refs: add optimize subcommand + t0601: refactor tests to be shareable + t: add test for git refs optimize subcommand + +Michael Lohmann (1): + builtin/reflog: respect user config in "write" subcommand + +Michael Rappazzo (2): + gitk: add README with usage, build, and contribution details + gitk: fix error when remote tracking branch is deleted + +NeilBrown (1): + send-email: don't duplicate Reply-to: in intro message + +Olamide Caleb Bello (2): + gpg-interface: do not use misdesigned strbuf_split*() + gpg-interface: do not use misdesigned strbuf_split*() + +Patrick Steinhardt (98): + refs: pass refname when invoking reflog entry callback + refs: simplify logic when migrating reflog entries + builtin/remote: fix sign comparison warnings + builtin/remote: determine whether refs need renaming early on + builtin/remote: rework how remote refs get renamed + builtin/remote: only iterate through refs that are to be renamed + odb: store locality in object database sources + odb: allow `odb_find_source()` to fail + odb: consistently use "dir" to refer to alternate's directory + odb: return newly created in-memory sources + odb: simplify calling `link_alt_odb_entry()` + midx: drop redundant `struct repository` parameter + midx: load multi-pack indices via their source + midx: write multi-pack indices via their source + midx: stop duplicating info redundant with its owning source + midx: compute paths via their source + reftable/writer: fix type used for number of records + reftable/writer: drop Git-specific `QSORT()` macro + reftable/stack: reorder code to avoid forward declarations + reftable/stack: fix compiler warning due to missing braces + reftable/stack: allow passing flags to `reftable_stack_add()` + reftable/stack: handle outdated stacks when compacting + reftable: don't second-guess errors from flock interface + refs/reftable: always reload stacks when creating lock + commit-graph: stop using `the_hash_algo` via macros + commit-graph: store the hash algorithm instead of its length + commit-graph: refactor `parse_commit_graph()` to take a repository + commit-graph: stop using `the_hash_algo` + commit-graph: stop using `the_repository` + commit-graph: stop passing in redundant repository + blame: drop explicit check for commit graph + revision: drop explicit check for commit graph + commit-graph: return the prepared commit graph from `prepare_commit_graph()` + commit-graph: return commit graph from `repo_find_commit_pos_in_graph()` + commit-graph: pass graphs that are to be merged as parameter + t/unit-tests: update clar to fcbed04 + meson: introduce a "docs" alias to compile documentation only + meson: print docs backend as part of the summary + ci: don't compile whole project when testing docs with Meson + t1300: write test expectations in the test's body + t1300: small style fixups + builtin/config: do not die in `get_color()` + builtin/config: special-case retrieving colors without a key + builtin/config: do not spawn pager when printing color codes + t/unit-tests: update to 10e96bc + packfile: introduce a new `struct packfile_store` + odb: move list of packfiles into `struct packfile_store` + odb: move initialization bit into `struct packfile_store` + odb: move packfile map into `struct packfile_store` + odb: move MRU list of packfiles into `struct packfile_store` + odb: move kept cache into `struct packfile_store` + packfile: reorder functions to avoid function declaration + packfile: refactor `prepare_packed_git()` to work on packfile store + packfile: split up responsibilities of `reprepare_packed_git()` + packfile: refactor `install_packed_git()` to work on packfile store + packfile: introduce function to load and add packfiles + packfile: move `get_multi_pack_index()` into "midx.c" + packfile: refactor `get_packed_git()` to work on packfile store + packfile: refactor `get_all_packs()` to work on packfile store + packfile: refactor `get_packed_git_mru()` to work on packfile store + meson: add infrastructure to build internal Rust library + Makefile: reorder sources after includes + Makefile: introduce infrastructure to build internal Rust library + help: report on whether or not Rust is enabled + varint: use explicit width for integers + varint: reimplement as test balloon for Rust + BreakingChanges: announce Rust becoming mandatory + ci: convert "pedantic" job into full build with breaking changes + ci: enable Rust for breaking-changes jobs + gitlab-ci: dedup instructions to disable realtime monitoring + gitlab-ci: ignore failures to disable realtime monitoring + gitlab-ci: drop workaround for Python certificate store on Windows + gitlab-ci: upload Meson test logs as JUnit reports + t8020: fix test failure due to indeterministic tag sorting + ci: deduplicate calls to `apt-get update` + ci: check formatting of our Rust code + rust/varint: add safety comments + ci: check for common Rust mistakes via Clippy + ci: verify minimum supported Rust version + rust: support for Windows + refs/files: deprecate writing symrefs as symbolic links + object-name: convert to use `packfile_store_get_all_packs()` + builtin/gc: convert to use `packfile_store_get_all_packs()` + builtin/grep: simplify how we preload packs + packfile: drop `packfile_store_get_packs()` + packfile: introduce macro to iterate through packs + packfile: rename `packfile_store_get_all_packs()` + builtin/gc: remove global `repack` variable + builtin/gc: make `too_many_loose_objects()` reusable without GC config + builtin/maintenance: introduce "geometric-repack" task + builtin/maintenance: make the geometric factor configurable + builtin/maintenance: don't silently ignore invalid strategy + builtin/maintenance: improve readability of strategies + builtin/maintenance: run maintenance tasks depending on type + builtin/maintenance: extend "maintenance.strategy" to manual maintenance + builtin/maintenance: make "gc" strategy accessible + builtin/maintenance: introduce "geometric" strategy + t7900: fix a flaky test due to git-repack always regenerating MIDX + +Paulo Casaretto (1): + range-diff: add configurable memory limit for cost matrix + +Phillip Wood (10): + xdiff: refactor xdl_hash_record() + breaking-changes: deprecate support for core.commentString=auto + config: warn on core.commentString=auto + commit: print advice when core.commentString=auto + breaking-changes: switch default branch to main + t4013: switch default branch name to main + t9902: switch default branch name to main + t0613: stop setting default initial branch + add -p: mark split hunks as undecided + add-patch: update hunk splitability after editing + +Ramsay Jones (5): + doc: add some missing technical documents + doc: remembering-renames.adoc: fix asciidoc warnings + doc: sparse-checkout.adoc: fix asciidoc warnings + doc: commit-graph.adoc: fix up some formatting + doc: add large-object-promisors.adoc to the docs build + +René Scharfe (14): + describe: use prio_queue + describe: use prio_queue_replace() + describe: use oidset in finish_depth_computation() + use repo_get_oid_with_flags() + add-patch: improve help for options j, J, k, and K + add-patch: document that option J rolls over + add-patch: let options y, n, j, and e roll over to next undecided + add-patch: let options k and K roll over like j and J + add-patch: let options a and d roll over like y and n + add-patch: reset "permitted" at loop start + add-patch: fully document option P + commit-reach: avoid commit_list_insert_by_date() + add-patch: quit without skipping undecided hunks + add-patch: quit on EOF + +Ruoyu Zhong (3): + gitk: use for ctx menus on macOS with Tcl 8.7+ + gitk: fix trackpad scrolling for Tcl/Tk 8.7+ + bisect: fix handling of `help` and invalid subcommands + +SZEDER Gábor (4): + line-log: avoid unnecessary tree diffs when processing merge commits + line-log: get rid of the parents array in process_ranges_merge_commit() + line-log: initialize diff queue in process_ranges_ordinary_commit() + line-log: simplify condition checking for merge commits + +Taylor Blau (52): + SubmittingPatches: extend release-notes experiment to topic names + SubmittingPatches: guidance for multi-series efforts + builtin/cat-file.c: simplify calling `report_object_status()` + builtin/repack.c: avoid "the_repository" in `cmd_repack()` + builtin/repack.c: avoid "the_repository" in existing packs API + builtin/repack.c: avoid "the_repository" when taking a ref snapshot + builtin/repack.c: avoid "the_repository" when removing packs + builtin/repack.c: avoid "the_repository" when repacking promisor objects + builtin/repack.c: avoid "the_hash_algo" when deleting packs + builtin/repack.c: avoid "the_hash_algo" in `write_oid()` + builtin/repack: avoid "the_hash_algo" in `repack_promisor_objects()` + builtin/repack.c: avoid "the_hash_algo" in `finish_pack_objects_cmd()` + builtin/repack.c: avoid using `hash_to_hex()` in pack geometry + repack: introduce new compilation unit + builtin/repack.c: pass both pack_objects args to repack_config + repack: move 'delta_base_offset' to 'struct pack_objects_args' + repack: remove 'prepare_pack_objects' from the builtin + builtin/repack.c: rename many 'struct existing_packs' functions + repack: remove 'remove_redundant_pack' from the builtin + builtin/repack.c: pass "packdir" when removing packs + builtin/repack.c: avoid unnecessary numeric casts in existing_packs + repack: remove 'existing_packs' API from the builtin + builtin/repack.c: rename "struct generated_pack_data" + builtin/repack.c: factor out "generated_pack_install" + builtin/repack.c: pass "packtmp" to `generated_pack_populate()` + builtin/repack.c: provide pack locations to `generated_pack_install()` + repack: remove 'generated_pack' API from the builtin + builtin/repack.c: pass "packtmp" to `repack_promisor_objects()` + builtin/repack.c: remove "repack_promisor_objects()" from the builtin + builtin/repack.c: rename various pack_geometry functions + builtin/repack.c: pass 'pack_kept_objects' to `pack_geometry_init()` + builtin/repack.c: pass 'packdir' to `pack_geometry_remove_redundant()` + repack: remove pack_geometry API from the builtin + builtin/repack.c: remove ref snapshotting from builtin + builtin/repack.c: extract opts struct for 'write_midx_included_packs()' + builtin/repack.c: use a string_list for 'midx_pack_names' + repack: keep track of MIDX pack names using existing_packs + builtin/repack.c: reorder `remove_redundant_bitmaps()` + builtin/repack.c: inline `remove_redundant_bitmaps()` + builtin/repack.c: pass `repack_write_midx_opts` to `midx_included_packs` + builtin/repack.c: inline packs within `write_midx_included_packs()` + repack: 'write_midx_included_packs' API from the builtin + builtin/repack.c: introduce `struct write_pack_opts` + builtin/repack.c: use `write_pack_opts` within `write_cruft_pack()` + repack: move `find_pack_prefix()` out of the builtin + repack: extract `write_pack_opts_is_local()` + builtin/repack.c: pass `write_pack_opts` to `finish_pack_objects_cmd()` + repack: move `finish_pack_objects_cmd()` out of the builtin + repack: move `pack_kept_objects` to `struct pack_objects_args` + repack: move `write_filtered_pack()` out of the builtin + repack: move `write_cruft_pack()` out of the builtin + builtin/repack.c: clean up unused `#include`s + +Thomas Uhle (1): + contrib/credential: harmonize Makefiles + +Toon Claes (7): + within_depth: fix return for empty path + t0450: fix test for out-of-tree builds + last-modified: new subcommand to show when files were last modified + t/perf: add last-modified perf script + last-modified: use Bloom filters when available + t0450: add allowlist for builtins with missing .adoc + last-modified: fix bug when some paths remain unhandled + +Usman Akinyemi (3): + t/t1517: automate `git subcmd -h` tests outside a repository + t5200: move `update-server-info -h` test from t1517 + t5304: move `prune -h` test from t1517 + +brian m. carlson (9): + docs: update pack index v3 format + docs: update offset order for pack index v3 + docs: reflect actual double signature for tags + docs: improve ambiguous areas of pack format documentation + docs: add documentation for loose objects + rev-parse: allow printing compatibility hash + fsck: consider gpgsig headers expected in tags + t: allow specifying compatibility hash + t1010: use BROKEN_OBJECTS prerequisite + +shejialuo (4): + string-list: use bool instead of int for "exact_match" + string-list: replace negative index encoding with "exact_match" parameter + string-list: change "string_list_find_insert_index" return type to "size_t" + refs: enable sign compare warnings check + +ノウラ | Flare (1): + alloc: fix dangling pointer in alloc_state cleanup + + +Version v2.51.2; changes since v2.51.1: +--------------------------------------- + +Jacob Keller (1): + diff --no-index: fix logic for paths ending in '/' + +Jeff King (2): + diff: restore redirection to /dev/null for diff_from_contents + status: make coloring of "-z --short" consistent + +Johannes Schindelin (5): + refs: forbid clang to complain about unreachable code + build(deps): bump actions/download-artifact from 4 to 5 + build(deps): bump actions/checkout from 4 to 5 + build(deps): bump actions/setup-python from 5 to 6 + build(deps): bump actions/github-script from 7 to 8 + +Junio C Hamano (2): + diff: make sure the other caller of diff_flush_patch_quietly() is silent + Git 2.51.2 + +Kristoffer Haugsbakk (1): + doc: fix accidental literal blocks + +Patrick Steinhardt (2): + gitlab-ci: disable realtime monitoring to unbreak Windows jobs + t7528: work around ETOOMANY in OpenSSH 10.1 and newer + +Solly (1): + t2401: update path checks using test_path helpers + +Torsten Bögershausen (1): + unicode: update the width tables to Unicode 17 + + +Version v2.51.1; changes since v2.51.0: +--------------------------------------- + +Aditya Garg (1): + docs: update sendmail docs to use more secure SMTP server for Gmail + +Daniele Sassoli (2): + count-objects: document count-objects pack + doc: clarify which remotes can be used with GitGitGadget + +David Aguilar (1): + Makefile: build libgit-rs and libgit-sys serially + +Denton Liu (3): + t5516: remove surrounding empty lines in test bodies + remote.c: remove BUG in show_push_unqualified_ref_name_error() + remote.c: convert if-else ladder to switch + +Derrick Stolee (8): + path-walk: fix setup of pending objects + path-walk: create initializer for path lists + midx-write: only load initialized packs + midx-write: put failing response value back + midx-write: use cleanup when incremental midx fails + midx-write: use uint32_t for preferred_pack_idx + midx-write: reenable signed comparison errors + midx-write: simplify error cases + +Elijah Newren (8): + merge-ort: update comments to modern testfile location + merge-ort: drop unnecessary temporary in check_for_directory_rename() + t6423: document two bugs with rename-to-self testcases + t6423: fix missed staging of file in testcases 12i,12j,12k + merge-ort: clarify the interning of strings in opt->priv->path + merge-ort: fix incorrect file handling + merge-ort: fix directory rename on top of source of other rename/delete + Documentation/git-merge-tree.adoc: clarify the --merge-base option + +Jean-Noël Avila (2): + doc: fix asciidoc format compatibility in pretty-formats.adoc + doc: change the markup of paragraphs following a nested list item + +Jeff King (7): + fetch-pack: re-scan when double-checking graph objects + curl: add support for curl_global_trace() components + stash: pass --no-color to diff plumbing child processes + add-interactive: respect color.diff for diff coloring + add-interactive: manually fall back color config to color.ui + contrib/diff-highlight: mention interactive.diffFilter + doc: fix indentation of refStorage item in git-config(1) + +Johannes Schindelin (3): + http: offer to cast `size_t` to `curl_off_t` safely + imap-send: be more careful when casting to `curl_off_t` + http-push: avoid new compile error + +Johannes Sixt (4): + rebase -i: permit 'drop' of a merge commit + doc/gitk: update reference to the external project + doc/format-patch: adjust Thunderbird MUA hint to new add-on + progress: pay attention to (customized) delay time + +Junio C Hamano (4): + diff: --no-index should ignore the worktree + config: document includeIf conditions consistently + Prepare for 2.51.1 + Git 2.51.1 + +Justin Tobler (1): + clang-format: exclude control macros from SpaceBeforeParens + +Karthik Nayak (4): + refs/files: catch conflicts on case-insensitive file-systems + refs/files: use correct error type when lock exists + refs/files: handle F/D conflicts in case-insensitive FS + refs/files: handle D/F conflicts during locking + +Knut Harald Ryager (1): + docs: remove stray bracket from git-clone synopsis + +Kristoffer Haugsbakk (17): + doc: git-log: fix description list + doc: interpret-trailers: close all pairs of single quotes + doc: config: replace backtick with apostrophe for possessive + doc: add missing backtick for inline-verbatim + doc: remove extra backtick for inline-verbatim + doc: fast-import: replace literal block with paragraph + Makefile: don’t add whatchanged after it has been removed + git: add `deprecated` category to --list-cmds + git: move seen-alias bookkeeping into handle_alias(...) + git: allow alias-shadowing deprecated builtins + t0014: test shadowing of aliases for a sample of builtins + you-still-use-that??: help the user help themselves + whatchanged: hint about git-log(1) and aliasing + whatchanged: remove not-even-shorter clause + BreakingChanges: remove claim about whatchanged reports + doc: patch-id: fix accidental literal blocks + RelNotes: minor fixups before 2.51.1 + +Kyle E. Mitchell (1): + doc: fix formatting of function-wrap shell alias + +Lidong Yan (1): + diff: ensure consistent diff behavior with ignore options + +M Hickford (1): + docs/gitcredentials: describe URL prefix matching + +Mikhail Malinouski (1): + docs: fix typo in worktree.adoc 'extension' + +Patrick Steinhardt (13): + Documentation/git-reflog: convert to use synopsis type + builtin/reflog: improve grouping of subcommands + refs: export `ref_transaction_update_reflog()` + builtin/reflog: implement subcommand to write new entries + ident: fix type of string length parameter + refs: fix identity for migrated reflogs + refs/files: detect race when generating reflog entry for HEAD + refs: stop unsetting REF_HAVE_OLD for log-only updates + refs: fix invalid old object IDs when migrating reflogs + t5530: modernize tests + upload-pack: don't ACK non-commits repeatedly in protocol v2 + odb: drop deprecated wrapper functions + ci: fix broken jobs on Ubuntu 25.10 caused by switch to sudo-rs(1) + +Phillip Wood (2): + rebase -i: respect commit.cleanup when picking fixups + sequencer: remove VERBATIM_MSG flag + +Ramsay Jones (1): + t6137-*.sh: fix test failure on cygwin + +René Scharfe (1): + object-name: declare pointer type of extend_abbrev_len()'s 2nd parameter + +SZEDER Gábor (2): + line-log: fix assertion error + line-log: show all line ranges touched by the same diff range + +brian m. carlson (1): + docs: note that extensions.compatobjectformat is incomplete + + Version v2.51.0; changes since v2.51.0-rc2: ------------------------------------------- @@ -32755,10 +34284,8 @@ Dimitriy Ryazantcev (2): l10n: ru.po: update Russian translation l10n: ru.po: update Russian translation -Jean-Noel Avila (1): +Jean-Noël Avila (2): l10n: fr.po fix some mistakes - -Jean-Noël Avila (1): l10n: fr.po: v2.15.0 round 2 Jiang Xin (3): @@ -33947,7 +35474,7 @@ Hartmut Henkel (1): Hugues Peccatte (1): l10n: fr.po Fix some translations -Jean-Noel Avila (1): +Jean-Noël Avila (1): l10n: fr.po v2.14.0 rnd 2 Jiang Xin (2): @@ -52293,7 +53820,7 @@ Antoine Pelisse (1): Christian Couder (1): Makefile: detect when PYTHON_PATH changes -Jean-Noël AVILA (1): +Jean-Noël Avila (1): Add directory pattern matching to attributes Jeff King (9): @@ -67462,6 +68989,9 @@ Brandon Casey (5): Eric Wong (1): git svn: allow uppercase UUIDs from SVN +Greg Hurrell (1): + gitweb: update Git homepage URL + Johan Herland (1): quickfetch(): Prevent overflow of the rev-list command line @@ -67489,9 +69019,6 @@ SZEDER Gábor (2): Document 'git (rev-list|log) --merges' bash: add '--merges' to common 'git log' options -Wincent Colaiuta (1): - gitweb: update Git homepage URL - Version v1.6.4-rc0; changes since v1.6.3.4: ------------------------------------------- @@ -68434,6 +69961,9 @@ Erik Faye-Lund (4): Frank Lichtenheld (1): gitcvs-migration: Link to git-cvsimport documentation +Greg Hurrell (1): + git add -p: add missing "q" to patch prompt + Holger Weiß (1): gitweb: Fix snapshots requested via PATH_INFO @@ -68506,9 +70036,6 @@ Wesley J. Landaker (2): Documentation: git-svn: fix spurious bolding that mangles the output Documentation: git-svn: fix a grammatical error without awkwardness -Wincent Colaiuta (1): - git add -p: add missing "q" to patch prompt - Version v1.6.3-rc1; changes since v1.6.3-rc0: --------------------------------------------- @@ -68785,6 +70312,10 @@ Finn Arne Gangstad (7): Giuseppe Bilotta (1): import-tars: separate author from committer +Greg Hurrell (2): + Grammar fixes to "merge" and "patch-id" docs + Grammar fix for "git merge" man page + Heiko Voigt (3): Add warning about known issues to documentation of cvsimport Cleanup warning about known issues in cvsimport documentation @@ -69151,10 +70682,6 @@ Tor Arne Vestbø (2): Wesley J. Landaker (1): Documentation: git-svn: fix trunk/fetch svn-remote key typo -Wincent Colaiuta (2): - Grammar fixes to "merge" and "patch-id" docs - Grammar fix for "git merge" man page - Version v1.6.2.5; changes since v1.6.2.4: ----------------------------------------- @@ -69166,6 +70693,9 @@ Allan Caffee (2): Frank Lichtenheld (1): gitcvs-migration: Link to git-cvsimport documentation +Greg Hurrell (1): + git add -p: add missing "q" to patch prompt + Johannes Schindelin (1): Fix off-by-one in read_tree_recursive @@ -69194,9 +70724,6 @@ Nicolas Pitre (1): Stephen Boyd (1): test-genrandom: Add newline to usage string -Wincent Colaiuta (1): - git add -p: add missing "q" to patch prompt - Version v1.6.2.4; changes since v1.6.2.3: ----------------------------------------- @@ -75753,6 +77280,9 @@ Version v1.5.4.3; changes since v1.5.4.2: Gerrit Pape (1): git-clone.sh: properly configure remote even if remote's head is dangling +Greg Hurrell (1): + git-gui: relax "dirty" version detection + Jay Soffian (2): git-gui: support Git Gui.app under OS X 10.5 send-email: squelch warning due to comparing undefined $_ to "" @@ -75782,9 +77312,6 @@ Shawn O. Pearce (5): git-gui: Avoid hardcoded Windows paths in Cygwin package files git-gui: Focus insertion point at end of strings in repository chooser -Wincent Colaiuta (1): - git-gui: relax "dirty" version detection - Version v1.5.4.2; changes since v1.5.4.1: ----------------------------------------- @@ -76319,6 +77846,9 @@ Arjen Laarhoven (1): Charles Bailey (1): Remove old generated files from .gitignore. +Greg Hurrell (1): + Emit helpful status for accidental "git stash" save + Gustaf Hendeby (2): Make git send-email accept $EDITOR with arguments shortlog manpage documentation: work around asciidoc markup issues @@ -76374,9 +77904,6 @@ Shawn O. Pearce (2): Stefan Sperling (1): Small comment fix for git-cvsimport. -Wincent Colaiuta (1): - Emit helpful status for accidental "git stash" save - Version v1.5.4-rc1; changes since v1.5.4-rc0: --------------------------------------------- @@ -76403,6 +77930,13 @@ Eric Wong (5): Finn Arne Gangstad (1): Improved submodule merge support +Greg Hurrell (5): + "diff --check" should affect exit status + Unify whitespace checking + Make "diff --check" output match "git apply" + Use shorter error messages for whitespace problems + Test interaction between diff --check and --exit-code + H. Merijn Brand (1): the use of 'tr' in the test suite isn't really portable @@ -76513,13 +78047,6 @@ Shawn O. Pearce (2): Avoid update hook during git-rebase --interactive Catch and handle git-commit failures in git-rebase --interactive -Wincent Colaiuta (5): - "diff --check" should affect exit status - Unify whitespace checking - Make "diff --check" output match "git apply" - Use shorter error messages for whitespace problems - Test interaction between diff --check and --exit-code - anonymous (1): Documentation: describe pack idx v2 @@ -76770,6 +78297,29 @@ Gerrit Pape (9): Gordon Hopper (1): git-cvsimport: fix handling of user name when it is not set in CVSROOT +Greg Hurrell (21): + Further clarify clean.requireForce changes + Authenticate only once in git-send-email + Refactor patch_update_cmd + Teach builtin-add to pass multiple paths to git-add--interactive + Add path-limiting to git-add--interactive + Add "--patch" option to git-add--interactive + Fix typo in draft 1.5.4 release notes + Highlight keyboard shortcuts in git-add--interactive + revert/cherry-pick: Allow overriding the help text by the calling Porcelain + add -i: allow prefix highlighting for "Add untracked" as well. + git-add -i: add help text for list-and-choose UI + Silence iconv warnings on Leopard + Teach "git add -i" to colorize whitespace errors + Allow --no-verify to bypass commit-msg hook + Documentation: fix --no-verify documentation for "git commit" + Add tests for pre-commit and commit-msg hooks + Interactive editor tests for commit-msg hook + Style fixes for pre-commit hook tests + Use "whitespace" consistently + Documentation: minor grammar fix for "git apply" + Fix "diff --check" whitespace detection + Guido Ostkamp (2): Remove unreachable statements Use compat mkdtemp() on Solaris boxes @@ -77695,29 +79245,6 @@ Vineet Kumar (1): Väinö Järvelä (1): Added a test for fetching remote tags when there is not tags. -Wincent Colaiuta (21): - Further clarify clean.requireForce changes - Authenticate only once in git-send-email - Refactor patch_update_cmd - Teach builtin-add to pass multiple paths to git-add--interactive - Add path-limiting to git-add--interactive - Add "--patch" option to git-add--interactive - Fix typo in draft 1.5.4 release notes - Highlight keyboard shortcuts in git-add--interactive - revert/cherry-pick: Allow overriding the help text by the calling Porcelain - add -i: allow prefix highlighting for "Add untracked" as well. - git-add -i: add help text for list-and-choose UI - Silence iconv warnings on Leopard - Teach "git add -i" to colorize whitespace errors - Allow --no-verify to bypass commit-msg hook - Documentation: fix --no-verify documentation for "git commit" - Add tests for pre-commit and commit-msg hooks - Interactive editor tests for commit-msg hook - Style fixes for pre-commit hook tests - Use "whitespace" consistently - Documentation: minor grammar fix for "git apply" - Fix "diff --check" whitespace detection - Xudong Guan (2): Initial Chinese translation for git-gui git-gui: Added initial version of po/glossary/zh_cn.po @@ -77858,6 +79385,10 @@ Gerrit Pape (4): git-daemon: fix remote port number in log entry git-mailsplit: with maildirs not only process cur/, but also new/ +Greg Hurrell (2): + Grammar fixes for gitattributes documentation + Fix t9101 test failure caused by Subversion "auto-props" + Jakub Narębski (1): gitweb: Update config file example for snapshot feature in gitweb/INSTALL @@ -77927,10 +79458,6 @@ Shawn O. Pearce (2): Vincent Zanotti (1): gitweb: correct month in date display for atom feeds -Wincent Colaiuta (2): - Grammar fixes for gitattributes documentation - Fix t9101 test failure caused by Subversion "auto-props" - Version v1.5.3.5; changes since v1.5.3.4: ----------------------------------------- diff --git a/debian/control b/debian/control index da944795..e74cffcc 100644 --- a/debian/control +++ b/debian/control @@ -19,7 +19,7 @@ Build-Depends: libz-dev, gettext, dh-apache2, dpkg-dev (>= 1.16.2~) Build-Depends-Indep: asciidoc (>= 8.6.10), xmlto, docbook-xsl -Standards-Version: 4.7.0 +Standards-Version: 4.7.2 Homepage: https://git-scm.com/ Vcs-Git: https://repo.or.cz/r/git/debian.git/ Vcs-Browser: https://repo.or.cz/w/git/debian.git/ diff --git a/debian/copyright b/debian/copyright index 4f5fe47b..3f9815e7 100644 --- a/debian/copyright +++ b/debian/copyright @@ -3,7 +3,7 @@ Upstream-Contact: git@vger.kernel.org Source: https://www.kernel.org/pub/software/scm/git/ Files: * -Copyright: © 2005-2025, Linus Torvalds and others. +Copyright: © 2005-2026, Linus Torvalds and others. License: GPL-2 Files: reftable/* t/unit-tests/u-reftable-*.c diff --git a/debian/versions.upstream b/debian/versions.upstream index 164802f9..4b990a05 100644 --- a/debian/versions.upstream +++ b/debian/versions.upstream @@ -916,3 +916,13 @@ v2.51.0-rc0 v2.51.0-rc1 v2.51.0-rc2 v2.51.0 +v2.51.1 +v2.51.2 +v2.52.0-rc0 +v2.52.0-rc1 +v2.52.0-rc2 +v2.52.0 +v2.53.0-rc0 +v2.53.0-rc1 +v2.53.0-rc2 +v2.53.0 diff --git a/for-each-ref.h b/for-each-ref.h new file mode 100644 index 00000000..c8d02191 --- /dev/null +++ b/for-each-ref.h @@ -0,0 +1,26 @@ +#ifndef FOR_EACH_REF_H +#define FOR_EACH_REF_H + +struct repository; + +/* + * Shared usage string for options common to git-for-each-ref(1) + * and git-refs-list(1). The command-specific part (e.g., "git refs list ") + * must be prepended by the caller. + */ +#define COMMON_USAGE_FOR_EACH_REF \ + "[--count=] [--shell|--perl|--python|--tcl]\n" \ + " [(--sort=)...] [--format=]\n" \ + " [--include-root-refs] [--points-at=]\n" \ + " [--merged[=]] [--no-merged[=]]\n" \ + " [--contains[=]] [--no-contains[=]]\n" \ + " [(--exclude=)...] [--start-after=]\n" \ + " [ --stdin | (...)]" + +/* + * The core logic for for-each-ref and its clones. + */ +int for_each_ref_core(int argc, const char **argv, const char *prefix, + struct repository *repo, const char *const *usage); + +#endif /* FOR_EACH_REF_H */ diff --git a/git-gui/git-gui--askyesno b/git-gui/git-gui--askyesno new file mode 100755 index 00000000..142d1bc3 --- /dev/null +++ b/git-gui/git-gui--askyesno @@ -0,0 +1,63 @@ +#!/bin/sh +# Tcl ignores the next line -*- tcl -*- \ +exec wish "$0" -- "$@" + +# This is an implementation of a simple yes no dialog +# which is injected into the git commandline by git gui +# in case a yesno question needs to be answered. +# +# The window title, which defaults to "Question?", can be +# overridden via the optional `--title` command-line +# option. + +set NS {} +set use_ttk [package vsatisfies [package provide Tk] 8.5] +if {$use_ttk} { + set NS ttk +} + +set title "Question?" +if {$argc < 1} { + puts stderr "Usage: $argv0 " + exit 1 +} else { + if {$argc > 2 && [lindex $argv 0] == "--title"} { + set title [lindex $argv 1] + set argv [lreplace $argv 0 1] + } + set prompt [join $argv " "] +} + +${NS}::frame .t +${NS}::label .t.m -text $prompt -justify center -width 40 +.t.m configure -wraplength 400 +pack .t.m -side top -fill x -padx 20 -pady 20 -expand 1 +pack .t -side top -fill x -ipadx 20 -ipady 20 -expand 1 + +${NS}::frame .b +${NS}::frame .b.left -width 200 +${NS}::button .b.yes -text Yes -command {exit 0} +${NS}::button .b.no -text No -command {exit 1} + +pack .b.left -side left -expand 1 -fill x +pack .b.yes -side left -expand 1 +pack .b.no -side right -expand 1 -ipadx 5 +pack .b -side bottom -fill x -ipadx 20 -ipady 15 + +bind . {exit 0} +bind . {exit 1} + +if {$::tcl_platform(platform) eq {windows}} { + set icopath [file dirname [file normalize $argv0]] + if {[file tail $icopath] eq {git-core}} { + set icopath [file dirname $icopath] + } + set icopath [file dirname $icopath] + set icopath [file join $icopath share git git-for-windows.ico] + if {[file exists $icopath]} { + wm iconbitmap . -default $icopath + } +} + +wm title . $title +tk::PlaceWindow . diff --git a/gitk-git/README.md b/gitk-git/README.md new file mode 100644 index 00000000..2e307463 --- /dev/null +++ b/gitk-git/README.md @@ -0,0 +1,93 @@ +Gitk - The Git Repository Browser +================================= + +Gitk is a graphical Git repository browser. It displays the commit +history of a Git repository as a graph, showing the relationships +between commits, branches, and tags. + +Usage +===== + +To view the history of the current repository: +```bash +gitk +``` + +To view the history of specific files or directories: +```bash +gitk path/to/file +gitk path/to/directory +``` + +To view a specific branch or range of commits: +```bash +gitk branch-name +gitk v1.0..v2.0 +``` + +For more usage examples and options, see the [gitk manual](https://git-scm.com/docs/gitk). + +Building +======== + +Gitk is a Tcl/Tk application. It requires Tcl/Tk to be installed on +your system. + +Running directly +---------------- + +Gitk can be run from the source directory without installation: + +```bash +./gitk +``` + +This allows for quick testing of changes. + +Installation +------------ + +To install system-wide, you can use either `make` or `meson`: + +```bash +# Install to default location ($HOME/bin) +make install + +# Install to system-wide location +sudo make install prefix=/usr/local + +# Install to custom location +make install prefix=/opt/gitk + +# Using Meson +meson setup builddir +meson compile -C builddir +meson install -C builddir +``` + +Both build systems will handle setting the correct Tcl/Tk interpreter +path and installing translation files. + +Contributing +============ + +Contributions are welcome! The preferred method for submitting patches +is via email to the Git mailing list, as this allows for more thorough +review and broader community feedback. However, GitHub pull requests +are also accepted. + +All commits must be signed off (use `git commit --signoff`) and should +have commit messages prefixed with `gitk:`. + +Email Patches +------------- + +Send patches to git@vger.kernel.org and CC j6t@kdbg.org. See the Git +project's [patch submission guidelines](https://git-scm.com/docs/SubmittingPatches) +for detailed instructions on creating and sending patches. + +License +======= + +Gitk is distributed under the GNU General Public License, either +version 2, or (at your option) any later version. diff --git a/odb/streaming.c b/odb/streaming.c new file mode 100644 index 00000000..4a4474f8 --- /dev/null +++ b/odb/streaming.c @@ -0,0 +1,292 @@ +/* + * Copyright (c) 2011, Google Inc. + */ + +#include "git-compat-util.h" +#include "convert.h" +#include "environment.h" +#include "repository.h" +#include "object-file.h" +#include "odb.h" +#include "odb/streaming.h" +#include "replace-object.h" +#include "packfile.h" + +#define FILTER_BUFFER (1024*16) + +/***************************************************************** + * + * Filtered stream + * + *****************************************************************/ + +struct odb_filtered_read_stream { + struct odb_read_stream base; + struct odb_read_stream *upstream; + struct stream_filter *filter; + char ibuf[FILTER_BUFFER]; + char obuf[FILTER_BUFFER]; + int i_end, i_ptr; + int o_end, o_ptr; + int input_finished; +}; + +static int close_istream_filtered(struct odb_read_stream *_fs) +{ + struct odb_filtered_read_stream *fs = (struct odb_filtered_read_stream *)_fs; + free_stream_filter(fs->filter); + return odb_read_stream_close(fs->upstream); +} + +static ssize_t read_istream_filtered(struct odb_read_stream *_fs, char *buf, + size_t sz) +{ + struct odb_filtered_read_stream *fs = (struct odb_filtered_read_stream *)_fs; + size_t filled = 0; + + while (sz) { + /* do we already have filtered output? */ + if (fs->o_ptr < fs->o_end) { + size_t to_move = fs->o_end - fs->o_ptr; + if (sz < to_move) + to_move = sz; + memcpy(buf + filled, fs->obuf + fs->o_ptr, to_move); + fs->o_ptr += to_move; + sz -= to_move; + filled += to_move; + continue; + } + fs->o_end = fs->o_ptr = 0; + + /* do we have anything to feed the filter with? */ + if (fs->i_ptr < fs->i_end) { + size_t to_feed = fs->i_end - fs->i_ptr; + size_t to_receive = FILTER_BUFFER; + if (stream_filter(fs->filter, + fs->ibuf + fs->i_ptr, &to_feed, + fs->obuf, &to_receive)) + return -1; + fs->i_ptr = fs->i_end - to_feed; + fs->o_end = FILTER_BUFFER - to_receive; + continue; + } + + /* tell the filter to drain upon no more input */ + if (fs->input_finished) { + size_t to_receive = FILTER_BUFFER; + if (stream_filter(fs->filter, + NULL, NULL, + fs->obuf, &to_receive)) + return -1; + fs->o_end = FILTER_BUFFER - to_receive; + if (!fs->o_end) + break; + continue; + } + fs->i_end = fs->i_ptr = 0; + + /* refill the input from the upstream */ + if (!fs->input_finished) { + fs->i_end = odb_read_stream_read(fs->upstream, fs->ibuf, FILTER_BUFFER); + if (fs->i_end < 0) + return -1; + if (fs->i_end) + continue; + } + fs->input_finished = 1; + } + return filled; +} + +static struct odb_read_stream *attach_stream_filter(struct odb_read_stream *st, + struct stream_filter *filter) +{ + struct odb_filtered_read_stream *fs; + + CALLOC_ARRAY(fs, 1); + fs->base.close = close_istream_filtered; + fs->base.read = read_istream_filtered; + fs->upstream = st; + fs->filter = filter; + fs->base.size = -1; /* unknown */ + fs->base.type = st->type; + + return &fs->base; +} + +/***************************************************************** + * + * In-core stream + * + *****************************************************************/ + +struct odb_incore_read_stream { + struct odb_read_stream base; + char *buf; /* from odb_read_object_info_extended() */ + unsigned long read_ptr; +}; + +static int close_istream_incore(struct odb_read_stream *_st) +{ + struct odb_incore_read_stream *st = (struct odb_incore_read_stream *)_st; + free(st->buf); + return 0; +} + +static ssize_t read_istream_incore(struct odb_read_stream *_st, char *buf, size_t sz) +{ + struct odb_incore_read_stream *st = (struct odb_incore_read_stream *)_st; + size_t read_size = sz; + size_t remainder = st->base.size - st->read_ptr; + + if (remainder <= read_size) + read_size = remainder; + if (read_size) { + memcpy(buf, st->buf + st->read_ptr, read_size); + st->read_ptr += read_size; + } + return read_size; +} + +static int open_istream_incore(struct odb_read_stream **out, + struct object_database *odb, + const struct object_id *oid) +{ + struct object_info oi = OBJECT_INFO_INIT; + struct odb_incore_read_stream stream = { + .base.close = close_istream_incore, + .base.read = read_istream_incore, + }; + struct odb_incore_read_stream *st; + int ret; + + oi.typep = &stream.base.type; + oi.sizep = &stream.base.size; + oi.contentp = (void **)&stream.buf; + ret = odb_read_object_info_extended(odb, oid, &oi, + OBJECT_INFO_DIE_IF_CORRUPT); + if (ret) + return ret; + + CALLOC_ARRAY(st, 1); + *st = stream; + *out = &st->base; + + return 0; +} + +/***************************************************************************** + * static helpers variables and functions for users of streaming interface + *****************************************************************************/ + +static int istream_source(struct odb_read_stream **out, + struct object_database *odb, + const struct object_id *oid) +{ + struct odb_source *source; + + odb_prepare_alternates(odb); + for (source = odb->sources; source; source = source->next) { + if (!packfile_store_read_object_stream(out, source->packfiles, oid) || + !odb_source_loose_read_object_stream(out, source, oid)) + return 0; + } + + return open_istream_incore(out, odb, oid); +} + +/**************************************************************** + * Users of streaming interface + ****************************************************************/ + +int odb_read_stream_close(struct odb_read_stream *st) +{ + int r = st->close(st); + free(st); + return r; +} + +ssize_t odb_read_stream_read(struct odb_read_stream *st, void *buf, size_t sz) +{ + return st->read(st, buf, sz); +} + +struct odb_read_stream *odb_read_stream_open(struct object_database *odb, + const struct object_id *oid, + struct stream_filter *filter) +{ + struct odb_read_stream *st; + const struct object_id *real = lookup_replace_object(odb->repo, oid); + int ret = istream_source(&st, odb, real); + + if (ret) + return NULL; + + if (filter) { + /* Add "&& !is_null_stream_filter(filter)" for performance */ + struct odb_read_stream *nst = attach_stream_filter(st, filter); + if (!nst) { + odb_read_stream_close(st); + return NULL; + } + st = nst; + } + + return st; +} + +int odb_stream_blob_to_fd(struct object_database *odb, + int fd, + const struct object_id *oid, + struct stream_filter *filter, + int can_seek) +{ + struct odb_read_stream *st; + ssize_t kept = 0; + int result = -1; + + st = odb_read_stream_open(odb, oid, filter); + if (!st) { + if (filter) + free_stream_filter(filter); + return result; + } + if (st->type != OBJ_BLOB) + goto close_and_exit; + for (;;) { + char buf[1024 * 16]; + ssize_t wrote, holeto; + ssize_t readlen = odb_read_stream_read(st, buf, sizeof(buf)); + + if (readlen < 0) + goto close_and_exit; + if (!readlen) + break; + if (can_seek && sizeof(buf) == readlen) { + for (holeto = 0; holeto < readlen; holeto++) + if (buf[holeto]) + break; + if (readlen == holeto) { + kept += holeto; + continue; + } + } + + if (kept && lseek(fd, kept, SEEK_CUR) == (off_t) -1) + goto close_and_exit; + else + kept = 0; + wrote = write_in_full(fd, buf, readlen); + + if (wrote < 0) + goto close_and_exit; + } + if (kept && (lseek(fd, kept - 1, SEEK_CUR) == (off_t) -1 || + xwrite(fd, "", 1) != 1)) + goto close_and_exit; + result = 0; + + close_and_exit: + odb_read_stream_close(st); + return result; +} diff --git a/odb/streaming.h b/odb/streaming.h new file mode 100644 index 00000000..c7861f7e --- /dev/null +++ b/odb/streaming.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2011, Google Inc. + */ +#ifndef STREAMING_H +#define STREAMING_H 1 + +#include "object.h" + +struct object_database; +struct odb_read_stream; +struct stream_filter; + +typedef int (*odb_read_stream_close_fn)(struct odb_read_stream *); +typedef ssize_t (*odb_read_stream_read_fn)(struct odb_read_stream *, char *, size_t); + +/* + * A stream that can be used to read an object from the object database without + * loading all of it into memory. + */ +struct odb_read_stream { + odb_read_stream_close_fn close; + odb_read_stream_read_fn read; + enum object_type type; + unsigned long size; /* inflated size of full object */ +}; + +/* + * Create a new object stream for the given object database. An optional filter + * can be used to transform the object's content. + * + * Returns the stream on success, a `NULL` pointer otherwise. + */ +struct odb_read_stream *odb_read_stream_open(struct object_database *odb, + const struct object_id *oid, + struct stream_filter *filter); + +/* + * Close the given read stream and release all resources associated with it. + * Returns 0 on success, a negative error code otherwise. + */ +int odb_read_stream_close(struct odb_read_stream *stream); + +/* + * Read data from the stream into the buffer. Returns 0 on EOF and the number + * of bytes read on success. Returns a negative error code in case reading from + * the stream fails. + */ +ssize_t odb_read_stream_read(struct odb_read_stream *stream, void *buf, size_t len); + +/* + * Look up the object by its ID and write the full contents to the file + * descriptor. The object must be a blob, or the function will fail. When + * provided, the filter is used to transform the blob contents. + * + * `can_seek` should be set to 1 in case the given file descriptor can be + * seek(3p)'d on. This is used to support files with holes in case a + * significant portion of the blob contains NUL bytes. + * + * Returns a negative error code on failure, 0 on success. + */ +int odb_stream_blob_to_fd(struct object_database *odb, + int fd, + const struct object_id *oid, + struct stream_filter *filter, + int can_seek); + +#endif /* STREAMING_H */ diff --git a/pack-refs.c b/pack-refs.c new file mode 100644 index 00000000..eb6b2ba2 --- /dev/null +++ b/pack-refs.c @@ -0,0 +1,56 @@ +#include "builtin.h" +#include "config.h" +#include "environment.h" +#include "pack-refs.h" +#include "parse-options.h" +#include "refs.h" +#include "revision.h" + +int pack_refs_core(int argc, + const char **argv, + const char *prefix, + struct repository *repo, + const char * const *usage_opts) +{ + struct ref_exclusions excludes = REF_EXCLUSIONS_INIT; + struct string_list included_refs = STRING_LIST_INIT_NODUP; + struct refs_optimize_opts optimize_opts = { + .exclusions = &excludes, + .includes = &included_refs, + .flags = REFS_OPTIMIZE_PRUNE, + }; + struct string_list option_excluded_refs = STRING_LIST_INIT_NODUP; + struct string_list_item *item; + int pack_all = 0; + int ret; + + struct option opts[] = { + OPT_BOOL(0, "all", &pack_all, N_("pack everything")), + OPT_BIT(0, "prune", &optimize_opts.flags, N_("prune loose refs (default)"), REFS_OPTIMIZE_PRUNE), + OPT_BIT(0, "auto", &optimize_opts.flags, N_("auto-pack refs as needed"), REFS_OPTIMIZE_AUTO), + OPT_STRING_LIST(0, "include", optimize_opts.includes, N_("pattern"), + N_("references to include")), + OPT_STRING_LIST(0, "exclude", &option_excluded_refs, N_("pattern"), + N_("references to exclude")), + OPT_END(), + }; + repo_config(repo, git_default_config, NULL); + if (parse_options(argc, argv, prefix, opts, usage_opts, 0)) + usage_with_options(usage_opts, opts); + + for_each_string_list_item(item, &option_excluded_refs) + add_ref_exclusion(optimize_opts.exclusions, item->string); + + if (pack_all) + string_list_append(optimize_opts.includes, "*"); + + if (!optimize_opts.includes->nr) + string_list_append(optimize_opts.includes, "refs/tags/*"); + + ret = refs_optimize(get_main_ref_store(repo), &optimize_opts); + + clear_ref_exclusions(&excludes); + string_list_clear(&included_refs, 0); + string_list_clear(&option_excluded_refs, 0); + return ret; +} diff --git a/pack-refs.h b/pack-refs.h new file mode 100644 index 00000000..5de27e7d --- /dev/null +++ b/pack-refs.h @@ -0,0 +1,23 @@ +#ifndef PACK_REFS_H +#define PACK_REFS_H + +struct repository; + +/* + * Shared usage string for options common to git-pack-refs(1) + * and git-refs-optimize(1). The command-specific part (e.g., "git refs optimize ") + * must be prepended by the caller. + */ +#define PACK_REFS_OPTS \ + "[--all] [--no-prune] [--auto] [--include ] [--exclude ]" + +/* + * The core logic for pack-refs and its clones. + */ +int pack_refs_core(int argc, + const char **argv, + const char *prefix, + struct repository *repo, + const char * const *usage_opts); + +#endif /* PACK_REFS_H */ diff --git a/reftable/fsck.c b/reftable/fsck.c new file mode 100644 index 00000000..26b9115b --- /dev/null +++ b/reftable/fsck.c @@ -0,0 +1,100 @@ +#include "basics.h" +#include "reftable-fsck.h" +#include "reftable-table.h" +#include "stack.h" + +static bool table_has_valid_name(const char *name) +{ + const char *ptr = name; + char *endptr; + + /* strtoull doesn't set errno on success */ + errno = 0; + + strtoull(ptr, &endptr, 16); + if (errno) + return false; + ptr = endptr; + + if (*ptr != '-') + return false; + ptr++; + + strtoull(ptr, &endptr, 16); + if (errno) + return false; + ptr = endptr; + + if (*ptr != '-') + return false; + ptr++; + + strtoul(ptr, &endptr, 16); + if (errno) + return false; + ptr = endptr; + + if (strcmp(ptr, ".ref") && strcmp(ptr, ".log")) + return false; + + return true; +} + +typedef int (*table_check_fn)(struct reftable_table *table, + reftable_fsck_report_fn report_fn, + void *cb_data); + +static int table_check_name(struct reftable_table *table, + reftable_fsck_report_fn report_fn, + void *cb_data) +{ + if (!table_has_valid_name(table->name)) { + struct reftable_fsck_info info; + + info.error = REFTABLE_FSCK_ERROR_TABLE_NAME; + info.msg = "invalid reftable table name"; + info.path = table->name; + + return report_fn(&info, cb_data); + } + + return 0; +} + +static int table_checks(struct reftable_table *table, + reftable_fsck_report_fn report_fn, + reftable_fsck_verbose_fn verbose_fn UNUSED, + void *cb_data) +{ + table_check_fn table_check_fns[] = { + table_check_name, + NULL, + }; + int err = 0; + + for (size_t i = 0; table_check_fns[i]; i++) + err |= table_check_fns[i](table, report_fn, cb_data); + + return err; +} + +int reftable_fsck_check(struct reftable_stack *stack, + reftable_fsck_report_fn report_fn, + reftable_fsck_verbose_fn verbose_fn, + void *cb_data) +{ + struct reftable_buf msg = REFTABLE_BUF_INIT; + int err = 0; + + for (size_t i = 0; i < stack->tables_len; i++) { + reftable_buf_reset(&msg); + reftable_buf_addstr(&msg, "Checking table: "); + reftable_buf_addstr(&msg, stack->tables[i]->name); + verbose_fn(msg.buf, cb_data); + + err |= table_checks(stack->tables[i], report_fn, verbose_fn, cb_data); + } + + reftable_buf_release(&msg); + return err; +} diff --git a/reftable/reftable-fsck.h b/reftable/reftable-fsck.h new file mode 100644 index 00000000..007a392c --- /dev/null +++ b/reftable/reftable-fsck.h @@ -0,0 +1,40 @@ +#ifndef REFTABLE_FSCK_H +#define REFTABLE_FSCK_H + +#include "reftable-stack.h" + +enum reftable_fsck_error { + /* Invalid table name */ + REFTABLE_FSCK_ERROR_TABLE_NAME = 0, + /* Used for bounds checking, must be last */ + REFTABLE_FSCK_MAX_VALUE, +}; + +/* Represents an individual error encountered during the FSCK checks. */ +struct reftable_fsck_info { + enum reftable_fsck_error error; + const char *msg; + const char *path; +}; + +typedef int reftable_fsck_report_fn(struct reftable_fsck_info *info, + void *cb_data); +typedef void reftable_fsck_verbose_fn(const char *msg, void *cb_data); + +/* + * Given a reftable stack, perform consistency checks on the stack. + * + * If an issue is encountered, the issue is reported to the callee via the + * provided 'report_fn'. If the issue is non-recoverable the flow will not + * continue. If it is recoverable, the flow will continue and further issues + * will be reported as identified. + * + * The 'verbose_fn' will be invoked to provide verbose information about + * the progress and state of the consistency checks. + */ +int reftable_fsck_check(struct reftable_stack *stack, + reftable_fsck_report_fn report_fn, + reftable_fsck_verbose_fn verbose_fn, + void *cb_data); + +#endif /* REFTABLE_FSCK_H */ diff --git a/repack-cruft.c b/repack-cruft.c new file mode 100644 index 00000000..0653e887 --- /dev/null +++ b/repack-cruft.c @@ -0,0 +1,98 @@ +#include "git-compat-util.h" +#include "repack.h" +#include "packfile.h" +#include "repository.h" +#include "run-command.h" + +static void combine_small_cruft_packs(FILE *in, off_t combine_cruft_below_size, + struct existing_packs *existing) +{ + struct packed_git *p; + struct strbuf buf = STRBUF_INIT; + size_t i; + + repo_for_each_pack(existing->repo, p) { + if (!(p->is_cruft && p->pack_local)) + continue; + + strbuf_reset(&buf); + strbuf_addstr(&buf, pack_basename(p)); + strbuf_strip_suffix(&buf, ".pack"); + + if (!string_list_has_string(&existing->cruft_packs, buf.buf)) + continue; + + if (p->pack_size < combine_cruft_below_size) { + fprintf(in, "-%s\n", pack_basename(p)); + } else { + existing_packs_retain_cruft(existing, p); + fprintf(in, "%s\n", pack_basename(p)); + } + } + + for (i = 0; i < existing->non_kept_packs.nr; i++) + fprintf(in, "-%s.pack\n", + existing->non_kept_packs.items[i].string); + + strbuf_release(&buf); +} + +int write_cruft_pack(const struct write_pack_opts *opts, + const char *cruft_expiration, + unsigned long combine_cruft_below_size, + struct string_list *names, + struct existing_packs *existing) +{ + struct child_process cmd = CHILD_PROCESS_INIT; + struct string_list_item *item; + FILE *in; + int ret; + const char *pack_prefix = write_pack_opts_pack_prefix(opts); + + prepare_pack_objects(&cmd, opts->po_args, opts->destination); + + strvec_push(&cmd.args, "--cruft"); + if (cruft_expiration) + strvec_pushf(&cmd.args, "--cruft-expiration=%s", + cruft_expiration); + + strvec_push(&cmd.args, "--non-empty"); + + cmd.in = -1; + + ret = start_command(&cmd); + if (ret) + return ret; + + /* + * names has a confusing double use: it both provides the list + * of just-written new packs, and accepts the name of the cruft + * pack we are writing. + * + * By the time it is read here, it contains only the pack(s) + * that were just written, which is exactly the set of packs we + * want to consider kept. + * + * If `--expire-to` is given, the double-use served by `names` + * ensures that the pack written to `--expire-to` excludes any + * objects contained in the cruft pack. + */ + in = xfdopen(cmd.in, "w"); + for_each_string_list_item(item, names) + fprintf(in, "%s-%s.pack\n", pack_prefix, item->string); + if (combine_cruft_below_size && !cruft_expiration) { + combine_small_cruft_packs(in, combine_cruft_below_size, + existing); + } else { + for_each_string_list_item(item, &existing->non_kept_packs) + fprintf(in, "-%s.pack\n", item->string); + for_each_string_list_item(item, &existing->cruft_packs) + fprintf(in, "-%s.pack\n", item->string); + } + for_each_string_list_item(item, &existing->kept_packs) + fprintf(in, "%s.pack\n", item->string); + fclose(in); + + return finish_pack_objects_cmd(existing->repo->hash_algo, opts, &cmd, + names); +} diff --git a/repack-filtered.c b/repack-filtered.c new file mode 100644 index 00000000..edcf7667 --- /dev/null +++ b/repack-filtered.c @@ -0,0 +1,51 @@ +#include "git-compat-util.h" +#include "repack.h" +#include "repository.h" +#include "run-command.h" +#include "string-list.h" + +int write_filtered_pack(const struct write_pack_opts *opts, + struct existing_packs *existing, + struct string_list *names) +{ + struct child_process cmd = CHILD_PROCESS_INIT; + struct string_list_item *item; + FILE *in; + int ret; + const char *caret; + const char *pack_prefix = write_pack_opts_pack_prefix(opts); + + prepare_pack_objects(&cmd, opts->po_args, opts->destination); + + strvec_push(&cmd.args, "--stdin-packs"); + + for_each_string_list_item(item, &existing->kept_packs) + strvec_pushf(&cmd.args, "--keep-pack=%s", item->string); + + cmd.in = -1; + + ret = start_command(&cmd); + if (ret) + return ret; + + /* + * Here 'names' contains only the pack(s) that were just + * written, which is exactly the packs we want to keep. Also + * 'existing_kept_packs' already contains the packs in + * 'keep_pack_list'. + */ + in = xfdopen(cmd.in, "w"); + for_each_string_list_item(item, names) + fprintf(in, "^%s-%s.pack\n", pack_prefix, item->string); + for_each_string_list_item(item, &existing->non_kept_packs) + fprintf(in, "%s.pack\n", item->string); + for_each_string_list_item(item, &existing->cruft_packs) + fprintf(in, "%s.pack\n", item->string); + caret = opts->po_args->pack_kept_objects ? "" : "^"; + for_each_string_list_item(item, &existing->kept_packs) + fprintf(in, "%s%s.pack\n", caret, item->string); + fclose(in); + + return finish_pack_objects_cmd(existing->repo->hash_algo, opts, &cmd, + names); +} diff --git a/repack-geometry.c b/repack-geometry.c new file mode 100644 index 00000000..7cebd0cb --- /dev/null +++ b/repack-geometry.c @@ -0,0 +1,261 @@ +#define DISABLE_SIGN_COMPARE_WARNINGS + +#include "git-compat-util.h" +#include "repack.h" +#include "repository.h" +#include "hex.h" +#include "packfile.h" + +static uint32_t pack_geometry_weight(struct packed_git *p) +{ + if (open_pack_index(p)) + die(_("cannot open index for %s"), p->pack_name); + return p->num_objects; +} + +static int pack_geometry_cmp(const void *va, const void *vb) +{ + uint32_t aw = pack_geometry_weight(*(struct packed_git **)va), + bw = pack_geometry_weight(*(struct packed_git **)vb); + + if (aw < bw) + return -1; + if (aw > bw) + return 1; + return 0; +} + +void pack_geometry_init(struct pack_geometry *geometry, + struct existing_packs *existing, + const struct pack_objects_args *args) +{ + struct packed_git *p; + struct strbuf buf = STRBUF_INIT; + + repo_for_each_pack(existing->repo, p) { + if (args->local && !p->pack_local) + /* + * When asked to only repack local packfiles we skip + * over any packfiles that are borrowed from alternate + * object directories. + */ + continue; + + if (!args->pack_kept_objects) { + /* + * Any pack that has its pack_keep bit set will + * appear in existing->kept_packs below, but + * this saves us from doing a more expensive + * check. + */ + if (p->pack_keep) + continue; + + /* + * The pack may be kept via the --keep-pack + * option; check 'existing->kept_packs' to + * determine whether to ignore it. + */ + strbuf_reset(&buf); + strbuf_addstr(&buf, pack_basename(p)); + strbuf_strip_suffix(&buf, ".pack"); + + if (string_list_has_string(&existing->kept_packs, buf.buf)) + continue; + } + if (p->is_cruft) + continue; + + if (p->pack_promisor) { + ALLOC_GROW(geometry->promisor_pack, + geometry->promisor_pack_nr + 1, + geometry->promisor_pack_alloc); + + geometry->promisor_pack[geometry->promisor_pack_nr] = p; + geometry->promisor_pack_nr++; + } else { + ALLOC_GROW(geometry->pack, + geometry->pack_nr + 1, + geometry->pack_alloc); + + geometry->pack[geometry->pack_nr] = p; + geometry->pack_nr++; + } + } + + QSORT(geometry->pack, geometry->pack_nr, pack_geometry_cmp); + QSORT(geometry->promisor_pack, geometry->promisor_pack_nr, pack_geometry_cmp); + strbuf_release(&buf); +} + +static uint32_t compute_pack_geometry_split(struct packed_git **pack, size_t pack_nr, + int split_factor) +{ + uint32_t i; + uint32_t split; + off_t total_size = 0; + + if (!pack_nr) + return 0; + + /* + * First, count the number of packs (in descending order of size) which + * already form a geometric progression. + */ + for (i = pack_nr - 1; i > 0; i--) { + struct packed_git *ours = pack[i]; + struct packed_git *prev = pack[i - 1]; + + if (unsigned_mult_overflows(split_factor, + pack_geometry_weight(prev))) + die(_("pack %s too large to consider in geometric " + "progression"), + prev->pack_name); + + if (pack_geometry_weight(ours) < + split_factor * pack_geometry_weight(prev)) + break; + } + + split = i; + + if (split) { + /* + * Move the split one to the right, since the top element in the + * last-compared pair can't be in the progression. Only do this + * when we split in the middle of the array (otherwise if we got + * to the end, then the split is in the right place). + */ + split++; + } + + /* + * Then, anything to the left of 'split' must be in a new pack. But, + * creating that new pack may cause packs in the heavy half to no longer + * form a geometric progression. + * + * Compute an expected size of the new pack, and then determine how many + * packs in the heavy half need to be joined into it (if any) to restore + * the geometric progression. + */ + for (i = 0; i < split; i++) { + struct packed_git *p = pack[i]; + + if (unsigned_add_overflows(total_size, pack_geometry_weight(p))) + die(_("pack %s too large to roll up"), p->pack_name); + total_size += pack_geometry_weight(p); + } + for (i = split; i < pack_nr; i++) { + struct packed_git *ours = pack[i]; + + if (unsigned_mult_overflows(split_factor, total_size)) + die(_("pack %s too large to roll up"), ours->pack_name); + + if (pack_geometry_weight(ours) < split_factor * total_size) { + if (unsigned_add_overflows(total_size, + pack_geometry_weight(ours))) + die(_("pack %s too large to roll up"), + ours->pack_name); + + split++; + total_size += pack_geometry_weight(ours); + } else + break; + } + + return split; +} + +void pack_geometry_split(struct pack_geometry *geometry) +{ + geometry->split = compute_pack_geometry_split(geometry->pack, geometry->pack_nr, + geometry->split_factor); + geometry->promisor_split = compute_pack_geometry_split(geometry->promisor_pack, + geometry->promisor_pack_nr, + geometry->split_factor); +} + +struct packed_git *pack_geometry_preferred_pack(struct pack_geometry *geometry) +{ + uint32_t i; + + if (!geometry) { + /* + * No geometry means either an all-into-one repack (in which + * case there is only one pack left and it is the largest) or an + * incremental one. + * + * If repacking incrementally, then we could check the size of + * all packs to determine which should be preferred, but leave + * this for later. + */ + return NULL; + } + if (geometry->split == geometry->pack_nr) + return NULL; + + /* + * The preferred pack is the largest pack above the split line. In + * other words, it is the largest pack that does not get rolled up in + * the geometric repack. + */ + for (i = geometry->pack_nr; i > geometry->split; i--) + /* + * A pack that is not local would never be included in a + * multi-pack index. We thus skip over any non-local packs. + */ + if (geometry->pack[i - 1]->pack_local) + return geometry->pack[i - 1]; + + return NULL; +} + +static void remove_redundant_packs(struct packed_git **pack, + uint32_t pack_nr, + struct string_list *names, + struct existing_packs *existing, + const char *packdir) +{ + const struct git_hash_algo *algop = existing->repo->hash_algo; + struct strbuf buf = STRBUF_INIT; + uint32_t i; + + for (i = 0; i < pack_nr; i++) { + struct packed_git *p = pack[i]; + if (string_list_has_string(names, hash_to_hex_algop(p->hash, + algop))) + continue; + + strbuf_reset(&buf); + strbuf_addstr(&buf, pack_basename(p)); + strbuf_strip_suffix(&buf, ".pack"); + + if ((p->pack_keep) || + (string_list_has_string(&existing->kept_packs, buf.buf))) + continue; + + repack_remove_redundant_pack(existing->repo, packdir, buf.buf); + } + + strbuf_release(&buf); +} + +void pack_geometry_remove_redundant(struct pack_geometry *geometry, + struct string_list *names, + struct existing_packs *existing, + const char *packdir) +{ + remove_redundant_packs(geometry->pack, geometry->split, + names, existing, packdir); + remove_redundant_packs(geometry->promisor_pack, geometry->promisor_split, + names, existing, packdir); +} + +void pack_geometry_release(struct pack_geometry *geometry) +{ + if (!geometry) + return; + + free(geometry->pack); + free(geometry->promisor_pack); +} diff --git a/repack-midx.c b/repack-midx.c new file mode 100644 index 00000000..74bdfa3a --- /dev/null +++ b/repack-midx.c @@ -0,0 +1,370 @@ +#include "git-compat-util.h" +#include "repack.h" +#include "hash.h" +#include "hex.h" +#include "odb.h" +#include "oidset.h" +#include "pack-bitmap.h" +#include "refs.h" +#include "run-command.h" +#include "tempfile.h" + +struct midx_snapshot_ref_data { + struct repository *repo; + struct tempfile *f; + struct oidset seen; + int preferred; +}; + +static int midx_snapshot_ref_one(const struct reference *ref, void *_data) +{ + struct midx_snapshot_ref_data *data = _data; + const struct object_id *maybe_peeled = ref->oid; + struct object_id peeled; + + if (!reference_get_peeled_oid(data->repo, ref, &peeled)) + maybe_peeled = &peeled; + + if (oidset_insert(&data->seen, maybe_peeled)) + return 0; /* already seen */ + + if (odb_read_object_info(data->repo->objects, maybe_peeled, NULL) != OBJ_COMMIT) + return 0; + + fprintf(data->f->fp, "%s%s\n", data->preferred ? "+" : "", + oid_to_hex(maybe_peeled)); + + return 0; +} + +void midx_snapshot_refs(struct repository *repo, struct tempfile *f) +{ + struct midx_snapshot_ref_data data; + const struct string_list *preferred = bitmap_preferred_tips(repo); + + data.repo = repo; + data.f = f; + data.preferred = 0; + oidset_init(&data.seen, 0); + + if (!fdopen_tempfile(f, "w")) + die(_("could not open tempfile %s for writing"), + get_tempfile_path(f)); + + if (preferred) { + struct string_list_item *item; + + data.preferred = 1; + for_each_string_list_item(item, preferred) + refs_for_each_ref_in(get_main_ref_store(repo), + item->string, + midx_snapshot_ref_one, &data); + data.preferred = 0; + } + + refs_for_each_ref(get_main_ref_store(repo), + midx_snapshot_ref_one, &data); + + if (close_tempfile_gently(f)) { + int save_errno = errno; + delete_tempfile(&f); + errno = save_errno; + die_errno(_("could not close refs snapshot tempfile")); + } + + oidset_clear(&data.seen); +} + +static int midx_has_unknown_packs(struct string_list *include, + struct pack_geometry *geometry, + struct existing_packs *existing) +{ + struct string_list_item *item; + + string_list_sort(include); + + for_each_string_list_item(item, &existing->midx_packs) { + const char *pack_name = item->string; + + /* + * Determine whether or not each MIDX'd pack from the existing + * MIDX (if any) is represented in the new MIDX. For each pack + * in the MIDX, it must either be: + * + * - In the "include" list of packs to be included in the new + * MIDX. Note this function is called before the include + * list is populated with any cruft pack(s). + * + * - Below the geometric split line (if using pack geometry), + * indicating that the pack won't be included in the new + * MIDX, but its contents were rolled up as part of the + * geometric repack. + * + * - In the existing non-kept packs list (if not using pack + * geometry), and marked as non-deleted. + */ + if (string_list_has_string(include, pack_name)) { + continue; + } else if (geometry) { + struct strbuf buf = STRBUF_INIT; + uint32_t j; + + for (j = 0; j < geometry->split; j++) { + strbuf_reset(&buf); + strbuf_addstr(&buf, pack_basename(geometry->pack[j])); + strbuf_strip_suffix(&buf, ".pack"); + strbuf_addstr(&buf, ".idx"); + + if (!strcmp(pack_name, buf.buf)) { + strbuf_release(&buf); + break; + } + } + + strbuf_release(&buf); + + if (j < geometry->split) + continue; + } else { + struct string_list_item *item; + + item = string_list_lookup(&existing->non_kept_packs, + pack_name); + if (item && !existing_pack_is_marked_for_deletion(item)) + continue; + } + + /* + * If we got to this point, the MIDX includes some pack that we + * don't know about. + */ + return 1; + } + + return 0; +} + +static void midx_included_packs(struct string_list *include, + struct repack_write_midx_opts *opts) +{ + struct existing_packs *existing = opts->existing; + struct pack_geometry *geometry = opts->geometry; + struct string_list *names = opts->names; + struct string_list_item *item; + struct strbuf buf = STRBUF_INIT; + + for_each_string_list_item(item, &existing->kept_packs) { + strbuf_reset(&buf); + strbuf_addf(&buf, "%s.idx", item->string); + string_list_insert(include, buf.buf); + } + + for_each_string_list_item(item, names) { + strbuf_reset(&buf); + strbuf_addf(&buf, "pack-%s.idx", item->string); + string_list_insert(include, buf.buf); + } + + if (geometry->split_factor) { + uint32_t i; + + for (i = geometry->split; i < geometry->pack_nr; i++) { + struct packed_git *p = geometry->pack[i]; + + /* + * The multi-pack index never refers to packfiles part + * of an alternate object database, so we skip these. + * While git-multi-pack-index(1) would silently ignore + * them anyway, this allows us to skip executing the + * command completely when we have only non-local + * packfiles. + */ + if (!p->pack_local) + continue; + + strbuf_reset(&buf); + strbuf_addstr(&buf, pack_basename(p)); + strbuf_strip_suffix(&buf, ".pack"); + strbuf_addstr(&buf, ".idx"); + + string_list_insert(include, buf.buf); + } + } else { + for_each_string_list_item(item, &existing->non_kept_packs) { + if (existing_pack_is_marked_for_deletion(item)) + continue; + + strbuf_reset(&buf); + strbuf_addf(&buf, "%s.idx", item->string); + string_list_insert(include, buf.buf); + } + } + + if (opts->midx_must_contain_cruft || + midx_has_unknown_packs(include, geometry, existing)) { + /* + * If there are one or more unknown pack(s) present (see + * midx_has_unknown_packs() for what makes a pack + * "unknown") in the MIDX before the repack, keep them + * as they may be required to form a reachability + * closure if the MIDX is bitmapped. + * + * For example, a cruft pack can be required to form a + * reachability closure if the MIDX is bitmapped and one + * or more of the bitmap's selected commits reaches a + * once-cruft object that was later made reachable. + */ + for_each_string_list_item(item, &existing->cruft_packs) { + /* + * When doing a --geometric repack, there is no + * need to check for deleted packs, since we're + * by definition not doing an ALL_INTO_ONE + * repack (hence no packs will be deleted). + * Otherwise we must check for and exclude any + * packs which are enqueued for deletion. + * + * So we could omit the conditional below in the + * --geometric case, but doing so is unnecessary + * since no packs are marked as pending + * deletion (since we only call + * `existing_packs_mark_for_deletion()` when + * doing an all-into-one repack). + */ + if (existing_pack_is_marked_for_deletion(item)) + continue; + + strbuf_reset(&buf); + strbuf_addf(&buf, "%s.idx", item->string); + string_list_insert(include, buf.buf); + } + } else { + /* + * Modern versions of Git (with the appropriate + * configuration setting) will write new copies of + * once-cruft objects when doing a --geometric repack. + * + * If the MIDX has no cruft pack, new packs written + * during a --geometric repack will not rely on the + * cruft pack to form a reachability closure, so we can + * avoid including them in the MIDX in that case. + */ + ; + } + + strbuf_release(&buf); +} + +static void remove_redundant_bitmaps(struct string_list *include, + const char *packdir) +{ + struct strbuf path = STRBUF_INIT; + struct string_list_item *item; + size_t packdir_len; + + strbuf_addstr(&path, packdir); + strbuf_addch(&path, '/'); + packdir_len = path.len; + + /* + * Remove any pack bitmaps corresponding to packs which are now + * included in the MIDX. + */ + for_each_string_list_item(item, include) { + strbuf_addstr(&path, item->string); + strbuf_strip_suffix(&path, ".idx"); + strbuf_addstr(&path, ".bitmap"); + + if (unlink(path.buf) && errno != ENOENT) + warning_errno(_("could not remove stale bitmap: %s"), + path.buf); + + strbuf_setlen(&path, packdir_len); + } + strbuf_release(&path); +} + +int write_midx_included_packs(struct repack_write_midx_opts *opts) +{ + struct child_process cmd = CHILD_PROCESS_INIT; + struct string_list include = STRING_LIST_INIT_DUP; + struct string_list_item *item; + struct packed_git *preferred = pack_geometry_preferred_pack(opts->geometry); + FILE *in; + int ret = 0; + + midx_included_packs(&include, opts); + if (!include.nr) + goto done; + + cmd.in = -1; + cmd.git_cmd = 1; + + strvec_push(&cmd.args, "multi-pack-index"); + strvec_pushl(&cmd.args, "write", "--stdin-packs", NULL); + + if (opts->show_progress) + strvec_push(&cmd.args, "--progress"); + else + strvec_push(&cmd.args, "--no-progress"); + + if (opts->write_bitmaps) + strvec_push(&cmd.args, "--bitmap"); + + if (preferred) + strvec_pushf(&cmd.args, "--preferred-pack=%s", + pack_basename(preferred)); + else if (opts->names->nr) { + /* The largest pack was repacked, meaning that either + * one or two packs exist depending on whether the + * repository has a cruft pack or not. + * + * Select the non-cruft one as preferred to encourage + * pack-reuse among packs containing reachable objects + * over unreachable ones. + * + * (Note we could write multiple packs here if + * `--max-pack-size` was given, but any one of them + * will suffice, so pick the first one.) + */ + for_each_string_list_item(item, opts->names) { + struct generated_pack *pack = item->util; + if (generated_pack_has_ext(pack, ".mtimes")) + continue; + + strvec_pushf(&cmd.args, "--preferred-pack=pack-%s.pack", + item->string); + break; + } + } else { + /* + * No packs were kept, and no packs were written. The + * only thing remaining are .keep packs (unless + * --pack-kept-objects was given). + * + * Set the `--preferred-pack` arbitrarily here. + */ + ; + } + + if (opts->refs_snapshot) + strvec_pushf(&cmd.args, "--refs-snapshot=%s", + opts->refs_snapshot); + + ret = start_command(&cmd); + if (ret) + goto done; + + in = xfdopen(cmd.in, "w"); + for_each_string_list_item(item, &include) + fprintf(in, "%s\n", item->string); + fclose(in); + + ret = finish_command(&cmd); +done: + if (!ret && opts->write_bitmaps) + remove_redundant_bitmaps(&include, opts->packdir); + + string_list_clear(&include, 0); + + return ret; +} diff --git a/repack-promisor.c b/repack-promisor.c new file mode 100644 index 00000000..73af57bc --- /dev/null +++ b/repack-promisor.c @@ -0,0 +1,139 @@ +#include "git-compat-util.h" +#include "repack.h" +#include "hex.h" +#include "pack.h" +#include "packfile.h" +#include "path.h" +#include "repository.h" +#include "run-command.h" + +struct write_oid_context { + struct child_process *cmd; + const struct git_hash_algo *algop; +}; + +/* + * Write oid to the given struct child_process's stdin, starting it first if + * necessary. + */ +static int write_oid(const struct object_id *oid, + struct packed_git *pack UNUSED, + uint32_t pos UNUSED, void *data) +{ + struct write_oid_context *ctx = data; + struct child_process *cmd = ctx->cmd; + + if (cmd->in == -1) { + if (start_command(cmd)) + die(_("could not start pack-objects to repack promisor objects")); + } + + if (write_in_full(cmd->in, oid_to_hex(oid), ctx->algop->hexsz) < 0 || + write_in_full(cmd->in, "\n", 1) < 0) + die(_("failed to feed promisor objects to pack-objects")); + return 0; +} + +static void finish_repacking_promisor_objects(struct repository *repo, + struct child_process *cmd, + struct string_list *names, + const char *packtmp) +{ + struct strbuf line = STRBUF_INIT; + FILE *out; + + close(cmd->in); + + out = xfdopen(cmd->out, "r"); + while (strbuf_getline_lf(&line, out) != EOF) { + struct string_list_item *item; + char *promisor_name; + + if (line.len != repo->hash_algo->hexsz) + die(_("repack: Expecting full hex object ID lines only from pack-objects.")); + item = string_list_append(names, line.buf); + + /* + * pack-objects creates the .pack and .idx files, but not the + * .promisor file. Create the .promisor file, which is empty. + * + * NEEDSWORK: fetch-pack sometimes generates non-empty + * .promisor files containing the ref names and associated + * hashes at the point of generation of the corresponding + * packfile, but this would not preserve their contents. Maybe + * concatenate the contents of all .promisor files instead of + * just creating a new empty file. + */ + promisor_name = mkpathdup("%s-%s.promisor", packtmp, + line.buf); + write_promisor_file(promisor_name, NULL, 0); + + item->util = generated_pack_populate(item->string, packtmp); + + free(promisor_name); + } + + fclose(out); + if (finish_command(cmd)) + die(_("could not finish pack-objects to repack promisor objects")); + strbuf_release(&line); +} + +void repack_promisor_objects(struct repository *repo, + const struct pack_objects_args *args, + struct string_list *names, const char *packtmp) +{ + struct write_oid_context ctx; + struct child_process cmd = CHILD_PROCESS_INIT; + + prepare_pack_objects(&cmd, args, packtmp); + cmd.in = -1; + + /* + * NEEDSWORK: Giving pack-objects only the OIDs without any ordering + * hints may result in suboptimal deltas in the resulting pack. See if + * the OIDs can be sent with fake paths such that pack-objects can use a + * {type -> existing pack order} ordering when computing deltas instead + * of a {type -> size} ordering, which may produce better deltas. + */ + ctx.cmd = &cmd; + ctx.algop = repo->hash_algo; + for_each_packed_object(repo, write_oid, &ctx, + FOR_EACH_OBJECT_PROMISOR_ONLY); + + if (cmd.in == -1) { + /* No packed objects; cmd was never started */ + child_process_clear(&cmd); + return; + } + + finish_repacking_promisor_objects(repo, &cmd, names, packtmp); +} + +void pack_geometry_repack_promisors(struct repository *repo, + const struct pack_objects_args *args, + const struct pack_geometry *geometry, + struct string_list *names, + const char *packtmp) +{ + struct child_process cmd = CHILD_PROCESS_INIT; + FILE *in; + + if (!geometry->promisor_split) + return; + + prepare_pack_objects(&cmd, args, packtmp); + strvec_push(&cmd.args, "--stdin-packs"); + cmd.in = -1; + if (start_command(&cmd)) + die(_("could not start pack-objects to repack promisor packs")); + + in = xfdopen(cmd.in, "w"); + for (size_t i = 0; i < geometry->promisor_split; i++) + fprintf(in, "%s\n", pack_basename(geometry->promisor_pack[i])); + for (size_t i = geometry->promisor_split; i < geometry->promisor_pack_nr; i++) + fprintf(in, "^%s\n", pack_basename(geometry->promisor_pack[i])); + fclose(in); + + finish_repacking_promisor_objects(repo, &cmd, names, packtmp); +} diff --git a/repack.c b/repack.c new file mode 100644 index 00000000..59684102 --- /dev/null +++ b/repack.c @@ -0,0 +1,359 @@ +#include "git-compat-util.h" +#include "dir.h" +#include "midx.h" +#include "odb.h" +#include "packfile.h" +#include "path.h" +#include "repack.h" +#include "repository.h" +#include "run-command.h" +#include "tempfile.h" + +void prepare_pack_objects(struct child_process *cmd, + const struct pack_objects_args *args, + const char *out) +{ + strvec_push(&cmd->args, "pack-objects"); + if (args->window) + strvec_pushf(&cmd->args, "--window=%s", args->window); + if (args->window_memory) + strvec_pushf(&cmd->args, "--window-memory=%s", args->window_memory); + if (args->depth) + strvec_pushf(&cmd->args, "--depth=%s", args->depth); + if (args->threads) + strvec_pushf(&cmd->args, "--threads=%s", args->threads); + if (args->max_pack_size) + strvec_pushf(&cmd->args, "--max-pack-size=%lu", args->max_pack_size); + if (args->no_reuse_delta) + strvec_pushf(&cmd->args, "--no-reuse-delta"); + if (args->no_reuse_object) + strvec_pushf(&cmd->args, "--no-reuse-object"); + if (args->name_hash_version) + strvec_pushf(&cmd->args, "--name-hash-version=%d", args->name_hash_version); + if (args->path_walk) + strvec_pushf(&cmd->args, "--path-walk"); + if (args->local) + strvec_push(&cmd->args, "--local"); + if (args->quiet) + strvec_push(&cmd->args, "--quiet"); + if (args->delta_base_offset) + strvec_push(&cmd->args, "--delta-base-offset"); + if (!args->pack_kept_objects) + strvec_push(&cmd->args, "--honor-pack-keep"); + strvec_push(&cmd->args, out); + cmd->git_cmd = 1; + cmd->out = -1; +} + +void pack_objects_args_release(struct pack_objects_args *args) +{ + free(args->window); + free(args->window_memory); + free(args->depth); + free(args->threads); + list_objects_filter_release(&args->filter_options); +} + +void repack_remove_redundant_pack(struct repository *repo, const char *dir_name, + const char *base_name) +{ + struct strbuf buf = STRBUF_INIT; + struct odb_source *source = repo->objects->sources; + struct multi_pack_index *m = get_multi_pack_index(source); + strbuf_addf(&buf, "%s.pack", base_name); + if (m && source->local && midx_contains_pack(m, buf.buf)) + clear_midx_file(repo); + strbuf_insertf(&buf, 0, "%s/", dir_name); + unlink_pack_path(buf.buf, 1); + strbuf_release(&buf); +} + +const char *write_pack_opts_pack_prefix(const struct write_pack_opts *opts) +{ + const char *pack_prefix; + if (!skip_prefix(opts->packtmp, opts->packdir, &pack_prefix)) + die(_("pack prefix %s does not begin with objdir %s"), + opts->packtmp, opts->packdir); + if (*pack_prefix == '/') + pack_prefix++; + return pack_prefix; +} + +bool write_pack_opts_is_local(const struct write_pack_opts *opts) +{ + return starts_with(opts->destination, opts->packdir); +} + +int finish_pack_objects_cmd(const struct git_hash_algo *algop, + const struct write_pack_opts *opts, + struct child_process *cmd, + struct string_list *names) +{ + FILE *out; + bool local = write_pack_opts_is_local(opts); + struct strbuf line = STRBUF_INIT; + + out = xfdopen(cmd->out, "r"); + while (strbuf_getline_lf(&line, out) != EOF) { + struct string_list_item *item; + + if (line.len != algop->hexsz) + die(_("repack: Expecting full hex object ID lines only " + "from pack-objects.")); + /* + * Avoid putting packs written outside of the repository in the + * list of names. + */ + if (local) { + item = string_list_append(names, line.buf); + item->util = generated_pack_populate(line.buf, + opts->packtmp); + } + } + fclose(out); + + strbuf_release(&line); + + return finish_command(cmd); +} + +#define DELETE_PACK 1 +#define RETAIN_PACK 2 + +void existing_packs_collect(struct existing_packs *existing, + const struct string_list *extra_keep) +{ + struct packed_git *p; + struct strbuf buf = STRBUF_INIT; + + repo_for_each_pack(existing->repo, p) { + size_t i; + const char *base; + + if (p->multi_pack_index) + string_list_append(&existing->midx_packs, + pack_basename(p)); + if (!p->pack_local) + continue; + + base = pack_basename(p); + + for (i = 0; i < extra_keep->nr; i++) + if (!fspathcmp(base, extra_keep->items[i].string)) + break; + + strbuf_reset(&buf); + strbuf_addstr(&buf, base); + strbuf_strip_suffix(&buf, ".pack"); + + if ((extra_keep->nr > 0 && i < extra_keep->nr) || p->pack_keep) + string_list_append(&existing->kept_packs, buf.buf); + else if (p->is_cruft) + string_list_append(&existing->cruft_packs, buf.buf); + else + string_list_append(&existing->non_kept_packs, buf.buf); + } + + string_list_sort(&existing->kept_packs); + string_list_sort(&existing->non_kept_packs); + string_list_sort(&existing->cruft_packs); + string_list_sort(&existing->midx_packs); + strbuf_release(&buf); +} + +int existing_packs_has_non_kept(const struct existing_packs *existing) +{ + return existing->non_kept_packs.nr || existing->cruft_packs.nr; +} + +static void existing_pack_mark_for_deletion(struct string_list_item *item) +{ + item->util = (void*)((uintptr_t)item->util | DELETE_PACK); +} + +static void existing_pack_unmark_for_deletion(struct string_list_item *item) +{ + item->util = (void*)((uintptr_t)item->util & ~DELETE_PACK); +} + +int existing_pack_is_marked_for_deletion(struct string_list_item *item) +{ + return (uintptr_t)item->util & DELETE_PACK; +} + +static void existing_packs_mark_retained(struct string_list_item *item) +{ + item->util = (void*)((uintptr_t)item->util | RETAIN_PACK); +} + +static int existing_pack_is_retained(struct string_list_item *item) +{ + return (uintptr_t)item->util & RETAIN_PACK; +} + +static void existing_packs_mark_for_deletion_1(const struct git_hash_algo *algop, + struct string_list *names, + struct string_list *list) +{ + struct string_list_item *item; + const size_t hexsz = algop->hexsz; + + for_each_string_list_item(item, list) { + char *sha1; + size_t len = strlen(item->string); + if (len < hexsz) + continue; + sha1 = item->string + len - hexsz; + + if (existing_pack_is_retained(item)) { + existing_pack_unmark_for_deletion(item); + } else if (!string_list_has_string(names, sha1)) { + /* + * Mark this pack for deletion, which ensures + * that this pack won't be included in a MIDX + * (if `--write-midx` was given) and that we + * will actually delete this pack (if `-d` was + * given). + */ + existing_pack_mark_for_deletion(item); + } + } +} + +void existing_packs_retain_cruft(struct existing_packs *existing, + struct packed_git *cruft) +{ + struct strbuf buf = STRBUF_INIT; + struct string_list_item *item; + + strbuf_addstr(&buf, pack_basename(cruft)); + strbuf_strip_suffix(&buf, ".pack"); + + item = string_list_lookup(&existing->cruft_packs, buf.buf); + if (!item) + BUG("could not find cruft pack '%s'", pack_basename(cruft)); + + existing_packs_mark_retained(item); + strbuf_release(&buf); +} + +void existing_packs_mark_for_deletion(struct existing_packs *existing, + struct string_list *names) + +{ + const struct git_hash_algo *algop = existing->repo->hash_algo; + existing_packs_mark_for_deletion_1(algop, names, + &existing->non_kept_packs); + existing_packs_mark_for_deletion_1(algop, names, + &existing->cruft_packs); +} + +static void remove_redundant_packs_1(struct repository *repo, + struct string_list *packs, + const char *packdir) +{ + struct string_list_item *item; + for_each_string_list_item(item, packs) { + if (!existing_pack_is_marked_for_deletion(item)) + continue; + repack_remove_redundant_pack(repo, packdir, item->string); + } +} + +void existing_packs_remove_redundant(struct existing_packs *existing, + const char *packdir) +{ + remove_redundant_packs_1(existing->repo, &existing->non_kept_packs, + packdir); + remove_redundant_packs_1(existing->repo, &existing->cruft_packs, + packdir); +} + +void existing_packs_release(struct existing_packs *existing) +{ + string_list_clear(&existing->kept_packs, 0); + string_list_clear(&existing->non_kept_packs, 0); + string_list_clear(&existing->cruft_packs, 0); + string_list_clear(&existing->midx_packs, 0); +} + +static struct { + const char *name; + unsigned optional:1; +} exts[] = { + {".pack"}, + {".rev", 1}, + {".mtimes", 1}, + {".bitmap", 1}, + {".promisor", 1}, + {".idx"}, +}; + +struct generated_pack { + struct tempfile *tempfiles[ARRAY_SIZE(exts)]; +}; + +struct generated_pack *generated_pack_populate(const char *name, + const char *packtmp) +{ + struct stat statbuf; + struct strbuf path = STRBUF_INIT; + struct generated_pack *pack = xcalloc(1, sizeof(*pack)); + size_t i; + + for (i = 0; i < ARRAY_SIZE(exts); i++) { + strbuf_reset(&path); + strbuf_addf(&path, "%s-%s%s", packtmp, name, exts[i].name); + + if (stat(path.buf, &statbuf)) + continue; + + pack->tempfiles[i] = register_tempfile(path.buf); + } + + strbuf_release(&path); + return pack; +} + +int generated_pack_has_ext(const struct generated_pack *pack, const char *ext) +{ + size_t i; + for (i = 0; i < ARRAY_SIZE(exts); i++) { + if (strcmp(exts[i].name, ext)) + continue; + return !!pack->tempfiles[i]; + } + BUG("unknown pack extension: '%s'", ext); +} + +void generated_pack_install(struct generated_pack *pack, const char *name, + const char *packdir, const char *packtmp) +{ + size_t ext; + for (ext = 0; ext < ARRAY_SIZE(exts); ext++) { + char *fname; + + fname = mkpathdup("%s/pack-%s%s", packdir, name, + exts[ext].name); + + if (pack->tempfiles[ext]) { + const char *fname_old = get_tempfile_path(pack->tempfiles[ext]); + struct stat statbuffer; + + if (!stat(fname_old, &statbuffer)) { + statbuffer.st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH); + chmod(fname_old, statbuffer.st_mode); + } + + if (rename_tempfile(&pack->tempfiles[ext], fname)) + die_errno(_("renaming pack to '%s' failed"), + fname); + } else if (!exts[ext].optional) + die(_("pack-objects did not write a '%s' file for pack %s-%s"), + exts[ext].name, packtmp, name); + else if (unlink(fname) < 0 && errno != ENOENT) + die_errno(_("could not unlink: %s"), fname); + + free(fname); + } +} diff --git a/repack.h b/repack.h new file mode 100644 index 00000000..bc9f2e1a --- /dev/null +++ b/repack.h @@ -0,0 +1,156 @@ +#ifndef REPACK_H +#define REPACK_H + +#include "list-objects-filter-options.h" +#include "string-list.h" + +struct pack_objects_args { + char *window; + char *window_memory; + char *depth; + char *threads; + unsigned long max_pack_size; + int no_reuse_delta; + int no_reuse_object; + int quiet; + int local; + int name_hash_version; + int path_walk; + int delta_base_offset; + int pack_kept_objects; + struct list_objects_filter_options filter_options; +}; + +#define PACK_OBJECTS_ARGS_INIT { \ + .delta_base_offset = 1, \ + .pack_kept_objects = -1, \ +} + +struct child_process; + +void prepare_pack_objects(struct child_process *cmd, + const struct pack_objects_args *args, + const char *out); +void pack_objects_args_release(struct pack_objects_args *args); + +void repack_remove_redundant_pack(struct repository *repo, const char *dir_name, + const char *base_name); + +struct write_pack_opts { + struct pack_objects_args *po_args; + const char *destination; + const char *packdir; + const char *packtmp; +}; + +const char *write_pack_opts_pack_prefix(const struct write_pack_opts *opts); +bool write_pack_opts_is_local(const struct write_pack_opts *opts); + +int finish_pack_objects_cmd(const struct git_hash_algo *algop, + const struct write_pack_opts *opts, + struct child_process *cmd, + struct string_list *names); + +struct repository; +struct packed_git; + +struct existing_packs { + struct repository *repo; + struct string_list kept_packs; + struct string_list non_kept_packs; + struct string_list cruft_packs; + struct string_list midx_packs; +}; + +#define EXISTING_PACKS_INIT { \ + .kept_packs = STRING_LIST_INIT_DUP, \ + .non_kept_packs = STRING_LIST_INIT_DUP, \ + .cruft_packs = STRING_LIST_INIT_DUP, \ +} + +/* + * Adds all packs hex strings (pack-$HASH) to either packs->non_kept + * or packs->kept based on whether each pack has a corresponding + * .keep file or not. Packs without a .keep file are not to be kept + * if we are going to pack everything into one file. + */ +void existing_packs_collect(struct existing_packs *existing, + const struct string_list *extra_keep); +int existing_packs_has_non_kept(const struct existing_packs *existing); +int existing_pack_is_marked_for_deletion(struct string_list_item *item); +void existing_packs_retain_cruft(struct existing_packs *existing, + struct packed_git *cruft); +void existing_packs_mark_for_deletion(struct existing_packs *existing, + struct string_list *names); +void existing_packs_remove_redundant(struct existing_packs *existing, + const char *packdir); +void existing_packs_release(struct existing_packs *existing); + +struct generated_pack; + +struct generated_pack *generated_pack_populate(const char *name, + const char *packtmp); +int generated_pack_has_ext(const struct generated_pack *pack, const char *ext); +void generated_pack_install(struct generated_pack *pack, const char *name, + const char *packdir, const char *packtmp); + +void repack_promisor_objects(struct repository *repo, + const struct pack_objects_args *args, + struct string_list *names, const char *packtmp); + +struct pack_geometry { + struct packed_git **pack; + uint32_t pack_nr, pack_alloc; + uint32_t split; + + struct packed_git **promisor_pack; + uint32_t promisor_pack_nr, promisor_pack_alloc; + uint32_t promisor_split; + + int split_factor; +}; + +void pack_geometry_repack_promisors(struct repository *repo, + const struct pack_objects_args *args, + const struct pack_geometry *geometry, + struct string_list *names, + const char *packtmp); + +void pack_geometry_init(struct pack_geometry *geometry, + struct existing_packs *existing, + const struct pack_objects_args *args); +void pack_geometry_split(struct pack_geometry *geometry); +struct packed_git *pack_geometry_preferred_pack(struct pack_geometry *geometry); +void pack_geometry_remove_redundant(struct pack_geometry *geometry, + struct string_list *names, + struct existing_packs *existing, + const char *packdir); +void pack_geometry_release(struct pack_geometry *geometry); + +struct tempfile; + +struct repack_write_midx_opts { + struct existing_packs *existing; + struct pack_geometry *geometry; + struct string_list *names; + const char *refs_snapshot; + const char *packdir; + int show_progress; + int write_bitmaps; + int midx_must_contain_cruft; +}; + +void midx_snapshot_refs(struct repository *repo, struct tempfile *f); +int write_midx_included_packs(struct repack_write_midx_opts *opts); + +int write_filtered_pack(const struct write_pack_opts *opts, + struct existing_packs *existing, + struct string_list *names); + +int write_cruft_pack(const struct write_pack_opts *opts, + const char *cruft_expiration, + unsigned long combine_cruft_below_size, + struct string_list *names, + struct existing_packs *existing); + +#endif /* REPACK_H */ diff --git a/src/cargo-meson.sh b/src/cargo-meson.sh new file mode 100755 index 00000000..38728a37 --- /dev/null +++ b/src/cargo-meson.sh @@ -0,0 +1,39 @@ +#!/bin/sh + +if test "$#" -lt 2 +then + exit 1 +fi + +SOURCE_DIR="$1" +BUILD_DIR="$2" +BUILD_TYPE=debug + +shift 2 + +for arg +do + case "$arg" in + --release) + BUILD_TYPE=release;; + esac +done + +cargo build --lib --quiet --manifest-path="$SOURCE_DIR/Cargo.toml" --target-dir="$BUILD_DIR" "$@" +RET=$? +if test $RET -ne 0 +then + exit $RET +fi + +case "$(cargo -vV | sed -n 's/^host: \(.*\)$/\1/p')" in + *-windows-*) + LIBNAME=gitcore.lib;; + *) + LIBNAME=libgitcore.a;; +esac + +if ! cmp "$BUILD_DIR/$BUILD_TYPE/$LIBNAME" "$BUILD_DIR/libgitcore.a" >/dev/null 2>&1 +then + cp "$BUILD_DIR/$BUILD_TYPE/$LIBNAME" "$BUILD_DIR/libgitcore.a" +fi diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 00000000..9da70d8b --- /dev/null +++ b/src/lib.rs @@ -0,0 +1 @@ +pub mod varint; diff --git a/src/meson.build b/src/meson.build new file mode 100644 index 00000000..25b9ad5a --- /dev/null +++ b/src/meson.build @@ -0,0 +1,41 @@ +libgit_rs_sources = [ + 'lib.rs', + 'varint.rs', +] + +# Unfortunately we must use a wrapper command to move the output file into the +# current build directory. This can fixed once `cargo build --artifact-dir` +# stabilizes. See https://github.com/rust-lang/cargo/issues/6790 for that +# effort. +cargo_command = [ + shell, + meson.current_source_dir() / 'cargo-meson.sh', + meson.project_source_root(), + meson.current_build_dir(), +] +if get_option('buildtype') == 'release' + cargo_command += '--release' +endif + +libgit_rs = custom_target('git_rs', + input: libgit_rs_sources + [ + meson.project_source_root() / 'Cargo.toml', + ], + output: 'libgitcore.a', + command: cargo_command, +) +libgit_dependencies += declare_dependency(link_with: libgit_rs) + +if get_option('tests') + test('rust', cargo, + args: [ + 'test', + '--manifest-path', + meson.project_source_root() / 'Cargo.toml', + '--target-dir', + meson.current_build_dir() / 'target', + ], + timeout: 0, + protocol: 'rust', + ) +endif diff --git a/src/varint.rs b/src/varint.rs new file mode 100644 index 00000000..06492dfc --- /dev/null +++ b/src/varint.rs @@ -0,0 +1,107 @@ +/// Decode the variable-length integer stored in `bufp` and return the decoded value. +/// +/// Returns 0 in case the decoded integer would overflow u64::MAX. +/// +/// # Safety +/// +/// The buffer must be NUL-terminated to ensure safety. +#[no_mangle] +pub unsafe extern "C" fn decode_varint(bufp: *mut *const u8) -> u64 { + let mut buf = *bufp; + let mut c = *buf; + let mut val = u64::from(c & 127); + + buf = buf.add(1); + + while (c & 128) != 0 { + val = val.wrapping_add(1); + if val == 0 || val.leading_zeros() < 7 { + return 0; // overflow + } + + c = *buf; + buf = buf.add(1); + + val = (val << 7) + u64::from(c & 127); + } + + *bufp = buf; + val +} + +/// Encode `value` into `buf` as a variable-length integer unless `buf` is null. +/// +/// Returns the number of bytes written, or, if `buf` is null, the number of bytes that would be +/// written to encode the integer. +/// +/// # Safety +/// +/// `buf` must either be null or point to at least 16 bytes of memory. +#[no_mangle] +pub unsafe extern "C" fn encode_varint(value: u64, buf: *mut u8) -> u8 { + let mut varint: [u8; 16] = [0; 16]; + let mut pos = varint.len() - 1; + + varint[pos] = (value & 127) as u8; + + let mut value = value >> 7; + while value != 0 { + pos -= 1; + value -= 1; + varint[pos] = 128 | (value & 127) as u8; + value >>= 7; + } + + if !buf.is_null() { + std::ptr::copy_nonoverlapping(varint.as_ptr().add(pos), buf, varint.len() - pos); + } + + (varint.len() - pos) as u8 +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_decode_varint() { + unsafe { + assert_eq!(decode_varint(&mut [0x00].as_slice().as_ptr()), 0); + assert_eq!(decode_varint(&mut [0x01].as_slice().as_ptr()), 1); + assert_eq!(decode_varint(&mut [0x7f].as_slice().as_ptr()), 127); + assert_eq!(decode_varint(&mut [0x80, 0x00].as_slice().as_ptr()), 128); + assert_eq!(decode_varint(&mut [0x80, 0x01].as_slice().as_ptr()), 129); + assert_eq!(decode_varint(&mut [0x80, 0x7f].as_slice().as_ptr()), 255); + + // Overflows are expected to return 0. + assert_eq!(decode_varint(&mut [0x88; 16].as_slice().as_ptr()), 0); + } + } + + #[test] + fn test_encode_varint() { + unsafe { + let mut varint: [u8; 16] = [0; 16]; + + assert_eq!(encode_varint(0, std::ptr::null_mut()), 1); + + assert_eq!(encode_varint(0, varint.as_mut_slice().as_mut_ptr()), 1); + assert_eq!(varint, [0; 16]); + + assert_eq!(encode_varint(10, varint.as_mut_slice().as_mut_ptr()), 1); + assert_eq!(varint, [10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); + + assert_eq!(encode_varint(127, varint.as_mut_slice().as_mut_ptr()), 1); + assert_eq!(varint, [127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); + + assert_eq!(encode_varint(128, varint.as_mut_slice().as_mut_ptr()), 2); + assert_eq!(varint, [128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); + + assert_eq!(encode_varint(129, varint.as_mut_slice().as_mut_ptr()), 2); + assert_eq!(varint, [128, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); + + assert_eq!(encode_varint(255, varint.as_mut_slice().as_mut_ptr()), 2); + assert_eq!(varint, [128, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); + } + } +} diff --git a/t/for-each-ref-tests.sh b/t/for-each-ref-tests.sh new file mode 100644 index 00000000..4593be5f --- /dev/null +++ b/t/for-each-ref-tests.sh @@ -0,0 +1,2143 @@ +git_for_each_ref=${git_for_each_ref:-git for-each-ref} +GNUPGHOME_NOT_USED=$GNUPGHOME +. "$TEST_DIRECTORY"/lib-gpg.sh +. "$TEST_DIRECTORY"/lib-terminal.sh + +# Mon Jul 3 23:18:43 2006 +0000 +datestamp=1151968723 +setdate_and_increment () { + GIT_COMMITTER_DATE="$datestamp +0200" + datestamp=$(expr "$datestamp" + 1) + GIT_AUTHOR_DATE="$datestamp +0200" + datestamp=$(expr "$datestamp" + 1) + export GIT_COMMITTER_DATE GIT_AUTHOR_DATE +} + +test_object_file_size () { + oid=$(git rev-parse "$1") + path=".git/objects/$(test_oid_to_path $oid)" + test_file_size "$path" +} + +test_expect_success setup ' + # setup .mailmap + cat >.mailmap <<-EOF && + A Thor A U Thor + C Mitter C O Mitter + EOF + + setdate_and_increment && + echo "Using $datestamp" > one && + git add one && + git commit -m "Initial" && + git branch -M main && + setdate_and_increment && + git tag -a -m "Tagging at $datestamp" testtag && + git update-ref refs/remotes/origin/main main && + git remote add origin nowhere && + git config branch.main.remote origin && + git config branch.main.merge refs/heads/main && + git remote add myfork elsewhere && + git config remote.pushdefault myfork && + git config push.default current +' + +test_atom () { + case "$1" in + head) ref=refs/heads/main ;; + tag) ref=refs/tags/testtag ;; + sym) ref=refs/heads/sym ;; + *) ref=$1 ;; + esac + format=$2 + test_do=test_expect_${4:-success} + + printf '%s\n' "$3" >expected + $test_do $PREREQ "basic atom: $ref $format" ' + ${git_for_each_ref} --format="%($format)" "$ref" >actual && + sanitize_pgp actual.clean && + test_cmp expected actual.clean + ' + + # Automatically test "contents:size" atom after testing "contents" + if test "$format" = "contents" + then + # for commit leg, $3 is changed there + expect=$(printf '%s' "$3" | wc -c) + $test_do $PREREQ "basic atom: $ref contents:size" ' + type=$(git cat-file -t "$ref") && + case $type in + tag) + # We cannot use $3 as it expects sanitize_pgp to run + git cat-file tag $ref >out && + expect=$(tail -n +6 out | wc -c) && + rm -f out ;; + tree | blob) + expect="" ;; + commit) + : "use the calculated expect" ;; + *) + BUG "unknown object type" ;; + esac && + # Leave $expect unquoted to lose possible leading whitespaces + echo $expect >expected && + ${git_for_each_ref} --format="%(contents:size)" "$ref" >actual && + test_cmp expected actual + ' + fi +} + +hexlen=$(test_oid hexsz) + +test_atom head refname refs/heads/main +test_atom head refname: refs/heads/main +test_atom head refname:short main +test_atom head refname:lstrip=1 heads/main +test_atom head refname:lstrip=2 main +test_atom head refname:lstrip=-1 main +test_atom head refname:lstrip=-2 heads/main +test_atom head refname:rstrip=1 refs/heads +test_atom head refname:rstrip=2 refs +test_atom head refname:rstrip=-1 refs +test_atom head refname:rstrip=-2 refs/heads +test_atom head refname:strip=1 heads/main +test_atom head refname:strip=2 main +test_atom head refname:strip=-1 main +test_atom head refname:strip=-2 heads/main +test_atom head upstream refs/remotes/origin/main +test_atom head upstream:short origin/main +test_atom head upstream:lstrip=2 origin/main +test_atom head upstream:lstrip=-2 origin/main +test_atom head upstream:rstrip=2 refs/remotes +test_atom head upstream:rstrip=-2 refs/remotes +test_atom head upstream:strip=2 origin/main +test_atom head upstream:strip=-2 origin/main +test_atom head push refs/remotes/myfork/main +test_atom head push:short myfork/main +test_atom head push:lstrip=1 remotes/myfork/main +test_atom head push:lstrip=-1 main +test_atom head push:rstrip=1 refs/remotes/myfork +test_atom head push:rstrip=-1 refs +test_atom head push:strip=1 remotes/myfork/main +test_atom head push:strip=-1 main +test_atom head objecttype commit +test_atom head objectsize $((131 + hexlen)) +test_atom head objectsize:disk $(test_object_file_size refs/heads/main) +test_atom head deltabase $ZERO_OID +test_atom head objectname $(git rev-parse refs/heads/main) +test_atom head objectname:short $(git rev-parse --short refs/heads/main) +test_atom head objectname:short=1 $(git rev-parse --short=1 refs/heads/main) +test_atom head objectname:short=10 $(git rev-parse --short=10 refs/heads/main) +test_atom head tree $(git rev-parse refs/heads/main^{tree}) +test_atom head tree:short $(git rev-parse --short refs/heads/main^{tree}) +test_atom head tree:short=1 $(git rev-parse --short=1 refs/heads/main^{tree}) +test_atom head tree:short=10 $(git rev-parse --short=10 refs/heads/main^{tree}) +test_atom head parent '' +test_atom head parent:short '' +test_atom head parent:short=1 '' +test_atom head parent:short=10 '' +test_atom head numparent 0 +test_atom head object '' +test_atom head type '' +test_atom head raw "$(git cat-file commit refs/heads/main) +" +test_atom head '*objectname' '' +test_atom head '*objecttype' '' +test_atom head author 'A U Thor 1151968724 +0200' +test_atom head authorname 'A U Thor' +test_atom head authorname:mailmap 'A Thor' +test_atom head authoremail '' +test_atom head authoremail:trim 'author@example.com' +test_atom head authoremail:localpart 'author' +test_atom head authoremail:trim,localpart 'author' +test_atom head authoremail:mailmap '' +test_atom head authoremail:mailmap,trim 'athor@example.com' +test_atom head authoremail:trim,mailmap 'athor@example.com' +test_atom head authoremail:mailmap,localpart 'athor' +test_atom head authoremail:localpart,mailmap 'athor' +test_atom head authoremail:mailmap,trim,localpart,mailmap,trim 'athor' +test_atom head authordate 'Tue Jul 4 01:18:44 2006 +0200' +test_atom head committer 'C O Mitter 1151968723 +0200' +test_atom head committername 'C O Mitter' +test_atom head committername:mailmap 'C Mitter' +test_atom head committeremail '' +test_atom head committeremail:trim 'committer@example.com' +test_atom head committeremail:localpart 'committer' +test_atom head committeremail:localpart,trim 'committer' +test_atom head committeremail:mailmap '' +test_atom head committeremail:mailmap,trim 'cmitter@example.com' +test_atom head committeremail:trim,mailmap 'cmitter@example.com' +test_atom head committeremail:mailmap,localpart 'cmitter' +test_atom head committeremail:localpart,mailmap 'cmitter' +test_atom head committeremail:trim,mailmap,trim,trim,localpart 'cmitter' +test_atom head committerdate 'Tue Jul 4 01:18:43 2006 +0200' +test_atom head tag '' +test_atom head tagger '' +test_atom head taggername '' +test_atom head taggeremail '' +test_atom head taggeremail:trim '' +test_atom head taggeremail:localpart '' +test_atom head taggerdate '' +test_atom head creator 'C O Mitter 1151968723 +0200' +test_atom head creatordate 'Tue Jul 4 01:18:43 2006 +0200' +test_atom head subject 'Initial' +test_atom head subject:sanitize 'Initial' +test_atom head contents:subject 'Initial' +test_atom head body '' +test_atom head contents:body '' +test_atom head contents:signature '' +test_atom head contents 'Initial +' +test_atom head HEAD '*' + +test_atom tag refname refs/tags/testtag +test_atom tag refname:short testtag +test_atom tag upstream '' +test_atom tag push '' +test_atom tag objecttype tag +test_atom tag objectsize $((114 + hexlen)) +test_atom tag objectsize:disk $(test_object_file_size refs/tags/testtag) +test_atom tag '*objectsize:disk' $(test_object_file_size refs/heads/main) +test_atom tag deltabase $ZERO_OID +test_atom tag '*deltabase' $ZERO_OID +test_atom tag objectname $(git rev-parse refs/tags/testtag) +test_atom tag objectname:short $(git rev-parse --short refs/tags/testtag) +test_atom head objectname:short=1 $(git rev-parse --short=1 refs/heads/main) +test_atom head objectname:short=10 $(git rev-parse --short=10 refs/heads/main) +test_atom tag tree '' +test_atom tag tree:short '' +test_atom tag tree:short=1 '' +test_atom tag tree:short=10 '' +test_atom tag parent '' +test_atom tag parent:short '' +test_atom tag parent:short=1 '' +test_atom tag parent:short=10 '' +test_atom tag numparent '' +test_atom tag object $(git rev-parse refs/tags/testtag^0) +test_atom tag type 'commit' +test_atom tag '*objectname' $(git rev-parse refs/tags/testtag^{}) +test_atom tag '*objecttype' 'commit' +test_atom tag author '' +test_atom tag authorname '' +test_atom tag authorname:mailmap '' +test_atom tag authoremail '' +test_atom tag authoremail:trim '' +test_atom tag authoremail:localpart '' +test_atom tag authoremail:trim,localpart '' +test_atom tag authoremail:mailmap '' +test_atom tag authoremail:mailmap,trim '' +test_atom tag authoremail:trim,mailmap '' +test_atom tag authoremail:mailmap,localpart '' +test_atom tag authoremail:localpart,mailmap '' +test_atom tag authoremail:mailmap,trim,localpart,mailmap,trim '' +test_atom tag authordate '' +test_atom tag committer '' +test_atom tag committername '' +test_atom tag committername:mailmap '' +test_atom tag committeremail '' +test_atom tag committeremail:trim '' +test_atom tag committeremail:localpart '' +test_atom tag committeremail:localpart,trim '' +test_atom tag committeremail:mailmap '' +test_atom tag committeremail:mailmap,trim '' +test_atom tag committeremail:trim,mailmap '' +test_atom tag committeremail:mailmap,localpart '' +test_atom tag committeremail:localpart,mailmap '' +test_atom tag committeremail:trim,mailmap,trim,trim,localpart '' +test_atom tag committerdate '' +test_atom tag tag 'testtag' +test_atom tag tagger 'C O Mitter 1151968725 +0200' +test_atom tag taggername 'C O Mitter' +test_atom tag taggername:mailmap 'C Mitter' +test_atom tag taggeremail '' +test_atom tag taggeremail:trim 'committer@example.com' +test_atom tag taggeremail:localpart 'committer' +test_atom tag taggeremail:trim,localpart 'committer' +test_atom tag taggeremail:mailmap '' +test_atom tag taggeremail:mailmap,trim 'cmitter@example.com' +test_atom tag taggeremail:trim,mailmap 'cmitter@example.com' +test_atom tag taggeremail:mailmap,localpart 'cmitter' +test_atom tag taggeremail:localpart,mailmap 'cmitter' +test_atom tag taggeremail:trim,mailmap,trim,localpart,localpart 'cmitter' +test_atom tag taggerdate 'Tue Jul 4 01:18:45 2006 +0200' +test_atom tag creator 'C O Mitter 1151968725 +0200' +test_atom tag creatordate 'Tue Jul 4 01:18:45 2006 +0200' +test_atom tag subject 'Tagging at 1151968727' +test_atom tag subject:sanitize 'Tagging-at-1151968727' +test_atom tag contents:subject 'Tagging at 1151968727' +test_atom tag body '' +test_atom tag contents:body '' +test_atom tag contents:signature '' +test_atom tag contents 'Tagging at 1151968727 +' +test_atom tag HEAD ' ' + +test_expect_success 'basic atom: refs/tags/testtag *raw' ' + git cat-file commit refs/tags/testtag^{} >expected && + ${git_for_each_ref} --format="%(*raw)" refs/tags/testtag >actual && + sanitize_pgp expected.clean && + echo >>expected.clean && + sanitize_pgp actual.clean && + test_cmp expected.clean actual.clean +' + +test_expect_success 'Check invalid atoms names are errors' ' + test_must_fail ${git_for_each_ref} --format="%(INVALID)" refs/heads +' + +test_expect_success 'Check format specifiers are ignored in naming date atoms' ' + ${git_for_each_ref} --format="%(authordate)" refs/heads && + ${git_for_each_ref} --format="%(authordate:default) %(authordate)" refs/heads && + ${git_for_each_ref} --format="%(authordate) %(authordate:default)" refs/heads && + ${git_for_each_ref} --format="%(authordate:default) %(authordate:default)" refs/heads +' + +test_expect_success 'Check valid format specifiers for date fields' ' + ${git_for_each_ref} --format="%(authordate:default)" refs/heads && + ${git_for_each_ref} --format="%(authordate:relative)" refs/heads && + ${git_for_each_ref} --format="%(authordate:short)" refs/heads && + ${git_for_each_ref} --format="%(authordate:local)" refs/heads && + ${git_for_each_ref} --format="%(authordate:iso8601)" refs/heads && + ${git_for_each_ref} --format="%(authordate:rfc2822)" refs/heads +' + +test_expect_success 'Check invalid format specifiers are errors' ' + test_must_fail ${git_for_each_ref} --format="%(authordate:INVALID)" refs/heads +' + +test_expect_success 'arguments to %(objectname:short=) must be positive integers' ' + test_must_fail ${git_for_each_ref} --format="%(objectname:short=0)" && + test_must_fail ${git_for_each_ref} --format="%(objectname:short=-1)" && + test_must_fail ${git_for_each_ref} --format="%(objectname:short=foo)" +' + +test_bad_atom () { + case "$1" in + head) ref=refs/heads/main ;; + tag) ref=refs/tags/testtag ;; + sym) ref=refs/heads/sym ;; + *) ref=$1 ;; + esac + format=$2 + test_do=test_expect_${4:-success} + + printf '%s\n' "$3" >expect + $test_do $PREREQ "err basic atom: $ref $format" ' + test_must_fail ${git_for_each_ref} \ + --format="%($format)" "$ref" 2>error && + test_cmp expect error + ' +} + +test_bad_atom head 'authoremail:foo' \ + 'fatal: unrecognized %(authoremail) argument: foo' + +test_bad_atom head 'authoremail:mailmap,trim,bar' \ + 'fatal: unrecognized %(authoremail) argument: bar' + +test_bad_atom head 'authoremail:trim,' \ + 'fatal: unrecognized %(authoremail) argument: ' + +test_bad_atom head 'authoremail:mailmaptrim' \ + 'fatal: unrecognized %(authoremail) argument: trim' + +test_bad_atom head 'committeremail: ' \ + 'fatal: unrecognized %(committeremail) argument: ' + +test_bad_atom head 'committeremail: trim,foo' \ + 'fatal: unrecognized %(committeremail) argument: trim,foo' + +test_bad_atom head 'committeremail:mailmap,localpart ' \ + 'fatal: unrecognized %(committeremail) argument: ' + +test_bad_atom head 'committeremail:trim_localpart' \ + 'fatal: unrecognized %(committeremail) argument: _localpart' + +test_bad_atom head 'committeremail:localpart,,,trim' \ + 'fatal: unrecognized %(committeremail) argument: ,,trim' + +test_bad_atom tag 'taggeremail:mailmap,trim, foo ' \ + 'fatal: unrecognized %(taggeremail) argument: foo ' + +test_bad_atom tag 'taggeremail:trim,localpart,' \ + 'fatal: unrecognized %(taggeremail) argument: ' + +test_bad_atom tag 'taggeremail:mailmap;localpart trim' \ + 'fatal: unrecognized %(taggeremail) argument: ;localpart trim' + +test_bad_atom tag 'taggeremail:localpart trim' \ + 'fatal: unrecognized %(taggeremail) argument: trim' + +test_bad_atom tag 'taggeremail:mailmap,mailmap,trim,qux,localpart,trim' \ + 'fatal: unrecognized %(taggeremail) argument: qux,localpart,trim' + +test_date () { + f=$1 && + committer_date=$2 && + author_date=$3 && + tagger_date=$4 && + cat >expected <<-EOF && + 'refs/heads/main' '$committer_date' '$author_date' + 'refs/tags/testtag' '$tagger_date' + EOF + ( + ${git_for_each_ref} --shell \ + --format="%(refname) %(committerdate${f:+:$f}) %(authordate${f:+:$f})" \ + refs/heads && + ${git_for_each_ref} --shell \ + --format="%(refname) %(taggerdate${f:+:$f})" \ + refs/tags + ) >actual && + test_cmp expected actual +} + +test_expect_success 'Check unformatted date fields output' ' + test_date "" \ + "Tue Jul 4 01:18:43 2006 +0200" \ + "Tue Jul 4 01:18:44 2006 +0200" \ + "Tue Jul 4 01:18:45 2006 +0200" +' + +test_expect_success 'Check format "default" formatted date fields output' ' + test_date default \ + "Tue Jul 4 01:18:43 2006 +0200" \ + "Tue Jul 4 01:18:44 2006 +0200" \ + "Tue Jul 4 01:18:45 2006 +0200" +' + +test_expect_success 'Check format "default-local" date fields output' ' + test_date default-local "Mon Jul 3 23:18:43 2006" "Mon Jul 3 23:18:44 2006" "Mon Jul 3 23:18:45 2006" +' + +# Don't know how to do relative check because I can't know when this script +# is going to be run and can't fake the current time to git, and hence can't +# provide expected output. Instead, I'll just make sure that "relative" +# doesn't exit in error +test_expect_success 'Check format "relative" date fields output' ' + f=relative && + (${git_for_each_ref} --shell --format="%(refname) %(committerdate:$f) %(authordate:$f)" refs/heads && + ${git_for_each_ref} --shell --format="%(refname) %(taggerdate:$f)" refs/tags) >actual +' + +# We just check that this is the same as "relative" for now. +test_expect_success 'Check format "relative-local" date fields output' ' + test_date relative-local \ + "$(${git_for_each_ref} --format="%(committerdate:relative)" refs/heads)" \ + "$(${git_for_each_ref} --format="%(authordate:relative)" refs/heads)" \ + "$(${git_for_each_ref} --format="%(taggerdate:relative)" refs/tags)" +' + +test_expect_success 'Check format "short" date fields output' ' + test_date short 2006-07-04 2006-07-04 2006-07-04 +' + +test_expect_success 'Check format "short-local" date fields output' ' + test_date short-local 2006-07-03 2006-07-03 2006-07-03 +' + +test_expect_success 'Check format "local" date fields output' ' + test_date local \ + "Mon Jul 3 23:18:43 2006" \ + "Mon Jul 3 23:18:44 2006" \ + "Mon Jul 3 23:18:45 2006" +' + +test_expect_success 'Check format "iso8601" date fields output' ' + test_date iso8601 \ + "2006-07-04 01:18:43 +0200" \ + "2006-07-04 01:18:44 +0200" \ + "2006-07-04 01:18:45 +0200" +' + +test_expect_success 'Check format "iso8601-local" date fields output' ' + test_date iso8601-local "2006-07-03 23:18:43 +0000" "2006-07-03 23:18:44 +0000" "2006-07-03 23:18:45 +0000" +' + +test_expect_success 'Check format "rfc2822" date fields output' ' + test_date rfc2822 \ + "Tue, 4 Jul 2006 01:18:43 +0200" \ + "Tue, 4 Jul 2006 01:18:44 +0200" \ + "Tue, 4 Jul 2006 01:18:45 +0200" +' + +test_expect_success 'Check format "rfc2822-local" date fields output' ' + test_date rfc2822-local "Mon, 3 Jul 2006 23:18:43 +0000" "Mon, 3 Jul 2006 23:18:44 +0000" "Mon, 3 Jul 2006 23:18:45 +0000" +' + +test_expect_success 'Check format "raw" date fields output' ' + test_date raw "1151968723 +0200" "1151968724 +0200" "1151968725 +0200" +' + +test_expect_success 'Check format "raw-local" date fields output' ' + test_date raw-local "1151968723 +0000" "1151968724 +0000" "1151968725 +0000" +' + +test_expect_success 'Check format of strftime date fields' ' + echo "my date is 2006-07-04" >expected && + ${git_for_each_ref} \ + --format="%(authordate:format:my date is %Y-%m-%d)" \ + refs/heads >actual && + test_cmp expected actual +' + +test_expect_success 'Check format of strftime-local date fields' ' + echo "my date is 2006-07-03" >expected && + ${git_for_each_ref} \ + --format="%(authordate:format-local:my date is %Y-%m-%d)" \ + refs/heads >actual && + test_cmp expected actual +' + +test_expect_success 'exercise strftime with odd fields' ' + echo >expected && + ${git_for_each_ref} --format="%(authordate:format:)" refs/heads >actual && + test_cmp expected actual && + long="long format -- $ZERO_OID$ZERO_OID$ZERO_OID$ZERO_OID$ZERO_OID$ZERO_OID$ZERO_OID" && + echo $long >expected && + ${git_for_each_ref} --format="%(authordate:format:$long)" refs/heads >actual && + test_cmp expected actual +' + +cat >expected <<\EOF +refs/heads/main +refs/remotes/origin/main +refs/tags/testtag +EOF + +test_expect_success 'Verify ascending sort' ' + ${git_for_each_ref} --format="%(refname)" --sort=refname >actual && + test_cmp expected actual +' + + +cat >expected <<\EOF +refs/tags/testtag +refs/remotes/origin/main +refs/heads/main +EOF + +test_expect_success 'Verify descending sort' ' + ${git_for_each_ref} --format="%(refname)" --sort=-refname >actual && + test_cmp expected actual +' + +test_expect_success 'Give help even with invalid sort atoms' ' + test_expect_code 129 ${git_for_each_ref} --sort=bogus -h >actual 2>&1 && + grep "^usage: ${git_for_each_ref}" actual +' + +cat >expected <<\EOF +refs/tags/testtag +refs/tags/testtag-2 +EOF + +test_expect_success 'exercise patterns with prefixes' ' + git tag testtag-2 && + test_when_finished "git tag -d testtag-2" && + ${git_for_each_ref} --format="%(refname)" \ + refs/tags/testtag refs/tags/testtag-2 >actual && + test_cmp expected actual +' + +cat >expected <<\EOF +refs/tags/testtag +refs/tags/testtag-2 +EOF + +test_expect_success 'exercise glob patterns with prefixes' ' + git tag testtag-2 && + test_when_finished "git tag -d testtag-2" && + ${git_for_each_ref} --format="%(refname)" \ + refs/tags/testtag "refs/tags/testtag-*" >actual && + test_cmp expected actual +' + +cat >expected <<\EOF +refs/tags/bar +refs/tags/baz +refs/tags/testtag +EOF + +test_expect_success 'exercise patterns with prefix exclusions' ' + for tag in foo/one foo/two foo/three bar baz + do + git tag "$tag" || return 1 + done && + test_when_finished "git tag -d foo/one foo/two foo/three bar baz" && + ${git_for_each_ref} --format="%(refname)" \ + refs/tags/ --exclude=refs/tags/foo >actual && + test_cmp expected actual +' + +cat >expected <<\EOF +refs/tags/bar +refs/tags/baz +refs/tags/foo/one +refs/tags/testtag +EOF + +test_expect_success 'exercise patterns with pattern exclusions' ' + for tag in foo/one foo/two foo/three bar baz + do + git tag "$tag" || return 1 + done && + test_when_finished "git tag -d foo/one foo/two foo/three bar baz" && + ${git_for_each_ref} --format="%(refname)" \ + refs/tags/ --exclude="refs/tags/foo/t*" >actual && + test_cmp expected actual +' + +cat >expected <<\EOF +'refs/heads/main' +'refs/remotes/origin/main' +'refs/tags/testtag' +EOF + +test_expect_success 'Quoting style: shell' ' + ${git_for_each_ref} --shell --format="%(refname)" >actual && + test_cmp expected actual +' + +test_expect_success 'Quoting style: perl' ' + ${git_for_each_ref} --perl --format="%(refname)" >actual && + test_cmp expected actual +' + +test_expect_success 'Quoting style: python' ' + ${git_for_each_ref} --python --format="%(refname)" >actual && + test_cmp expected actual +' + +cat >expected <<\EOF +"refs/heads/main" +"refs/remotes/origin/main" +"refs/tags/testtag" +EOF + +test_expect_success 'Quoting style: tcl' ' + ${git_for_each_ref} --tcl --format="%(refname)" >actual && + test_cmp expected actual +' + +for i in "--perl --shell" "-s --python" "--python --tcl" "--tcl --perl"; do + test_expect_success "more than one quoting style: $i" " + test_must_fail ${git_for_each_ref} $i 2>err && + grep '^error: more than one quoting style' err + " +done + +test_expect_success 'setup for upstream:track[short]' ' + test_commit two +' + +test_atom head upstream:track '[ahead 1]' +test_atom head upstream:trackshort '>' +test_atom head upstream:track,nobracket 'ahead 1' +test_atom head upstream:nobracket,track 'ahead 1' + +test_expect_success 'setup for push:track[short]' ' + test_commit third && + git update-ref refs/remotes/myfork/main main && + git reset main~1 +' + +test_atom head push:track '[behind 1]' +test_atom head push:trackshort '<' + +test_expect_success 'Check that :track[short] cannot be used with other atoms' ' + test_must_fail ${git_for_each_ref} --format="%(refname:track)" 2>/dev/null && + test_must_fail ${git_for_each_ref} --format="%(refname:trackshort)" 2>/dev/null +' + +test_expect_success 'Check that :track[short] works when upstream is invalid' ' + cat >expected <<-\EOF && + [gone] + + EOF + test_when_finished "git config branch.main.merge refs/heads/main" && + git config branch.main.merge refs/heads/does-not-exist && + ${git_for_each_ref} \ + --format="%(upstream:track)$LF%(upstream:trackshort)" \ + refs/heads >actual && + test_cmp expected actual +' + +test_expect_success 'Check for invalid refname format' ' + test_must_fail ${git_for_each_ref} --format="%(refname:INVALID)" +' + +test_expect_success 'set up color tests' ' + cat >expected.color <<-EOF && + $(git rev-parse --short refs/heads/main) main + $(git rev-parse --short refs/remotes/myfork/main) myfork/main + $(git rev-parse --short refs/remotes/origin/main) origin/main + $(git rev-parse --short refs/tags/testtag) testtag + $(git rev-parse --short refs/tags/third) third + $(git rev-parse --short refs/tags/two) two + EOF + sed "s/<[^>]*>//g" expected.bare && + color_format="%(objectname:short) %(color:green)%(refname:short)" +' + +test_expect_success TTY '%(color) shows color with a tty' ' + test_terminal ${git_for_each_ref} --format="$color_format" >actual.raw && + test_decode_color actual && + test_cmp expected.color actual +' + +test_expect_success '%(color) does not show color without tty' ' + TERM=vt100 ${git_for_each_ref} --format="$color_format" >actual && + test_cmp expected.bare actual +' + +test_expect_success '--color can override tty check' ' + ${git_for_each_ref} --color --format="$color_format" >actual.raw && + test_decode_color actual && + test_cmp expected.color actual +' + +test_expect_success 'color.ui=always does not override tty check' ' + git -c color.ui=always ${git_for_each_ref#git} --format="$color_format" >actual && + test_cmp expected.bare actual +' + +test_expect_success 'setup for describe atom tests' ' + git init -b master describe-repo && + ( + cd describe-repo && + + test_commit --no-tag one && + git tag tagone && + + test_commit --no-tag two && + git tag -a -m "tag two" tagtwo + ) +' + +test_expect_success 'describe atom vs git describe' ' + ( + cd describe-repo && + + ${git_for_each_ref} --format="%(objectname)" \ + refs/tags/ >obj && + while read hash + do + if desc=$(git describe $hash) + then + : >expect-contains-good + else + : >expect-contains-bad + fi && + echo "$hash $desc" || return 1 + done expect && + test_path_exists expect-contains-good && + test_path_exists expect-contains-bad && + + ${git_for_each_ref} --format="%(objectname) %(describe)" \ + refs/tags/ >actual 2>err && + test_cmp expect actual && + test_must_be_empty err + ) +' + +test_expect_success 'describe:tags vs describe --tags' ' + ( + cd describe-repo && + git describe --tags >expect && + ${git_for_each_ref} --format="%(describe:tags)" \ + refs/heads/master >actual && + test_cmp expect actual + ) +' + +test_expect_success 'describe:abbrev=... vs describe --abbrev=...' ' + ( + cd describe-repo && + + # Case 1: We have commits between HEAD and the most + # recent tag reachable from it + test_commit --no-tag file && + git describe --abbrev=14 >expect && + ${git_for_each_ref} --format="%(describe:abbrev=14)" \ + refs/heads/master >actual && + test_cmp expect actual && + + # Make sure the hash used is at least 14 digits long + sed -e "s/^.*-g\([0-9a-f]*\)$/\1/" hexpart && + test 15 -le $(wc -c expect && + ${git_for_each_ref} --format="%(describe:abbrev=14)" \ + refs/heads/master >actual && + test_cmp expect actual && + test tagname = $(cat actual) + ) +' + +test_expect_success 'describe:match=... vs describe --match ...' ' + ( + cd describe-repo && + git tag -a -m "tag foo" tag-foo && + git describe --match "*-foo" >expect && + ${git_for_each_ref} --format="%(describe:match="*-foo")" \ + refs/heads/master >actual && + test_cmp expect actual + ) +' + +test_expect_success 'describe:exclude:... vs describe --exclude ...' ' + ( + cd describe-repo && + git tag -a -m "tag bar" tag-bar && + git describe --exclude "*-bar" >expect && + ${git_for_each_ref} --format="%(describe:exclude="*-bar")" \ + refs/heads/master >actual && + test_cmp expect actual + ) +' + +test_expect_success 'deref with describe atom' ' + ( + cd describe-repo && + cat >expect <<-\EOF && + + tagname + tagname + tagname + + tagtwo + EOF + ${git_for_each_ref} --format="%(*describe)" >actual && + test_cmp expect actual + ) +' + +test_expect_success 'err on bad describe atom arg' ' + ( + cd describe-repo && + + # The bad arg is the only arg passed to describe atom + cat >expect <<-\EOF && + fatal: unrecognized %(describe) argument: baz + EOF + test_must_fail ${git_for_each_ref} --format="%(describe:baz)" \ + refs/heads/master 2>actual && + test_cmp expect actual && + + # The bad arg is in the middle of the option string + # passed to the describe atom + cat >expect <<-\EOF && + fatal: unrecognized %(describe) argument: qux=1,abbrev=14 + EOF + test_must_fail ${git_for_each_ref} \ + --format="%(describe:tags,qux=1,abbrev=14)" \ + ref/heads/master 2>actual && + test_cmp expect actual + ) +' + +cat >expected <<\EOF +heads/main +tags/main +EOF + +test_expect_success 'Check ambiguous head and tag refs (strict)' ' + git config --bool core.warnambiguousrefs true && + git checkout -b newtag && + echo "Using $datestamp" > one && + git add one && + git commit -m "Branch" && + setdate_and_increment && + git tag -m "Tagging at $datestamp" main && + ${git_for_each_ref} --format "%(refname:short)" refs/heads/main refs/tags/main >actual && + test_cmp expected actual +' + +cat >expected <<\EOF +heads/main +main +EOF + +test_expect_success 'Check ambiguous head and tag refs (loose)' ' + git config --bool core.warnambiguousrefs false && + ${git_for_each_ref} --format "%(refname:short)" refs/heads/main refs/tags/main >actual && + test_cmp expected actual +' + +cat >expected <<\EOF +heads/ambiguous +ambiguous +EOF + +test_expect_success 'Check ambiguous head and tag refs II (loose)' ' + git checkout main && + git tag ambiguous testtag^0 && + git branch ambiguous testtag^0 && + ${git_for_each_ref} --format "%(refname:short)" refs/heads/ambiguous refs/tags/ambiguous >actual && + test_cmp expected actual +' + +test_expect_success 'create tag without tagger' ' + git tag -a -m "Broken tag" taggerless && + git tag -f taggerless $(git cat-file tag taggerless | + sed -e "/^tagger /d" | + git hash-object --literally --stdin -w -t tag) +' + +test_atom refs/tags/taggerless type 'commit' +test_atom refs/tags/taggerless tag 'taggerless' +test_atom refs/tags/taggerless tagger '' +test_atom refs/tags/taggerless taggername '' +test_atom refs/tags/taggerless taggeremail '' +test_atom refs/tags/taggerless taggeremail:trim '' +test_atom refs/tags/taggerless taggeremail:localpart '' +test_atom refs/tags/taggerless taggerdate '' +test_atom refs/tags/taggerless committer '' +test_atom refs/tags/taggerless committername '' +test_atom refs/tags/taggerless committeremail '' +test_atom refs/tags/taggerless committeremail:trim '' +test_atom refs/tags/taggerless committeremail:localpart '' +test_atom refs/tags/taggerless committerdate '' +test_atom refs/tags/taggerless subject 'Broken tag' + +test_expect_success 'an unusual tag with an incomplete line' ' + + git tag -m "bogo" bogo && + bogo=$(git cat-file tag bogo) && + bogo=$(printf "%s" "$bogo" | git mktag) && + git tag -f bogo "$bogo" && + ${git_for_each_ref} --format "%(body)" refs/tags/bogo + +' + +test_expect_success 'create tag with subject and body content' ' + cat >>msg <<-\EOF && + the subject line + + first body line + second body line + EOF + git tag -F msg subject-body +' +test_atom refs/tags/subject-body subject 'the subject line' +test_atom refs/tags/subject-body subject:sanitize 'the-subject-line' +test_atom refs/tags/subject-body body 'first body line +second body line +' +test_atom refs/tags/subject-body contents 'the subject line + +first body line +second body line +' + +test_expect_success 'create tag with multiline subject' ' + cat >msg <<-\EOF && + first subject line + second subject line + + first body line + second body line + EOF + git tag -F msg multiline +' +test_atom refs/tags/multiline subject 'first subject line second subject line' +test_atom refs/tags/multiline subject:sanitize 'first-subject-line-second-subject-line' +test_atom refs/tags/multiline contents:subject 'first subject line second subject line' +test_atom refs/tags/multiline body 'first body line +second body line +' +test_atom refs/tags/multiline contents:body 'first body line +second body line +' +test_atom refs/tags/multiline contents:signature '' +test_atom refs/tags/multiline contents 'first subject line +second subject line + +first body line +second body line +' + +test_expect_success GPG 'create signed tags' ' + git tag -s -m "" signed-empty && + git tag -s -m "subject line" signed-short && + cat >msg <<-\EOF && + subject line + + body contents + EOF + git tag -s -F msg signed-long +' + +sig='-----BEGIN PGP SIGNATURE----- +-----END PGP SIGNATURE----- +' + +PREREQ=GPG +test_atom refs/tags/signed-empty subject '' +test_atom refs/tags/signed-empty subject:sanitize '' +test_atom refs/tags/signed-empty contents:subject '' +test_atom refs/tags/signed-empty body "$sig" +test_atom refs/tags/signed-empty contents:body '' +test_atom refs/tags/signed-empty contents:signature "$sig" +test_atom refs/tags/signed-empty contents "$sig" + +test_expect_success GPG 'basic atom: refs/tags/signed-empty raw' ' + git cat-file tag refs/tags/signed-empty >expected && + ${git_for_each_ref} --format="%(raw)" refs/tags/signed-empty >actual && + sanitize_pgp expected.clean && + echo >>expected.clean && + sanitize_pgp actual.clean && + test_cmp expected.clean actual.clean +' + +test_atom refs/tags/signed-short subject 'subject line' +test_atom refs/tags/signed-short subject:sanitize 'subject-line' +test_atom refs/tags/signed-short contents:subject 'subject line' +test_atom refs/tags/signed-short body "$sig" +test_atom refs/tags/signed-short contents:body '' +test_atom refs/tags/signed-short contents:signature "$sig" +test_atom refs/tags/signed-short contents "subject line +$sig" + +test_expect_success GPG 'basic atom: refs/tags/signed-short raw' ' + git cat-file tag refs/tags/signed-short >expected && + ${git_for_each_ref} --format="%(raw)" refs/tags/signed-short >actual && + sanitize_pgp expected.clean && + echo >>expected.clean && + sanitize_pgp actual.clean && + test_cmp expected.clean actual.clean +' + +test_atom refs/tags/signed-long subject 'subject line' +test_atom refs/tags/signed-long subject:sanitize 'subject-line' +test_atom refs/tags/signed-long contents:subject 'subject line' +test_atom refs/tags/signed-long body "body contents +$sig" +test_atom refs/tags/signed-long contents:body 'body contents +' +test_atom refs/tags/signed-long contents:signature "$sig" +test_atom refs/tags/signed-long contents "subject line + +body contents +$sig" + +test_expect_success GPG 'basic atom: refs/tags/signed-long raw' ' + git cat-file tag refs/tags/signed-long >expected && + ${git_for_each_ref} --format="%(raw)" refs/tags/signed-long >actual && + sanitize_pgp expected.clean && + echo >>expected.clean && + sanitize_pgp actual.clean && + test_cmp expected.clean actual.clean +' + +test_expect_success 'set up refs pointing to tree and blob' ' + git update-ref refs/mytrees/first refs/heads/main^{tree} && + git update-ref refs/myblobs/first refs/heads/main:one +' + +test_atom refs/mytrees/first subject "" +test_atom refs/mytrees/first contents:subject "" +test_atom refs/mytrees/first body "" +test_atom refs/mytrees/first contents:body "" +test_atom refs/mytrees/first contents:signature "" +test_atom refs/mytrees/first contents "" + +test_expect_success 'basic atom: refs/mytrees/first raw' ' + git cat-file tree refs/mytrees/first >expected && + echo >>expected && + ${git_for_each_ref} --format="%(raw)" refs/mytrees/first >actual && + test_cmp expected actual && + git cat-file -s refs/mytrees/first >expected && + ${git_for_each_ref} --format="%(raw:size)" refs/mytrees/first >actual && + test_cmp expected actual +' + +test_atom refs/myblobs/first subject "" +test_atom refs/myblobs/first contents:subject "" +test_atom refs/myblobs/first body "" +test_atom refs/myblobs/first contents:body "" +test_atom refs/myblobs/first contents:signature "" +test_atom refs/myblobs/first contents "" + +test_expect_success 'basic atom: refs/myblobs/first raw' ' + git cat-file blob refs/myblobs/first >expected && + echo >>expected && + ${git_for_each_ref} --format="%(raw)" refs/myblobs/first >actual && + test_cmp expected actual && + git cat-file -s refs/myblobs/first >expected && + ${git_for_each_ref} --format="%(raw:size)" refs/myblobs/first >actual && + test_cmp expected actual +' + +test_expect_success 'set up refs pointing to binary blob' ' + printf "a\0b\0c" >blob1 && + printf "a\0c\0b" >blob2 && + printf "\0a\0b\0c" >blob3 && + printf "abc" >blob4 && + printf "\0 \0 \0 " >blob5 && + printf "\0 \0a\0 " >blob6 && + printf " " >blob7 && + >blob8 && + obj=$(git hash-object -w blob1) && + git update-ref refs/myblobs/blob1 "$obj" && + obj=$(git hash-object -w blob2) && + git update-ref refs/myblobs/blob2 "$obj" && + obj=$(git hash-object -w blob3) && + git update-ref refs/myblobs/blob3 "$obj" && + obj=$(git hash-object -w blob4) && + git update-ref refs/myblobs/blob4 "$obj" && + obj=$(git hash-object -w blob5) && + git update-ref refs/myblobs/blob5 "$obj" && + obj=$(git hash-object -w blob6) && + git update-ref refs/myblobs/blob6 "$obj" && + obj=$(git hash-object -w blob7) && + git update-ref refs/myblobs/blob7 "$obj" && + obj=$(git hash-object -w blob8) && + git update-ref refs/myblobs/blob8 "$obj" +' + +test_expect_success 'Verify sorts with raw' ' + cat >expected <<-EOF && + refs/myblobs/blob8 + refs/myblobs/blob5 + refs/myblobs/blob6 + refs/myblobs/blob3 + refs/myblobs/blob7 + refs/mytrees/first + refs/myblobs/first + refs/myblobs/blob1 + refs/myblobs/blob2 + refs/myblobs/blob4 + refs/heads/main + EOF + ${git_for_each_ref} --format="%(refname)" --sort=raw \ + refs/heads/main refs/myblobs/ refs/mytrees/first >actual && + test_cmp expected actual +' + +test_expect_success 'Verify sorts with raw:size' ' + cat >expected <<-EOF && + refs/myblobs/blob8 + refs/myblobs/blob7 + refs/myblobs/blob4 + refs/myblobs/blob1 + refs/myblobs/blob2 + refs/myblobs/blob3 + refs/myblobs/blob5 + refs/myblobs/blob6 + refs/myblobs/first + refs/mytrees/first + refs/heads/main + EOF + ${git_for_each_ref} --format="%(refname)" --sort=raw:size \ + refs/heads/main refs/myblobs/ refs/mytrees/first >actual && + test_cmp expected actual +' + +test_expect_success 'validate raw atom with %(if:equals)' ' + cat >expected <<-EOF && + not equals + not equals + not equals + not equals + not equals + not equals + refs/myblobs/blob4 + not equals + not equals + not equals + not equals + not equals + EOF + ${git_for_each_ref} --format="%(if:equals=abc)%(raw)%(then)%(refname)%(else)not equals%(end)" \ + refs/myblobs/ refs/heads/ >actual && + test_cmp expected actual +' + +test_expect_success 'validate raw atom with %(if:notequals)' ' + cat >expected <<-EOF && + refs/heads/ambiguous + refs/heads/main + refs/heads/newtag + refs/myblobs/blob1 + refs/myblobs/blob2 + refs/myblobs/blob3 + equals + refs/myblobs/blob5 + refs/myblobs/blob6 + refs/myblobs/blob7 + refs/myblobs/blob8 + refs/myblobs/first + EOF + ${git_for_each_ref} --format="%(if:notequals=abc)%(raw)%(then)%(refname)%(else)equals%(end)" \ + refs/myblobs/ refs/heads/ >actual && + test_cmp expected actual +' + +test_expect_success 'empty raw refs with %(if)' ' + cat >expected <<-EOF && + refs/myblobs/blob1 not empty + refs/myblobs/blob2 not empty + refs/myblobs/blob3 not empty + refs/myblobs/blob4 not empty + refs/myblobs/blob5 not empty + refs/myblobs/blob6 not empty + refs/myblobs/blob7 empty + refs/myblobs/blob8 empty + refs/myblobs/first not empty + EOF + ${git_for_each_ref} --format="%(refname) %(if)%(raw)%(then)not empty%(else)empty%(end)" \ + refs/myblobs/ >actual && + test_cmp expected actual +' + +test_expect_success '%(raw) with --python must fail' ' + test_must_fail ${git_for_each_ref} --format="%(raw)" --python +' + +test_expect_success '%(raw) with --tcl must fail' ' + test_must_fail ${git_for_each_ref} --format="%(raw)" --tcl +' + +test_expect_success PERL_TEST_HELPERS '%(raw) with --perl' ' + ${git_for_each_ref} --format="\$name= %(raw); +print \"\$name\"" refs/myblobs/blob1 --perl | perl >actual && + cmp blob1 actual && + ${git_for_each_ref} --format="\$name= %(raw); +print \"\$name\"" refs/myblobs/blob3 --perl | perl >actual && + cmp blob3 actual && + ${git_for_each_ref} --format="\$name= %(raw); +print \"\$name\"" refs/myblobs/blob8 --perl | perl >actual && + cmp blob8 actual && + ${git_for_each_ref} --format="\$name= %(raw); +print \"\$name\"" refs/myblobs/first --perl | perl >actual && + cmp one actual && + git cat-file tree refs/mytrees/first > expected && + ${git_for_each_ref} --format="\$name= %(raw); +print \"\$name\"" refs/mytrees/first --perl | perl >actual && + cmp expected actual +' + +test_expect_success '%(raw) with --shell must fail' ' + test_must_fail ${git_for_each_ref} --format="%(raw)" --shell +' + +test_expect_success '%(raw) with --shell and --sort=raw must fail' ' + test_must_fail ${git_for_each_ref} --format="%(raw)" --sort=raw --shell +' + +test_expect_success '%(raw:size) with --shell' ' + ${git_for_each_ref} --format="%(raw:size)" | sed "s/^/$SQ/;s/$/$SQ/" >expect && + ${git_for_each_ref} --format="%(raw:size)" --shell >actual && + test_cmp expect actual +' + +test_expect_success "${git_for_each_ref} --format compare with cat-file --batch" ' + git rev-parse refs/mytrees/first | git cat-file --batch >expected && + ${git_for_each_ref} --format="%(objectname) %(objecttype) %(objectsize) +%(raw)" refs/mytrees/first >actual && + test_cmp expected actual +' + +test_expect_success 'verify sorts with contents:size' ' + cat >expect <<-\EOF && + refs/heads/main + refs/heads/newtag + refs/heads/ambiguous + EOF + ${git_for_each_ref} --format="%(refname)" \ + --sort=contents:size refs/heads/ >actual && + test_cmp expect actual +' + +test_expect_success 'set up multiple-sort tags' ' + for when in 100000 200000 + do + for email in user1 user2 + do + for ref in ref1 ref2 + do + GIT_COMMITTER_DATE="@$when +0000" \ + GIT_COMMITTER_EMAIL="$email@example.com" \ + git tag -m "tag $ref-$when-$email" \ + multi-$ref-$when-$email || return 1 + done + done + done +' + +test_expect_success 'Verify sort with multiple keys' ' + cat >expected <<-\EOF && + 100000 refs/tags/multi-ref2-100000-user1 + 100000 refs/tags/multi-ref1-100000-user1 + 100000 refs/tags/multi-ref2-100000-user2 + 100000 refs/tags/multi-ref1-100000-user2 + 200000 refs/tags/multi-ref2-200000-user1 + 200000 refs/tags/multi-ref1-200000-user1 + 200000 refs/tags/multi-ref2-200000-user2 + 200000 refs/tags/multi-ref1-200000-user2 + EOF + ${git_for_each_ref} \ + --format="%(taggerdate:unix) %(taggeremail) %(refname)" \ + --sort=-refname \ + --sort=taggeremail \ + --sort=taggerdate \ + "refs/tags/multi-*" >actual && + test_cmp expected actual +' + +test_expect_success 'equivalent sorts fall back on refname' ' + cat >expected <<-\EOF && + 100000 refs/tags/multi-ref1-100000-user1 + 100000 refs/tags/multi-ref1-100000-user2 + 100000 refs/tags/multi-ref2-100000-user1 + 100000 refs/tags/multi-ref2-100000-user2 + 200000 refs/tags/multi-ref1-200000-user1 + 200000 refs/tags/multi-ref1-200000-user2 + 200000 refs/tags/multi-ref2-200000-user1 + 200000 refs/tags/multi-ref2-200000-user2 + EOF + ${git_for_each_ref} \ + --format="%(taggerdate:unix) %(taggeremail) %(refname)" \ + --sort=taggerdate \ + "refs/tags/multi-*" >actual && + test_cmp expected actual +' + +test_expect_success '--no-sort cancels the previous sort keys' ' + cat >expected <<-\EOF && + 100000 refs/tags/multi-ref1-100000-user1 + 100000 refs/tags/multi-ref1-100000-user2 + 100000 refs/tags/multi-ref2-100000-user1 + 100000 refs/tags/multi-ref2-100000-user2 + 200000 refs/tags/multi-ref1-200000-user1 + 200000 refs/tags/multi-ref1-200000-user2 + 200000 refs/tags/multi-ref2-200000-user1 + 200000 refs/tags/multi-ref2-200000-user2 + EOF + ${git_for_each_ref} \ + --format="%(taggerdate:unix) %(taggeremail) %(refname)" \ + --sort=-refname \ + --sort=taggeremail \ + --no-sort \ + --sort=taggerdate \ + "refs/tags/multi-*" >actual && + test_cmp expected actual +' + +test_expect_success '--no-sort without subsequent --sort prints expected refs' ' + cat >expected <<-\EOF && + refs/tags/multi-ref1-100000-user1 + refs/tags/multi-ref1-100000-user2 + refs/tags/multi-ref1-200000-user1 + refs/tags/multi-ref1-200000-user2 + refs/tags/multi-ref2-100000-user1 + refs/tags/multi-ref2-100000-user2 + refs/tags/multi-ref2-200000-user1 + refs/tags/multi-ref2-200000-user2 + EOF + + # Sort the results with `sort` for a consistent comparison against + # expected + ${git_for_each_ref} \ + --format="%(refname)" \ + --no-sort \ + "refs/tags/multi-*" | sort >actual && + test_cmp expected actual +' + +test_expect_success 'set up custom date sorting' ' + # Dates: + # - Wed Feb 07 2024 21:34:20 +0000 + # - Tue Dec 14 1999 00:05:22 +0000 + # - Fri Jun 04 2021 11:26:51 +0000 + # - Mon Jan 22 2007 16:44:01 GMT+0000 + i=1 && + for when in 1707341660 945129922 1622806011 1169484241 + do + GIT_COMMITTER_DATE="@$when +0000" \ + GIT_COMMITTER_EMAIL="user@example.com" \ + git tag -m "tag $when" custom-dates-$i && + i=$(($i+1)) || return 1 + done +' + +test_expect_success 'sort by date defaults to full timestamp' ' + cat >expected <<-\EOF && + 945129922 refs/tags/custom-dates-2 + 1169484241 refs/tags/custom-dates-4 + 1622806011 refs/tags/custom-dates-3 + 1707341660 refs/tags/custom-dates-1 + EOF + + ${git_for_each_ref} \ + --format="%(creatordate:unix) %(refname)" \ + --sort=creatordate \ + "refs/tags/custom-dates-*" >actual && + test_cmp expected actual +' + +test_expect_success 'sort by custom date format' ' + cat >expected <<-\EOF && + 00:05:22 refs/tags/custom-dates-2 + 11:26:51 refs/tags/custom-dates-3 + 16:44:01 refs/tags/custom-dates-4 + 21:34:20 refs/tags/custom-dates-1 + EOF + + ${git_for_each_ref} \ + --format="%(creatordate:format:%H:%M:%S) %(refname)" \ + --sort="creatordate:format:%H:%M:%S" \ + "refs/tags/custom-dates-*" >actual && + test_cmp expected actual +' + +test_expect_success 'do not dereference NULL upon %(HEAD) on unborn branch' ' + test_when_finished "git checkout main" && + ${git_for_each_ref} --format="%(HEAD) %(refname:short)" refs/heads/ >actual && + sed -e "s/^\* / /" actual >expect && + git checkout --orphan orphaned-branch && + ${git_for_each_ref} --format="%(HEAD) %(refname:short)" refs/heads/ >actual && + test_cmp expect actual +' + +cat >trailers < +Signed-off-by: A U Thor +[ v2 updated patch description ] +Acked-by: A U Thor + +EOF + +unfold () { + perl -0pe 's/\n\s+/ /g' +} + +test_expect_success 'set up trailers for next test' ' + echo "Some contents" > two && + git add two && + git commit -F - <<-EOF + trailers: this commit message has trailers + + Some message contents + + $(cat trailers) + EOF +' + +test_trailer_option () { + if test "$#" -eq 3 + then + prereq="$1" + shift + fi && + title=$1 option=$2 + cat >expect + test_expect_success $prereq "$title" ' + ${git_for_each_ref} --format="%($option)" refs/heads/main >actual && + test_cmp expect actual && + ${git_for_each_ref} --format="%(contents:$option)" refs/heads/main >actual && + test_cmp expect actual + ' +} + +test_trailer_option PERL_TEST_HELPERS '%(trailers:unfold) unfolds trailers' \ + 'trailers:unfold' <<-EOF + $(unfold + + EOF + +test_trailer_option '%(trailers:key=foo) is case insensitive' \ + 'trailers:key=SiGned-oFf-bY' <<-EOF + Signed-off-by: A U Thor + + EOF + +test_trailer_option '%(trailers:key=foo:) trailing colon also works' \ + 'trailers:key=Signed-off-by:' <<-EOF + Signed-off-by: A U Thor + + EOF + +test_trailer_option '%(trailers:key=foo) multiple keys' \ + 'trailers:key=Reviewed-by:,key=Signed-off-by' <<-EOF + Reviewed-by: A U Thor + Signed-off-by: A U Thor + + EOF + +test_trailer_option '%(trailers:key=nonexistent) becomes empty' \ + 'trailers:key=Shined-off-by:' <<-EOF + + EOF + +test_trailer_option '%(trailers:key=foo) handles multiple lines even if folded' \ + 'trailers:key=Acked-by' <<-EOF + $(grep -v patch.description + $(grep patch.description + + EOF + +test_trailer_option '%(trailers:separator) changes separator' \ + 'trailers:separator=%x2C,key=Reviewed-by,key=Signed-off-by:' <<-EOF + Reviewed-by: A U Thor ,Signed-off-by: A U Thor + EOF + +test_trailer_option '%(trailers:key_value_separator) changes key-value separator' \ + 'trailers:key_value_separator=%x2C,key=Reviewed-by,key=Signed-off-by:' <<-EOF + Reviewed-by,A U Thor + Signed-off-by,A U Thor + + EOF + +test_trailer_option '%(trailers:separator,key_value_separator) changes both separators' \ + 'trailers:separator=%x2C,key_value_separator=%x2C,key=Reviewed-by,key=Signed-off-by:' <<-EOF + Reviewed-by,A U Thor ,Signed-off-by,A U Thor + EOF + +test_expect_success 'multiple %(trailers) use their own options' ' + git tag -F - tag-with-trailers <<-\EOF && + body + + one: foo + one: bar + two: baz + two: qux + EOF + t1="%(trailers:key=one,key_value_separator=W,separator=X)" && + t2="%(trailers:key=two,key_value_separator=Y,separator=Z)" && + ${git_for_each_ref} --format="$t1%0a$t2" refs/tags/tag-with-trailers >actual && + cat >expect <<-\EOF && + oneWfooXoneWbar + twoYbazZtwoYqux + EOF + test_cmp expect actual +' + +test_failing_trailer_option () { + title=$1 option=$2 + cat >expect + test_expect_success "$title" ' + # error message cannot be checked under i18n + test_must_fail ${git_for_each_ref} --format="%($option)" refs/heads/main 2>actual && + test_cmp expect actual && + test_must_fail ${git_for_each_ref} --format="%(contents:$option)" refs/heads/main 2>actual && + test_cmp expect actual + ' +} + +test_failing_trailer_option '%(trailers) rejects unknown trailers arguments' \ + 'trailers:unsupported' <<-\EOF + fatal: unknown %(trailers) argument: unsupported + EOF + +test_failing_trailer_option '%(trailers:key) without value is error' \ + 'trailers:key' <<-\EOF + fatal: expected %(trailers:key=) + EOF + +test_expect_success 'if arguments, %(contents:trailers) shows error if colon is missing' ' + cat >expect <<-EOF && + fatal: unrecognized %(contents) argument: trailersonly + EOF + test_must_fail ${git_for_each_ref} --format="%(contents:trailersonly)" 2>actual && + test_cmp expect actual +' + +test_expect_success 'basic atom: head contents:trailers' ' + ${git_for_each_ref} --format="%(contents:trailers)" refs/heads/main >actual && + sanitize_pgp actual.clean && + # ${git_for_each_ref} ends with a blank line + cat >expect <<-EOF && + $(cat trailers) + + EOF + test_cmp expect actual.clean +' + +test_expect_success 'basic atom: rest must fail' ' + test_must_fail ${git_for_each_ref} --format="%(rest)" refs/heads/main +' + +test_expect_success 'HEAD atom does not take arguments' ' + test_must_fail ${git_for_each_ref} --format="%(HEAD:foo)" 2>err && + echo "fatal: %(HEAD) does not take arguments" >expect && + test_cmp expect err +' + +test_expect_success 'subject atom rejects unknown arguments' ' + test_must_fail ${git_for_each_ref} --format="%(subject:foo)" 2>err && + echo "fatal: unrecognized %(subject) argument: foo" >expect && + test_cmp expect err +' + +test_expect_success 'refname atom rejects unknown arguments' ' + test_must_fail ${git_for_each_ref} --format="%(refname:foo)" 2>err && + echo "fatal: unrecognized %(refname) argument: foo" >expect && + test_cmp expect err +' + +test_expect_success 'trailer parsing not fooled by --- line' ' + git commit --allow-empty -F - <<-\EOF && + this is the subject + + This is the body. The message has a "---" line which would confuse a + message+patch parser. But here we know we have only a commit message, + so we get it right. + + trailer: wrong + --- + This is more body. + + trailer: right + EOF + + { + echo "trailer: right" && + echo + } >expect && + ${git_for_each_ref} --format="%(trailers)" refs/heads/main >actual && + test_cmp expect actual +' + +test_expect_success 'Add symbolic ref for the following tests' ' + git symbolic-ref refs/heads/sym refs/heads/main +' + +cat >expected <actual && + test_cmp expected actual +' + +cat >expected <actual && + test_cmp expected actual +' + +cat >expected < actual && + ${git_for_each_ref} --format="%(symref:lstrip=-2)" refs/heads/sym >> actual && + test_cmp expected actual && + + ${git_for_each_ref} --format="%(symref:strip=2)" refs/heads/sym > actual && + ${git_for_each_ref} --format="%(symref:strip=-2)" refs/heads/sym >> actual && + test_cmp expected actual +' + +cat >expected < actual && + ${git_for_each_ref} --format="%(symref:rstrip=-2)" refs/heads/sym >> actual && + test_cmp expected actual +' + +test_expect_success ':remotename and :remoteref' ' + git init remote-tests && + ( + cd remote-tests && + test_commit initial && + git branch -M main && + git remote add from fifth.coffee:blub && + git config branch.main.remote from && + git config branch.main.merge refs/heads/stable && + git remote add to southridge.audio:repo && + git config remote.to.push "refs/heads/*:refs/heads/pushed/*" && + git config branch.main.pushRemote to && + for pair in "%(upstream)=refs/remotes/from/stable" \ + "%(upstream:remotename)=from" \ + "%(upstream:remoteref)=refs/heads/stable" \ + "%(push)=refs/remotes/to/pushed/main" \ + "%(push:remotename)=to" \ + "%(push:remoteref)=refs/heads/pushed/main" + do + echo "${pair#*=}" >expect && + ${git_for_each_ref} --format="${pair%=*}" \ + refs/heads/main >actual && + test_cmp expect actual || exit 1 + done && + git branch push-simple && + git config branch.push-simple.pushRemote from && + actual="$(${git_for_each_ref} \ + --format="%(push:remotename),%(push:remoteref)" \ + refs/heads/push-simple)" && + test from, = "$actual" + ) +' + +test_expect_success "${git_for_each_ref} --ignore-case ignores case" ' + ${git_for_each_ref} --format="%(refname)" refs/heads/MAIN >actual && + test_must_be_empty actual && + + echo refs/heads/main >expect && + ${git_for_each_ref} --format="%(refname)" --ignore-case \ + refs/heads/MAIN >actual && + test_cmp expect actual +' + +test_expect_success "${git_for_each_ref} --omit-empty works" ' + ${git_for_each_ref} --format="%(refname)" >actual && + test_line_count -gt 1 actual && + ${git_for_each_ref} --format="%(if:equals=refs/heads/main)%(refname)%(then)%(refname)%(end)" --omit-empty >actual && + echo refs/heads/main >expect && + test_cmp expect actual +' + +test_expect_success "${git_for_each_ref} --ignore-case works on multiple sort keys" ' + # name refs numerically to avoid case-insensitive filesystem conflicts + nr=0 && + for email in a A b B + do + for subject in a A b B + do + GIT_COMMITTER_EMAIL="$email@example.com" \ + git tag -m "tag $subject" icase-$(printf %02d $nr) && + nr=$((nr+1))|| + return 1 + done + done && + ${git_for_each_ref} --ignore-case \ + --format="%(taggeremail) %(subject) %(refname)" \ + --sort=refname \ + --sort=subject \ + --sort=taggeremail \ + refs/tags/icase-* >actual && + cat >expect <<-\EOF && + tag a refs/tags/icase-00 + tag A refs/tags/icase-01 + tag a refs/tags/icase-04 + tag A refs/tags/icase-05 + tag b refs/tags/icase-02 + tag B refs/tags/icase-03 + tag b refs/tags/icase-06 + tag B refs/tags/icase-07 + tag a refs/tags/icase-08 + tag A refs/tags/icase-09 + tag a refs/tags/icase-12 + tag A refs/tags/icase-13 + tag b refs/tags/icase-10 + tag B refs/tags/icase-11 + tag b refs/tags/icase-14 + tag B refs/tags/icase-15 + EOF + test_cmp expect actual +' + +test_expect_success "${git_for_each_ref} reports broken tags" ' + git tag -m "good tag" broken-tag-good HEAD && + git cat-file tag broken-tag-good >good && + sed s/commit/blob/ bad && + bad=$(git hash-object -w -t tag bad) && + git update-ref refs/tags/broken-tag-bad $bad && + test_must_fail ${git_for_each_ref} --format="%(*objectname)" \ + refs/tags/broken-tag-* && + test_must_fail ${git_for_each_ref} --format="%(*objectname)" \ + refs/tags/broken-tag-bad +' + +test_expect_success 'set up tag with signature and no blank lines' ' + git tag -F - fake-sig-no-blanks <<-\EOF + this is the subject + -----BEGIN PGP SIGNATURE----- + not a real signature, but we just care about the + subject/body parsing. It is important here that + there are no blank lines in the signature. + -----END PGP SIGNATURE----- + EOF +' + +test_atom refs/tags/fake-sig-no-blanks contents:subject 'this is the subject' +test_atom refs/tags/fake-sig-no-blanks contents:body '' +test_atom refs/tags/fake-sig-no-blanks contents:signature "$sig" + +test_expect_success 'set up tag with CRLF signature' ' + append_cr <<-\EOF | + this is the subject + -----BEGIN PGP SIGNATURE----- + + not a real signature, but we just care about + the subject/body parsing. It is important here + that there is a blank line separating this + from the signature header. + -----END PGP SIGNATURE----- + EOF + git tag -F - --cleanup=verbatim fake-sig-crlf +' + +test_atom refs/tags/fake-sig-crlf contents:subject 'this is the subject' +test_atom refs/tags/fake-sig-crlf contents:body '' + +# CRLF is retained in the signature, so we have to pass our expected value +# through append_cr. But test_atom requires a shell string, which means command +# substitution, and the shell will strip trailing newlines from the output of +# the substitution. Hack around it by adding and then removing a dummy line. +sig_crlf="$(printf "%s" "$sig" | append_cr; echo dummy)" +sig_crlf=${sig_crlf%dummy} +test_atom refs/tags/fake-sig-crlf contents:signature "$sig_crlf" + +test_expect_success 'set up tag with signature and trailers' ' + git tag -F - fake-sig-trailer <<-\EOF + this is the subject + + this is the body + + My-Trailer: foo + -----BEGIN PGP SIGNATURE----- + + not a real signature, but we just care about the + subject/body/trailer parsing. + -----END PGP SIGNATURE----- + EOF +' + +# use "separator=" here to suppress the terminating newline +test_atom refs/tags/fake-sig-trailer trailers:separator= 'My-Trailer: foo' + +test_expect_success "${git_for_each_ref} --stdin: empty" ' + >in && + ${git_for_each_ref} --format="%(refname)" --stdin actual && + ${git_for_each_ref} --format="%(refname)" >expect && + test_cmp expect actual +' + +test_expect_success "${git_for_each_ref} --stdin: fails if extra args" ' + >in && + test_must_fail ${git_for_each_ref} --format="%(refname)" \ + --stdin refs/heads/extra err && + grep "unknown arguments supplied with --stdin" err +' + +test_expect_success "${git_for_each_ref} --stdin: matches" ' + cat >in <<-EOF && + refs/tags/multi* + refs/heads/amb* + EOF + + cat >expect <<-EOF && + refs/heads/ambiguous + refs/tags/multi-ref1-100000-user1 + refs/tags/multi-ref1-100000-user2 + refs/tags/multi-ref1-200000-user1 + refs/tags/multi-ref1-200000-user2 + refs/tags/multi-ref2-100000-user1 + refs/tags/multi-ref2-100000-user2 + refs/tags/multi-ref2-200000-user1 + refs/tags/multi-ref2-200000-user2 + refs/tags/multiline + EOF + + ${git_for_each_ref} --format="%(refname)" --stdin actual && + test_cmp expect actual +' + +test_expect_success "${git_for_each_ref} with non-existing refs" ' + cat >in <<-EOF && + refs/heads/this-ref-does-not-exist + refs/tags/bogus + EOF + + ${git_for_each_ref} --format="%(refname)" --stdin actual && + test_must_be_empty actual && + + xargs ${git_for_each_ref} --format="%(refname)" actual && + test_must_be_empty actual +' + +test_expect_success "${git_for_each_ref} with nested tags" ' + git tag -am "Normal tag" nested/base HEAD && + git tag -am "Nested tag" nested/nest1 refs/tags/nested/base && + git tag -am "Double nested tag" nested/nest2 refs/tags/nested/nest1 && + + head_oid="$(git rev-parse HEAD)" && + base_tag_oid="$(git rev-parse refs/tags/nested/base)" && + nest1_tag_oid="$(git rev-parse refs/tags/nested/nest1)" && + nest2_tag_oid="$(git rev-parse refs/tags/nested/nest2)" && + + cat >expect <<-EOF && + refs/tags/nested/base $base_tag_oid tag $head_oid commit + refs/tags/nested/nest1 $nest1_tag_oid tag $head_oid commit + refs/tags/nested/nest2 $nest2_tag_oid tag $head_oid commit + EOF + + ${git_for_each_ref} \ + --format="%(refname) %(objectname) %(objecttype) %(*objectname) %(*objecttype)" \ + refs/tags/nested/ >actual && + test_cmp expect actual +' + +test_expect_success 'is-base atom with non-commits' ' + ${git_for_each_ref} --format="%(is-base:HEAD) %(refname)" >out 2>err && + grep "(HEAD) refs/heads/main" out && + + test_line_count = 2 err && + grep "error: object .* is a commit, not a blob" err && + grep "error: bad tag pointer to" err +' + +GRADE_FORMAT="%(signature:grade)%0a%(signature:key)%0a%(signature:signer)%0a%(signature:fingerprint)%0a%(signature:primarykeyfingerprint)" +TRUSTLEVEL_FORMAT="%(signature:trustlevel)%0a%(signature:key)%0a%(signature:signer)%0a%(signature:fingerprint)%0a%(signature:primarykeyfingerprint)" + +test_expect_success GPG 'setup for signature atom using gpg' ' + git checkout -b signed && + + test_when_finished "test_unconfig commit.gpgSign" && + + echo "1" >file && + git add file && + test_tick && + git commit -S -m "file: 1" && + git tag first-signed && + + echo "2" >file && + test_tick && + git commit -a -m "file: 2" && + git tag second-unsigned && + + git config commit.gpgSign 1 && + echo "3" >file && + test_tick && + git commit -a --no-gpg-sign -m "file: 3" && + git tag third-unsigned && + + test_tick && + git rebase -f HEAD^^ && git tag second-signed HEAD^ && + git tag third-signed && + + echo "4" >file && + test_tick && + git commit -a -SB7227189 -m "file: 4" && + git tag fourth-signed && + + echo "5" >file && + test_tick && + git commit -a --no-gpg-sign -m "file: 5" && + git tag fifth-unsigned && + + echo "6" >file && + test_tick && + git commit -a --no-gpg-sign -m "file: 6" && + + test_tick && + git rebase -f HEAD^^ && + git tag fifth-signed HEAD^ && + git tag sixth-signed && + + echo "7" >file && + test_tick && + git commit -a --no-gpg-sign -m "file: 7" && + git tag seventh-unsigned +' + +test_expect_success GPGSSH 'setup for signature atom using ssh' ' + test_when_finished "test_unconfig gpg.format user.signingkey" && + + test_config gpg.format ssh && + test_config user.signingkey "${GPGSSH_KEY_PRIMARY}" && + echo "8" >file && + test_tick && + git add file && + git commit -S -m "file: 8" && + git tag eighth-signed-ssh +' + +test_expect_success GPG2 'bare signature atom' ' + git verify-commit first-signed 2>expect && + echo >>expect && + ${git_for_each_ref} refs/tags/first-signed \ + --format="%(signature)" >actual && + test_cmp expect actual +' + +test_expect_success GPG 'show good signature with custom format' ' + git verify-commit first-signed && + cat >expect <<-\EOF && + G + 13B6F51ECDDE430D + C O Mitter + 73D758744BE721698EC54E8713B6F51ECDDE430D + 73D758744BE721698EC54E8713B6F51ECDDE430D + EOF + ${git_for_each_ref} refs/tags/first-signed \ + --format="$GRADE_FORMAT" >actual && + test_cmp expect actual +' +test_expect_success GPGSSH 'show good signature with custom format with ssh' ' + test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" && + FINGERPRINT=$(ssh-keygen -lf "${GPGSSH_KEY_PRIMARY}" | awk "{print \$2;}") && + cat >expect.tmpl <<-\EOF && + G + FINGERPRINT + principal with number 1 + FINGERPRINT + + EOF + sed "s|FINGERPRINT|$FINGERPRINT|g" expect.tmpl >expect && + ${git_for_each_ref} refs/tags/eighth-signed-ssh \ + --format="$GRADE_FORMAT" >actual && + test_cmp expect actual +' + +test_expect_success GPG 'signature atom with grade option and bad signature' ' + git cat-file commit third-signed >raw && + sed -e "s/^file: 3/file: 3 forged/" raw >forged1 && + FORGED1=$(git hash-object -w -t commit forged1) && + git update-ref refs/tags/third-signed "$FORGED1" && + test_must_fail git verify-commit "$FORGED1" && + + cat >expect <<-\EOF && + B + 13B6F51ECDDE430D + C O Mitter + + + EOF + ${git_for_each_ref} refs/tags/third-signed \ + --format="$GRADE_FORMAT" >actual && + test_cmp expect actual +' + +test_expect_success GPG 'show untrusted signature with custom format' ' + cat >expect <<-\EOF && + U + 65A0EEA02E30CAD7 + Eris Discordia + F8364A59E07FFE9F4D63005A65A0EEA02E30CAD7 + D4BE22311AD3131E5EDA29A461092E85B7227189 + EOF + ${git_for_each_ref} refs/tags/fourth-signed \ + --format="$GRADE_FORMAT" >actual && + test_cmp expect actual +' + +test_expect_success GPG 'show untrusted signature with undefined trust level' ' + cat >expect <<-\EOF && + undefined + 65A0EEA02E30CAD7 + Eris Discordia + F8364A59E07FFE9F4D63005A65A0EEA02E30CAD7 + D4BE22311AD3131E5EDA29A461092E85B7227189 + EOF + ${git_for_each_ref} refs/tags/fourth-signed \ + --format="$TRUSTLEVEL_FORMAT" >actual && + test_cmp expect actual +' + +test_expect_success GPG 'show untrusted signature with ultimate trust level' ' + cat >expect <<-\EOF && + ultimate + 13B6F51ECDDE430D + C O Mitter + 73D758744BE721698EC54E8713B6F51ECDDE430D + 73D758744BE721698EC54E8713B6F51ECDDE430D + EOF + ${git_for_each_ref} refs/tags/sixth-signed \ + --format="$TRUSTLEVEL_FORMAT" >actual && + test_cmp expect actual +' + +test_expect_success GPG 'show unknown signature with custom format' ' + cat >expect <<-\EOF && + E + 13B6F51ECDDE430D + + + + EOF + GNUPGHOME="$GNUPGHOME_NOT_USED" ${git_for_each_ref} \ + refs/tags/sixth-signed --format="$GRADE_FORMAT" >actual && + test_cmp expect actual +' + +test_expect_success GPG 'show lack of signature with custom format' ' + cat >expect <<-\EOF && + N + + + + + EOF + ${git_for_each_ref} refs/tags/seventh-unsigned \ + --format="$GRADE_FORMAT" >actual && + test_cmp expect actual +' + +test_done diff --git a/t/pack-refs-tests.sh b/t/pack-refs-tests.sh new file mode 100644 index 00000000..81086c36 --- /dev/null +++ b/t/pack-refs-tests.sh @@ -0,0 +1,461 @@ +pack_refs=${pack_refs:-pack-refs} + +test_expect_success 'enable reflogs' ' + git config core.logallrefupdates true +' + +test_expect_success 'prepare a trivial repository' ' + echo Hello > A && + git update-index --add A && + git commit -m "Initial commit." && + HEAD=$(git rev-parse --verify HEAD) +' + +test_expect_success '${pack_refs} --prune --all' ' + test_path_is_missing .git/packed-refs && + git ${pack_refs} --no-prune --all && + test_path_is_file .git/packed-refs && + N=$(find .git/refs -type f | wc -l) && + test "$N" != 0 && + + git ${pack_refs} --prune --all && + test_path_is_file .git/packed-refs && + N=$(find .git/refs -type f) && + test -z "$N" +' + +SHA1= + +test_expect_success 'see if git show-ref works as expected' ' + git branch a && + SHA1=$(cat .git/refs/heads/a) && + echo "$SHA1 refs/heads/a" >expect && + git show-ref a >result && + test_cmp expect result +' + +test_expect_success 'see if a branch still exists when packed' ' + git branch b && + git ${pack_refs} --all && + rm -f .git/refs/heads/b && + echo "$SHA1 refs/heads/b" >expect && + git show-ref b >result && + test_cmp expect result +' + +test_expect_success 'git branch c/d should barf if branch c exists' ' + git branch c && + git ${pack_refs} --all && + rm -f .git/refs/heads/c && + test_must_fail git branch c/d +' + +test_expect_success 'see if a branch still exists after git ${pack_refs} --prune' ' + git branch e && + git ${pack_refs} --all --prune && + echo "$SHA1 refs/heads/e" >expect && + git show-ref e >result && + test_cmp expect result +' + +test_expect_success 'see if git ${pack_refs} --prune remove ref files' ' + git branch f && + git ${pack_refs} --all --prune && + ! test -f .git/refs/heads/f +' + +test_expect_success 'see if git ${pack_refs} --prune removes empty dirs' ' + git branch r/s/t && + git ${pack_refs} --all --prune && + ! test -e .git/refs/heads/r +' + +test_expect_success 'git branch g should work when git branch g/h has been deleted' ' + git branch g/h && + git ${pack_refs} --all --prune && + git branch -d g/h && + git branch g && + git ${pack_refs} --all && + git branch -d g +' + +test_expect_success 'git branch i/j/k should barf if branch i exists' ' + git branch i && + git ${pack_refs} --all --prune && + test_must_fail git branch i/j/k +' + +test_expect_success 'test git branch k after branch k/l/m and k/lm have been deleted' ' + git branch k/l && + git branch k/lm && + git branch -d k/l && + git branch k/l/m && + git branch -d k/l/m && + git branch -d k/lm && + git branch k +' + +test_expect_success 'test git branch n after some branch deletion and pruning' ' + git branch n/o && + git branch n/op && + git branch -d n/o && + git branch n/o/p && + git branch -d n/op && + git ${pack_refs} --all --prune && + git branch -d n/o/p && + git branch n +' + +test_expect_success 'test excluded refs are not packed' ' + git branch dont_pack1 && + git branch dont_pack2 && + git branch pack_this && + git ${pack_refs} --all --exclude "refs/heads/dont_pack*" && + test -f .git/refs/heads/dont_pack1 && + test -f .git/refs/heads/dont_pack2 && + ! test -f .git/refs/heads/pack_this' + +test_expect_success 'test --no-exclude refs clears excluded refs' ' + git branch dont_pack3 && + git branch dont_pack4 && + git ${pack_refs} --all --exclude "refs/heads/dont_pack*" --no-exclude && + ! test -f .git/refs/heads/dont_pack3 && + ! test -f .git/refs/heads/dont_pack4' + +test_expect_success 'test only included refs are packed' ' + git branch pack_this1 && + git branch pack_this2 && + git tag dont_pack5 && + git ${pack_refs} --include "refs/heads/pack_this*" && + test -f .git/refs/tags/dont_pack5 && + ! test -f .git/refs/heads/pack_this1 && + ! test -f .git/refs/heads/pack_this2' + +test_expect_success 'test --no-include refs clears included refs' ' + git branch pack1 && + git branch pack2 && + git ${pack_refs} --include "refs/heads/pack*" --no-include && + test -f .git/refs/heads/pack1 && + test -f .git/refs/heads/pack2' + +test_expect_success 'test --exclude takes precedence over --include' ' + git branch dont_pack5 && + git ${pack_refs} --include "refs/heads/pack*" --exclude "refs/heads/pack*" && + test -f .git/refs/heads/dont_pack5' + +test_expect_success 'see if up-to-date packed refs are preserved' ' + git branch q && + git ${pack_refs} --all --prune && + git update-ref refs/heads/q refs/heads/q && + ! test -f .git/refs/heads/q +' + +test_expect_success 'pack, prune and repack' ' + git tag foo && + git ${pack_refs} --all --prune && + git show-ref >all-of-them && + git ${pack_refs} && + git show-ref >again && + test_cmp all-of-them again +' + +test_expect_success 'explicit ${pack_refs} with dangling packed reference' ' + git commit --allow-empty -m "soon to be garbage-collected" && + git ${pack_refs} --all && + git reset --hard HEAD^ && + git reflog expire --expire=all --all && + git prune --expire=all && + git ${pack_refs} --all 2>result && + test_must_be_empty result +' + +test_expect_success 'delete ref with dangling packed version' ' + git checkout -b lamb && + git commit --allow-empty -m "future garbage" && + git ${pack_refs} --all && + git reset --hard HEAD^ && + git checkout main && + git reflog expire --expire=all --all && + git prune --expire=all && + git branch -d lamb 2>result && + test_must_be_empty result +' + +test_expect_success 'delete ref while another dangling packed ref' ' + git branch lamb && + git commit --allow-empty -m "future garbage" && + git ${pack_refs} --all && + git reset --hard HEAD^ && + git reflog expire --expire=all --all && + git prune --expire=all && + git branch -d lamb 2>result && + test_must_be_empty result +' + +test_expect_success 'pack ref directly below refs/' ' + git update-ref refs/top HEAD && + git ${pack_refs} --all --prune && + grep refs/top .git/packed-refs && + test_path_is_missing .git/refs/top +' + +test_expect_success 'do not pack ref in refs/bisect' ' + git update-ref refs/bisect/local HEAD && + git ${pack_refs} --all --prune && + ! grep refs/bisect/local .git/packed-refs >/dev/null && + test_path_is_file .git/refs/bisect/local +' + +test_expect_success 'disable reflogs' ' + git config core.logallrefupdates false && + rm -rf .git/logs +' + +test_expect_success 'create packed foo/bar/baz branch' ' + git branch foo/bar/baz && + git ${pack_refs} --all --prune && + test_path_is_missing .git/refs/heads/foo/bar/baz && + test_must_fail git reflog exists refs/heads/foo/bar/baz +' + +test_expect_success 'notice d/f conflict with existing directory' ' + test_must_fail git branch foo && + test_must_fail git branch foo/bar +' + +test_expect_success 'existing directory reports concrete ref' ' + test_must_fail git branch foo 2>stderr && + test_grep refs/heads/foo/bar/baz stderr +' + +test_expect_success 'notice d/f conflict with existing ref' ' + test_must_fail git branch foo/bar/baz/extra && + test_must_fail git branch foo/bar/baz/lots/of/extra/components +' + +test_expect_success 'reject packed-refs with unterminated line' ' + cp .git/packed-refs .git/packed-refs.bak && + test_when_finished "mv .git/packed-refs.bak .git/packed-refs" && + printf "%s" "$HEAD refs/zzzzz" >>.git/packed-refs && + echo "fatal: unterminated line in .git/packed-refs: $HEAD refs/zzzzz" >expected_err && + test_must_fail git for-each-ref >out 2>err && + test_cmp expected_err err +' + +test_expect_success 'reject packed-refs containing junk' ' + cp .git/packed-refs .git/packed-refs.bak && + test_when_finished "mv .git/packed-refs.bak .git/packed-refs" && + printf "%s\n" "bogus content" >>.git/packed-refs && + echo "fatal: unexpected line in .git/packed-refs: bogus content" >expected_err && + test_must_fail git for-each-ref >out 2>err && + test_cmp expected_err err +' + +test_expect_success 'reject packed-refs with a short SHA-1' ' + cp .git/packed-refs .git/packed-refs.bak && + test_when_finished "mv .git/packed-refs.bak .git/packed-refs" && + printf "%.7s %s\n" $HEAD refs/zzzzz >>.git/packed-refs && + printf "fatal: unexpected line in .git/packed-refs: %.7s %s\n" $HEAD refs/zzzzz >expected_err && + test_must_fail git for-each-ref >out 2>err && + test_cmp expected_err err +' + +test_expect_success 'timeout if packed-refs.lock exists' ' + LOCK=.git/packed-refs.lock && + >"$LOCK" && + test_when_finished "rm -f $LOCK" && + test_must_fail git ${pack_refs} --all --prune +' + +test_expect_success 'retry acquiring packed-refs.lock' ' + LOCK=.git/packed-refs.lock && + >"$LOCK" && + test_when_finished "wait && rm -f $LOCK" && + { + ( sleep 1 && rm -f $LOCK ) & + } && + git -c core.packedrefstimeout=3000 ${pack_refs} --all --prune +' + +test_expect_success SYMLINKS 'pack symlinked packed-refs' ' + # First make sure that symlinking works when reading: + git update-ref refs/heads/lossy refs/heads/main && + git for-each-ref >all-refs-before && + mv .git/packed-refs .git/my-deviant-packed-refs && + ln -s my-deviant-packed-refs .git/packed-refs && + git for-each-ref >all-refs-linked && + test_cmp all-refs-before all-refs-linked && + git ${pack_refs} --all --prune && + git for-each-ref >all-refs-packed && + test_cmp all-refs-before all-refs-packed && + test -h .git/packed-refs && + test "$(test_readlink .git/packed-refs)" = "my-deviant-packed-refs" +' + +# The 'packed-refs' file is stored directly in .git/. This means it is global +# to the repository, and can only contain refs that are shared across all +# worktrees. +test_expect_success 'refs/worktree must not be packed' ' + test_commit initial && + test_commit wt1 && + test_commit wt2 && + git worktree add wt1 wt1 && + git worktree add wt2 wt2 && + git checkout initial && + git update-ref refs/worktree/foo HEAD && + git -C wt1 update-ref refs/worktree/foo HEAD && + git -C wt2 update-ref refs/worktree/foo HEAD && + git ${pack_refs} --all && + test_path_is_missing .git/refs/tags/wt1 && + test_path_is_file .git/refs/worktree/foo && + test_path_is_file .git/worktrees/wt1/refs/worktree/foo && + test_path_is_file .git/worktrees/wt2/refs/worktree/foo +' + +# we do not want to count on running ${pack_refs} to +# actually pack it, as it is perfectly reasonable to +# skip processing a broken ref +test_expect_success 'create packed-refs file with broken ref' ' + test_tick && git commit --allow-empty -m one && + recoverable=$(git rev-parse HEAD) && + test_tick && git commit --allow-empty -m two && + missing=$(git rev-parse HEAD) && + rm -f .git/refs/heads/main && + cat >.git/packed-refs <<-EOF && + $missing refs/heads/main + $recoverable refs/heads/other + EOF + echo $missing >expect && + git rev-parse refs/heads/main >actual && + test_cmp expect actual +' + +test_expect_success '${pack_refs} does not silently delete broken packed ref' ' + git ${pack_refs} --all --prune && + git rev-parse refs/heads/main >actual && + test_cmp expect actual +' + +test_expect_success '${pack_refs} does not drop broken refs during deletion' ' + git update-ref -d refs/heads/other && + git rev-parse refs/heads/main >actual && + test_cmp expect actual +' + +for command in "git ${pack_refs} --all --auto" "git maintenance run --task=${pack_refs} --auto" +do + test_expect_success "$command does not repack below 16 refs without packed-refs" ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + git config set maintenance.auto false && + git commit --allow-empty --message "initial" && + + # Create 14 additional references, which brings us to + # 15 together with the default branch. + printf "create refs/heads/loose-%d HEAD\n" $(test_seq 14) >stdin && + git update-ref --stdin stdin && + git update-ref --stdin stdin && + git update-ref --stdin stdin && + git update-ref --stdin stdin && + git update-ref --stdin blob-content && + blob_id=$(git hash-object -w -t blob blob-content) && + + # Write an invalid tag into the object database. The tag itself + # is well-formed, but the tagged object is a blob while we + # claim that it is a commit. + cat >tag-content <<-EOF && + object $blob_id + type commit + tag bad-tag + tagger C O Mitter 1112354055 +0200 + + annotated + EOF + tag_id=$(git hash-object -w -t tag tag-content) && + git update-ref refs/tags/bad-tag "$tag_id" && + + # The packed-refs file should not contain the peeled object ID. + # If it did this would cause commands that use the peeled value + # to not notice this corrupted tag. + git pack-refs --all && + test_grep ! "^\^" .git/packed-refs + ) +' diff --git a/t/perf/p6010-merge-base.sh b/t/perf/p6010-merge-base.sh new file mode 100755 index 00000000..08212dd0 --- /dev/null +++ b/t/perf/p6010-merge-base.sh @@ -0,0 +1,105 @@ +#!/bin/sh + +test_description='Test git merge-base' + +. ./perf-lib.sh + +test_perf_fresh_repo + +# +# Creates lots of merges to make history traversal costly. In +# particular it creates 2^($max_level-1)-1 2-way merges on top of +# 2^($max_level-1) root commits. E.g., the commit history looks like +# this for a $max_level of 3: +# +# _1_ +# / \ +# 2 3 +# / \ / \ +# 4 5 6 7 +# +# The numbers are the fast-import marks, which also are the commit +# messages. 1 is the HEAD commit and a merge, 2 and 3 are also merges, +# 4-7 are the root commits. +# +build_history () { + local max_level="$1" && + local level="${2:-1}" && + local mark="${3:-1}" && + if test $level -eq $max_level + then + echo "reset refs/heads/master" && + echo "from $ZERO_OID" && + echo "commit refs/heads/master" && + echo "mark :$mark" && + echo "committer C 1234567890 +0000" && + echo "data < 1234567890 +0000" && + echo "data < 1234567890 +0000" && + echo "data <expect +' + +test_perf 'git merge-base' ' + git merge-base --all one two >actual +' + +test_expect_success 'verify result' ' + test_cmp expect actual +' + +test_perf 'git show-branch' ' + git show-branch one two +' + +test_done diff --git a/t/perf/p8020-last-modified.sh b/t/perf/p8020-last-modified.sh new file mode 100755 index 00000000..cb1f98d3 --- /dev/null +++ b/t/perf/p8020-last-modified.sh @@ -0,0 +1,22 @@ +#!/bin/sh + +test_description='last-modified perf tests' +. ./perf-lib.sh + +test_perf_default_repo + +test_perf 'top-level last-modified' ' + git last-modified HEAD +' + +test_perf 'top-level recursive last-modified' ' + git last-modified -r HEAD +' + +test_perf 'subdir last-modified' ' + git ls-tree -d HEAD >subtrees && + path="$(head -n 1 subtrees | cut -f2)" && + git last-modified -r HEAD -- "$path" +' + +test_done diff --git a/t/show-ref-exists-tests.sh b/t/show-ref-exists-tests.sh new file mode 100644 index 00000000..36e8e9df --- /dev/null +++ b/t/show-ref-exists-tests.sh @@ -0,0 +1,77 @@ +git_show_ref_exists=${git_show_ref_exists:-git show-ref --exists} + +test_expect_success setup ' + test_commit --annotate A && + git checkout -b side && + test_commit --annotate B && + git checkout main && + test_commit C && + git branch B A^0 +' + +test_expect_success '--exists with existing reference' ' + ${git_show_ref_exists} refs/heads/$GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +' + +test_expect_success '--exists with missing reference' ' + test_expect_code 2 ${git_show_ref_exists} refs/heads/does-not-exist +' + +test_expect_success '--exists does not use DWIM' ' + test_expect_code 2 ${git_show_ref_exists} $GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME 2>err && + grep "reference does not exist" err +' + +test_expect_success '--exists with HEAD' ' + ${git_show_ref_exists} HEAD +' + +test_expect_success '--exists with bad reference name' ' + test_when_finished "git update-ref -d refs/heads/bad...name" && + new_oid=$(git rev-parse HEAD) && + test-tool ref-store main update-ref msg refs/heads/bad...name $new_oid $ZERO_OID REF_SKIP_REFNAME_VERIFICATION && + ${git_show_ref_exists} refs/heads/bad...name +' + +test_expect_success '--exists with arbitrary symref' ' + test_when_finished "git symbolic-ref -d refs/symref" && + git symbolic-ref refs/symref refs/heads/$GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME && + ${git_show_ref_exists} refs/symref +' + +test_expect_success '--exists with dangling symref' ' + test_when_finished "git symbolic-ref -d refs/heads/dangling" && + git symbolic-ref refs/heads/dangling refs/heads/does-not-exist && + ${git_show_ref_exists} refs/heads/dangling +' + +test_expect_success '--exists with nonexistent object ID' ' + test-tool ref-store main update-ref msg refs/heads/missing-oid $(test_oid 001) $ZERO_OID REF_SKIP_OID_VERIFICATION && + ${git_show_ref_exists} refs/heads/missing-oid +' + +test_expect_success '--exists with non-commit object' ' + tree_oid=$(git rev-parse HEAD^{tree}) && + test-tool ref-store main update-ref msg refs/heads/tree ${tree_oid} $ZERO_OID REF_SKIP_OID_VERIFICATION && + ${git_show_ref_exists} refs/heads/tree +' + +test_expect_success '--exists with directory fails with generic error' ' + cat >expect <<-EOF && + error: reference does not exist + EOF + test_expect_code 2 ${git_show_ref_exists} refs/heads 2>err && + test_cmp expect err +' + +test_expect_success '--exists with non-existent special ref' ' + test_expect_code 2 ${git_show_ref_exists} FETCH_HEAD +' + +test_expect_success '--exists with existing special ref' ' + test_when_finished "rm .git/FETCH_HEAD" && + git rev-parse HEAD >.git/FETCH_HEAD && + ${git_show_ref_exists} FETCH_HEAD +' + +test_done diff --git a/t/t0450/adoc-missing b/t/t0450/adoc-missing new file mode 100644 index 00000000..1ec9f8dc --- /dev/null +++ b/t/t0450/adoc-missing @@ -0,0 +1,9 @@ +checkout--worker +merge-ours +merge-recursive +merge-recursive-ours +merge-recursive-theirs +merge-subtree +pickaxe +submodule--helper +upload-archive--writer diff --git a/t/t0614-reftable-fsck.sh b/t/t0614-reftable-fsck.sh new file mode 100755 index 00000000..d24b87f9 --- /dev/null +++ b/t/t0614-reftable-fsck.sh @@ -0,0 +1,102 @@ +#!/bin/sh + +test_description='Test reftable backend consistency check' + +GIT_TEST_DEFAULT_REF_FORMAT=reftable +export GIT_TEST_DEFAULT_REF_FORMAT + +. ./test-lib.sh + +test_expect_success "no errors reported on a well formed repository" ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + git commit --allow-empty -m initial && + + for i in $(test_seq 20) + do + git update-ref refs/heads/branch-$i HEAD || return 1 + done && + + # The repository should end up with multiple tables. + test_line_count -gt 1 .git/reftable/tables.list && + + git refs verify 2>err && + test_must_be_empty err + ) +' + +for TABLE_NAME in "foo-bar-e4d12d59.ref" \ + "0x00000000zzzz-0x00000000zzzz-e4d12d59.ref" \ + "0x000000000001-0x000000000002-e4d12d59.abc" \ + "0x000000000001-0x000000000002-e4d12d59.refabc"; do + test_expect_success "table name $TABLE_NAME should be checked" ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + git commit --allow-empty -m initial && + + git refs verify 2>err && + test_must_be_empty err && + + EXISTING_TABLE=$(head -n1 .git/reftable/tables.list) && + mv ".git/reftable/$EXISTING_TABLE" ".git/reftable/$TABLE_NAME" && + sed "s/${EXISTING_TABLE}/${TABLE_NAME}/g" .git/reftable/tables.list > tables.list && + mv tables.list .git/reftable/tables.list && + + git refs verify 2>err && + cat >expect <<-EOF && + warning: ${TABLE_NAME}: badReftableTableName: invalid reftable table name + EOF + test_cmp expect err + ) + ' +done + +test_expect_success 'worktree stacks can be verified' ' + test_when_finished "rm -rf repo worktree" && + git init repo && + test_commit -C repo initial && + git -C repo worktree add ../worktree && + + git -C worktree refs verify 2>err && + test_must_be_empty err && + + REFTABLE_DIR=$(git -C worktree rev-parse --git-dir)/reftable && + EXISTING_TABLE=$(head -n1 "$REFTABLE_DIR/tables.list") && + mv "$REFTABLE_DIR/$EXISTING_TABLE" "$REFTABLE_DIR/broken.ref" && + + for d in repo worktree + do + echo "broken.ref" >"$REFTABLE_DIR/tables.list" && + git -C "$d" refs verify 2>err && + cat >expect <<-EOF && + warning: broken.ref: badReftableTableName: invalid reftable table name + EOF + test_cmp expect err && + + echo garbage >"$REFTABLE_DIR/tables.list" && + test_must_fail git -C "$d" refs verify 2>err && + cat >expect <<-EOF && + error: reftable stack for worktree ${SQ}worktree${SQ} is broken + EOF + test_cmp expect err || return 1 + + done +' + +test_expect_success 'invalid symref gets reported' ' + test_when_finished "rm -rf repo" && + git init repo && + test_commit -C repo initial && + git -C repo symbolic-ref refs/heads/symref garbage && + test_must_fail git -C repo refs verify 2>err && + cat >expect <<-EOF && + error: refs/heads/symref: badReferentName: points to invalid refname ${SQ}garbage${SQ} + EOF + test_cmp expect err +' + +test_done diff --git a/t/t1311-config-optional.sh b/t/t1311-config-optional.sh new file mode 100755 index 00000000..fbbacfc6 --- /dev/null +++ b/t/t1311-config-optional.sh @@ -0,0 +1,38 @@ +#!/bin/sh +# +# Copyright (c) 2025 Google LLC +# + +test_description=':(optional) paths' + +. ./test-lib.sh + +test_expect_success 'var=:(optional)path-exists' ' + test_config a.path ":(optional)path-exists" && + >path-exists && + echo path-exists >expect && + + git config get --path a.path >actual && + test_cmp expect actual +' + +test_expect_success 'missing optional value is ignored' ' + test_config a.path ":(optional)no-such-path" && + # Using --show-scope ensures we skip writing not only the value + # but also any meta-information about the ignored key. + test_must_fail git config get --show-scope --path a.path >actual && + test_line_count = 0 actual +' + +test_expect_success 'missing optional value is ignored in multi-value config' ' + test_when_finished "git config unset --all a.path" && + git config set --append a.path ":(optional)path-exists" && + git config set --append a.path ":(optional)no-such-path" && + >path-exists && + echo path-exists >expect && + + git config --get --path a.path >actual && + test_cmp expect actual +' + +test_done diff --git a/t/t1421-reflog-write.sh b/t/t1421-reflog-write.sh new file mode 100755 index 00000000..603ec3f6 --- /dev/null +++ b/t/t1421-reflog-write.sh @@ -0,0 +1,162 @@ +#!/bin/sh + +test_description='Manually write reflog entries' + +. ./test-lib.sh + +SIGNATURE="C O Mitter 1112911993 -0700" + +test_reflog_matches () { + repo="$1" && + refname="$2" && + cat >actual && + test-tool -C "$repo" ref-store main for-each-reflog-ent "$refname" >expected && + test_cmp expected actual +} + +test_expect_success 'invalid number of arguments' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + for args in "" "1" "1 2" "1 2 3" "1 2 3 4 5" + do + test_must_fail git reflog write $args 2>err && + test_grep "usage: git reflog write" err || return 1 + done + ) +' + +test_expect_success 'invalid refname' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + test_must_fail git reflog write "refs/heads/ invalid" $ZERO_OID $ZERO_OID first 2>err && + test_grep "invalid reference name: " err + ) +' + +test_expect_success 'unqualified refname is rejected' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + test_must_fail git reflog write unqualified $ZERO_OID $ZERO_OID first 2>err && + test_grep "invalid reference name: " err + ) +' + +test_expect_success 'nonexistent object IDs' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + test_must_fail git reflog write refs/heads/something $(test_oid deadbeef) $ZERO_OID old-object-id 2>err && + test_grep "old object .* does not exist" err && + test_must_fail git reflog write refs/heads/something $ZERO_OID $(test_oid deadbeef) new-object-id 2>err && + test_grep "new object .* does not exist" err + ) +' + +test_expect_success 'abbreviated object IDs' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + test_commit initial && + abbreviated_oid=$(git rev-parse HEAD | test_copy_bytes 8) && + test_must_fail git reflog write refs/heads/something $abbreviated_oid $ZERO_OID old-object-id 2>err && + test_grep "invalid old object ID" err && + test_must_fail git reflog write refs/heads/something $ZERO_OID $abbreviated_oid new-object-id 2>err && + test_grep "invalid new object ID" err + ) +' + +test_expect_success 'reflog message gets normalized' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + test_commit initial && + COMMIT_OID=$(git rev-parse HEAD) && + git reflog write HEAD $COMMIT_OID $COMMIT_OID "$(printf "message\nwith\nnewlines")" && + git reflog show -1 --format=%gs HEAD >actual && + echo "message with newlines" >expected && + test_cmp expected actual + ) +' + +test_expect_success 'simple writes' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + test_commit initial && + COMMIT_OID=$(git rev-parse HEAD) && + + git reflog write refs/heads/something $ZERO_OID $COMMIT_OID first && + test_reflog_matches . refs/heads/something <<-EOF && + $ZERO_OID $COMMIT_OID $SIGNATURE first + EOF + + git reflog write refs/heads/something $COMMIT_OID $COMMIT_OID second && + test_reflog_matches . refs/heads/something <<-EOF + $ZERO_OID $COMMIT_OID $SIGNATURE first + $COMMIT_OID $COMMIT_OID $SIGNATURE second + EOF + ) +' + +test_expect_success 'uses user.name and user.email config' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + test_commit initial && + COMMIT_OID=$(git rev-parse HEAD) && + + sane_unset GIT_COMMITTER_NAME && + sane_unset GIT_COMMITTER_EMAIL && + git config --local user.name "Author" && + git config --local user.email "a@uth.or" && + git reflog write refs/heads/something $ZERO_OID $COMMIT_OID first && + test_reflog_matches . refs/heads/something <<-EOF + $ZERO_OID $COMMIT_OID Author $GIT_COMMITTER_DATE first + EOF + ) +' + +test_expect_success 'environment variables take precedence over config' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + test_commit initial && + COMMIT_OID=$(git rev-parse HEAD) && + + git config --local user.name "Author" && + git config --local user.email "a@uth.or" && + git reflog write refs/heads/something $ZERO_OID $COMMIT_OID first && + test_reflog_matches . refs/heads/something <<-EOF + $ZERO_OID $COMMIT_OID $SIGNATURE first + EOF + ) +' + +test_expect_success 'can write to root ref' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + test_commit initial && + COMMIT_OID=$(git rev-parse HEAD) && + + git reflog write ROOT_REF_HEAD $ZERO_OID $COMMIT_OID first && + test_reflog_matches . ROOT_REF_HEAD <<-EOF + $ZERO_OID $COMMIT_OID $SIGNATURE first + EOF + ) +' + +test_done diff --git a/t/t1422-show-ref-exists.sh b/t/t1422-show-ref-exists.sh new file mode 100755 index 00000000..fdca3f16 --- /dev/null +++ b/t/t1422-show-ref-exists.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +test_description='show-ref --exists' +GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main +export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME + +. ./test-lib.sh + +. "$TEST_DIRECTORY"/show-ref-exists-tests.sh diff --git a/t/t1461-refs-list.sh b/t/t1461-refs-list.sh new file mode 100755 index 00000000..36e3d81e --- /dev/null +++ b/t/t1461-refs-list.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +test_description='git refs list tests' + +. ./test-lib.sh + +git_for_each_ref='git refs list' +. "$TEST_DIRECTORY"/for-each-ref-tests.sh diff --git a/t/t1462-refs-exists.sh b/t/t1462-refs-exists.sh new file mode 100755 index 00000000..349453c4 --- /dev/null +++ b/t/t1462-refs-exists.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +test_description='refs exists' +GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main +export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME + +. ./test-lib.sh + +git_show_ref_exists='git refs exists' +. "$TEST_DIRECTORY"/show-ref-exists-tests.sh diff --git a/t/t1463-refs-optimize.sh b/t/t1463-refs-optimize.sh new file mode 100755 index 00000000..9afe3c1e --- /dev/null +++ b/t/t1463-refs-optimize.sh @@ -0,0 +1,19 @@ +#!/bin/sh + +test_description='git refs optimize should not change the branch semantic + +This test runs git refs optimize and git show-ref and checks that the branch +semantic is still the same. +' + +GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main +export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +GIT_TEST_DEFAULT_REF_FORMAT=files +export GIT_TEST_DEFAULT_REF_FORMAT + +. ./test-lib.sh + +pack_refs='refs optimize' +. "$TEST_DIRECTORY"/pack-refs-tests.sh + +test_done diff --git a/t/t1900-repo.sh b/t/t1900-repo.sh new file mode 100755 index 00000000..51d55f11 --- /dev/null +++ b/t/t1900-repo.sh @@ -0,0 +1,134 @@ +#!/bin/sh + +test_description='test git repo-info' + +. ./test-lib.sh + +# git-repo-info keys. It must contain the same keys listed in the const +# repo_info_fields, in lexicographical order. +REPO_INFO_KEYS=' + layout.bare + layout.shallow + object.format + references.format +' + +# Test whether a key-value pair is correctly returned +# +# Usage: test_repo_info