git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[RFC PATCH v5 18/19] Introduce support for the Meson build system

From
Patrick Steinhardt <ps@pks.im>
Date
Nov 11, 2024, 15:31 UTC
Message-ID
<de2239fbfcd365ebd4c10a7e07fa5bc9acb20f8f.1731335939.git.ps@pks.im>
In-Reply-To
<cover.1731335938.git.ps@pks.im>

Introduce support for the Meson build system, a "modern" meta build system that supports many different platforms, including Linux, macOS, Windows and BSDs. Meson supports different backends, including Ninja, Xcode and Microsoft Visual Studio. Several common IDEs provide an integration with it.

The biggest contender compared to Meson is probably CMake as outlined in our "Documentation/technical/build-systems.txt" file. Based on my own personal experience from working with both build systems extensively I strongly favor Meson over CMake. In my opinion, it feels significantly easier to use with a syntax that feels more like a "real" programming language. The second big reason is that Meson supports Rust natively, which may prove to be important given that the project may pick up Rust as another language eventually.

Using Meson is rather straight-forward. An example:
    ```
    # Meson uses out-of-tree builds. You can set up multiple build
    # directories, how you name them is completely up to you.
    $ mkdir build
    $ cd build
    $ meson setup .. -Dprefix=/tmp/git-installation
    # Build the project. This also provides several other targets like
    e.g. `install` or `test`.
    $ ninja
    # Meson has been wired up to support execution of our test suites.
    # Both our unit tests and our integration tests are supported.
    # Running `meson test` without any arguments will execute all tests,
    # but the syntax supports globbing to select only some tests.
    $ meson test 't-*'
    # Execute single test interactively to allow for debugging.
    $ meson test 't0000-*' --interactive --test-args=-ix
    ```

The build instructions have been successfully tested on the following systems, tests are passing:

  - Apple macOS 10.15.
  - FreeBSD 14.1.
  - NixOS 24.11.
  - OpenBSD 7.6.
  - Ubuntu 24.04.
  - Windows 10 with Cygwin.
  - Windows 10 with MinGW64, except for t9700, which is also broken with
    our Makefile.
  - Windows 10 with Visual Studio 2022 toolchain, using the Native Tools
    Command Prompt with `meson setup --vsenv`. Tests pass, except for
    t9700.
  - Windows 10 with Visual Studio 2022 solution, using the Native Tools
    Command Prompt with `meson setup --backend vs2022`. Tests pass,
    except for t9700.
  - Windows 10 with VS Code, using the Meson plug-in.

It is expected that there will still be rough edges in the current version. If this patch lands the expectation is that it will coexist with our other build systems for a while. Like this, distributions can slowly migrate over to Meson and report any findings they have to us such that we can continue to iterate. A potential cutoff date for other build systems may be Git 3.0.

Some notes:
  - The installed distribution is structured somewhat differently than
    how it used to be the case. All of our binaries are installed into
    `$libexec/git-core`, while all binaries part of `$bindir` are now
    symbolic links pointing to the former. This rule is consistent in
    itself and thus easier to reason about.
  - We do not install dashed binaries into `$libexec/git-core` anymore.
    So there won't e.g. be a symlink for git-add(1). These are not
    required by modern Git and there isn't really much of a use case for
    those anymore. By not installing those symlinks we thus start the
    deprecation of this layout.
  - Documentation does not yet exist. Same here, it will follow if the
    project can agree on Meson.
  - We're targeting Meson 1.3.0, which has been released relatively
    recently November 2023. The only feature we use from that version is
    `fs.relative_to()`, which we could replace if necessary. If so, we
    could start to target Meson 1.0.0 and newer, released in December
    2022.
  - The whole build instructions count around 3300 lines, half of which
    is listing all of our code and test files. Our Makefiles are around
    5000 lines, autoconf adds another 1300 lines. CMake in comparison
    has only 1200 linescode, but it avoids listing individual files and
    does not wire up auto-configuration as extensively as the Meson
    instructions do.
  - We bundle a set of subproject wrappers for curl, expat, openssl,
    pcre2 and zlib. This allows developers to build Git without these
    dependencies preinstalled, and Meson will fetch and build them
    automatically. This is especially helpful on Windows.
Helped-by: Eli Schwartz <eschwartz@gentoo.org>
Signed-off-by: Patrick Steinhardt <ps@pks.im>
---
 Documentation/meson.build          |  317 ++++++
 bin-wrappers/meson.build           |   28 +
 contrib/completion/meson.build     |    8 +
 contrib/meson.build                |    1 +
 gitweb/meson.build                 |   63 ++
 meson.build                        | 1614 ++++++++++++++++++++++++++++
 meson_options.txt                  |   73 ++
 perl/FromCPAN/Mail/meson.build     |    7 +
 perl/FromCPAN/meson.build          |    9 +
 perl/Git/LoadCPAN/Mail/meson.build |    7 +
 perl/Git/LoadCPAN/meson.build      |    9 +
 perl/Git/SVN/Memoize/meson.build   |    7 +
 perl/Git/SVN/meson.build           |   20 +
 perl/Git/meson.build               |   18 +
 perl/meson.build                   |   12 +
 po/meson.build                     |   27 +
 subprojects/.gitignore             |    1 +
 subprojects/curl.wrap              |   13 +
 subprojects/expat.wrap             |   13 +
 subprojects/openssl.wrap           |   15 +
 subprojects/pcre2.wrap             |   16 +
 subprojects/zlib.wrap              |   13 +
 t/helper/meson.build               |   91 ++
 t/meson.build                      | 1106 +++++++++++++++++++
 templates/hooks/meson.build        |   24 +
 templates/info/meson.build         |    5 +
 templates/meson.build              |   13 +
 27 files changed, 3530 insertions(+)
 create mode 100644 Documentation/meson.build
 create mode 100644 bin-wrappers/meson.build
 create mode 100644 contrib/completion/meson.build
 create mode 100644 contrib/meson.build
 create mode 100644 gitweb/meson.build
 create mode 100644 meson.build
 create mode 100644 meson_options.txt
 create mode 100644 perl/FromCPAN/Mail/meson.build
 create mode 100644 perl/FromCPAN/meson.build
 create mode 100644 perl/Git/LoadCPAN/Mail/meson.build
 create mode 100644 perl/Git/LoadCPAN/meson.build
 create mode 100644 perl/Git/SVN/Memoize/meson.build
 create mode 100644 perl/Git/SVN/meson.build
 create mode 100644 perl/Git/meson.build
 create mode 100644 perl/meson.build
 create mode 100644 po/meson.build
 create mode 100644 subprojects/.gitignore
 create mode 100644 subprojects/curl.wrap
 create mode 100644 subprojects/expat.wrap
 create mode 100644 subprojects/openssl.wrap
 create mode 100644 subprojects/pcre2.wrap
 create mode 100644 subprojects/zlib.wrap
 create mode 100644 t/helper/meson.build
 create mode 100644 t/meson.build
 create mode 100644 templates/hooks/meson.build
 create mode 100644 templates/info/meson.build
 create mode 100644 templates/meson.build
diff --git a/Documentation/meson.build b/Documentation/meson.build
new file mode 100644
index 00000000000..15ba5004ad4
--- /dev/null
+++ b/Documentation/meson.build
@@ -0,0 +1,317 @@
+manpages = {
+  # Category 1.
+  'git-add.txt' : 1,
+  'git-am.txt' : 1,
+  'git-annotate.txt' : 1,
+  'git-apply.txt' : 1,
+  'git-archimport.txt' : 1,
+  'git-archive.txt' : 1,
+  'git-bisect.txt' : 1,
+  'git-blame.txt' : 1,
+  'git-branch.txt' : 1,
+  'git-bugreport.txt' : 1,
+  'git-bundle.txt' : 1,
+  'git-cat-file.txt' : 1,
+  'git-check-attr.txt' : 1,
+  'git-check-ignore.txt' : 1,
+  'git-check-mailmap.txt' : 1,
+  'git-checkout-index.txt' : 1,
+  'git-checkout.txt' : 1,
+  'git-check-ref-format.txt' : 1,
+  'git-cherry-pick.txt' : 1,
+  'git-cherry.txt' : 1,
+  'git-citool.txt' : 1,
+  'git-clean.txt' : 1,
+  'git-clone.txt' : 1,
+  'git-column.txt' : 1,
+  'git-commit-graph.txt' : 1,
+  'git-commit-tree.txt' : 1,
+  'git-commit.txt' : 1,
+  'git-config.txt' : 1,
+  'git-count-objects.txt' : 1,
+  'git-credential-cache--daemon.txt' : 1,
+  'git-credential-cache.txt' : 1,
+  'git-credential-store.txt' : 1,
+  'git-credential.txt' : 1,
+  'git-cvsexportcommit.txt' : 1,
+  'git-cvsimport.txt' : 1,
+  'git-cvsserver.txt' : 1,
+  'git-daemon.txt' : 1,
+  'git-describe.txt' : 1,
+  'git-diagnose.txt' : 1,
+  'git-diff-files.txt' : 1,
+  'git-diff-index.txt' : 1,
+  'git-difftool.txt' : 1,
+  'git-diff-tree.txt' : 1,
+  'git-diff.txt' : 1,
+  'git-fast-export.txt' : 1,
+  'git-fast-import.txt' : 1,
+  'git-fetch-pack.txt' : 1,
+  'git-fetch.txt' : 1,
+  'git-filter-branch.txt' : 1,
+  'git-fmt-merge-msg.txt' : 1,
+  'git-for-each-ref.txt' : 1,
+  'git-for-each-repo.txt' : 1,
+  'git-format-patch.txt' : 1,
+  'git-fsck-objects.txt' : 1,
+  'git-fsck.txt' : 1,
+  'git-fsmonitor--daemon.txt' : 1,
+  'git-gc.txt' : 1,
+  'git-get-tar-commit-id.txt' : 1,
+  'git-grep.txt' : 1,
+  'git-gui.txt' : 1,
+  'git-hash-object.txt' : 1,
+  'git-help.txt' : 1,
+  'git-hook.txt' : 1,
+  'git-http-backend.txt' : 1,
+  'git-http-fetch.txt' : 1,
+  'git-http-push.txt' : 1,
+  'git-imap-send.txt' : 1,
+  'git-index-pack.txt' : 1,
+  'git-init-db.txt' : 1,
+  'git-init.txt' : 1,
+  'git-instaweb.txt' : 1,
+  'git-interpret-trailers.txt' : 1,
+  'git-log.txt' : 1,
+  'git-ls-files.txt' : 1,
+  'git-ls-remote.txt' : 1,
+  'git-ls-tree.txt' : 1,
+  'git-mailinfo.txt' : 1,
+  'git-mailsplit.txt' : 1,
+  'git-maintenance.txt' : 1,
+  'git-merge-base.txt' : 1,
+  'git-merge-file.txt' : 1,
+  'git-merge-index.txt' : 1,
+  'git-merge-one-file.txt' : 1,
+  'git-mergetool--lib.txt' : 1,
+  'git-mergetool.txt' : 1,
+  'git-merge-tree.txt' : 1,
+  'git-merge.txt' : 1,
+  'git-mktag.txt' : 1,
+  'git-mktree.txt' : 1,
+  'git-multi-pack-index.txt' : 1,
+  'git-mv.txt' : 1,
+  'git-name-rev.txt' : 1,
+  'git-notes.txt' : 1,
+  'git-p4.txt' : 1,
+  'git-pack-objects.txt' : 1,
+  'git-pack-redundant.txt' : 1,
+  'git-pack-refs.txt' : 1,
+  'git-patch-id.txt' : 1,
+  'git-prune-packed.txt' : 1,
+  'git-prune.txt' : 1,
+  'git-pull.txt' : 1,
+  'git-push.txt' : 1,
+  'git-quiltimport.txt' : 1,
+  'git-range-diff.txt' : 1,
+  'git-read-tree.txt' : 1,
+  'git-rebase.txt' : 1,
+  'git-receive-pack.txt' : 1,
+  'git-reflog.txt' : 1,
+  'git-refs.txt' : 1,
+  'git-remote-ext.txt' : 1,
+  'git-remote-fd.txt' : 1,
+  'git-remote.txt' : 1,
+  'git-repack.txt' : 1,
+  'git-replace.txt' : 1,
+  'git-replay.txt' : 1,
+  'git-request-pull.txt' : 1,
+  'git-rerere.txt' : 1,
+  'git-reset.txt' : 1,
+  'git-restore.txt' : 1,
+  'git-revert.txt' : 1,
+  'git-rev-list.txt' : 1,
+  'git-rev-parse.txt' : 1,
+  'git-rm.txt' : 1,
+  'git-send-email.txt' : 1,
+  'git-send-pack.txt' : 1,
+  'git-shell.txt' : 1,
+  'git-sh-i18n--envsubst.txt' : 1,
+  'git-sh-i18n.txt' : 1,
+  'git-shortlog.txt' : 1,
+  'git-show-branch.txt' : 1,
+  'git-show-index.txt' : 1,
+  'git-show-ref.txt' : 1,
+  'git-show.txt' : 1,
+  'git-sh-setup.txt' : 1,
+  'git-sparse-checkout.txt' : 1,
+  'git-stage.txt' : 1,
+  'git-stash.txt' : 1,
+  'git-status.txt' : 1,
+  'git-stripspace.txt' : 1,
+  'git-submodule.txt' : 1,
+  'git-svn.txt' : 1,
+  'git-switch.txt' : 1,
+  'git-symbolic-ref.txt' : 1,
+  'git-tag.txt' : 1,
+  'git-unpack-file.txt' : 1,
+  'git-unpack-objects.txt' : 1,
+  'git-update-index.txt' : 1,
+  'git-update-ref.txt' : 1,
+  'git-update-server-info.txt' : 1,
+  'git-upload-archive.txt' : 1,
+  'git-upload-pack.txt' : 1,
+  'git-var.txt' : 1,
+  'git-verify-commit.txt' : 1,
+  'git-verify-pack.txt' : 1,
+  'git-verify-tag.txt' : 1,
+  'git-version.txt' : 1,
+  'git-web--browse.txt' : 1,
+  'git-whatchanged.txt' : 1,
+  'git-worktree.txt' : 1,
+  'git-write-tree.txt' : 1,
+  'git.txt' : 1,
+  'gitk.txt' : 1,
+  'gitweb.txt' : 1,
+  'scalar.txt' : 1,
+
+  # Category 5.
+  'gitattributes.txt' : 5,
+  'gitformat-bundle.txt' : 5,
+  'gitformat-chunk.txt' : 5,
+  'gitformat-commit-graph.txt' : 5,
+  'gitformat-index.txt' : 5,
+  'gitformat-pack.txt' : 5,
+  'gitformat-signature.txt' : 5,
+  'githooks.txt' : 5,
+  'gitignore.txt' : 5,
+  'gitmailmap.txt' : 5,
+  'gitmodules.txt' : 5,
+  'gitprotocol-capabilities.txt' : 5,
+  'gitprotocol-common.txt' : 5,
+  'gitprotocol-http.txt' : 5,
+  'gitprotocol-pack.txt' : 5,
+  'gitprotocol-v2.txt' : 5,
+  'gitrepository-layout.txt' : 5,
+  'gitweb.conf.txt' : 5,
+
+  # Category 7.
+  'gitcli.txt' : 7,
+  'gitcore-tutorial.txt' : 7,
+  'gitcredentials.txt' : 7,
+  'gitcvs-migration.txt' : 7,
+  'gitdiffcore.txt' : 7,
+  'giteveryday.txt' : 7,
+  'gitfaq.txt' : 7,
+  'gitglossary.txt' : 7,
+  'gitpacking.txt' : 7,
+  'gitnamespaces.txt' : 7,
+  'gitremote-helpers.txt' : 7,
+  'gitrevisions.txt' : 7,
+  'gitsubmodules.txt' : 7,
+  'gittutorial-2.txt' : 7,
+  'gittutorial.txt' : 7,
+  'gitworkflows.txt' : 7,
+}
+
+asciidoc = find_program('asciidoc')
+git = find_program('git', required: false)
+xmlto = find_program('xmlto')
+
+git_revdate = ''
+if git.found()
+  git_revdate = run_command(git, 'show', '--quiet', '--pretty=%as', check: false).stdout().strip()
+endif
+
+asciidoc_common_options = [
+  asciidoc,
+  '--conf-file=' + meson.current_source_dir() / 'asciidoc.conf',
+  '--attribute=manual=Git Manual',
+  '--attribute=mansource=Git ' + git_version,
+  '--attribute=revdate=' + git_revdate,
+  '--attribute=build_dir=' + meson.current_build_dir(),
+]
+
+cmd_lists = [
+    'cmds-ancillaryinterrogators.txt',
+	'cmds-ancillarymanipulators.txt',
+	'cmds-mainporcelain.txt',
+	'cmds-plumbinginterrogators.txt',
+	'cmds-plumbingmanipulators.txt',
+	'cmds-synchingrepositories.txt',
+	'cmds-synchelpers.txt',
+	'cmds-guide.txt',
+	'cmds-developerinterfaces.txt',
+	'cmds-userinterfaces.txt',
+	'cmds-purehelpers.txt',
+	'cmds-foreignscminterface.txt',
+]
+
+documentation_deps = [ ]
+
+documentation_deps += custom_target(
+  command: [
+    perl,
+    meson.current_source_dir() / 'cmd-list.perl',
+    meson.project_source_root(),
+    meson.current_build_dir(),
+  ] + cmd_lists,
+  output: cmd_lists
+)
+
+foreach mode : [ 'diff', 'merge' ]
+  documentation_deps += custom_target(
+    command: [
+      shell,
+      meson.current_source_dir() / 'generate-mergetool-list.sh',
+      '..',
+      'diff',
+      '@OUTPUT@'
+    ],
+    env: [
+      'MERGE_TOOLS_DIR=' + meson.project_source_root() / 'mergetools',
+      'TOOL_MODE=' + mode,
+    ],
+    output: 'mergetools-' + mode + '.txt',
+  )
+endforeach
+
+foreach manpage, category : manpages
+  if get_option('docs').contains('man')
+    manpage_xml_target = custom_target(
+      command: asciidoc_common_options + [
+        '--backend=docbook',
+        '--doctype=manpage',
+        '--out-file=@OUTPUT@',
+        meson.current_source_dir() / manpage,
+      ],
+      depends: documentation_deps,
+      output: fs.stem(manpage) + '.xml',
+    )
+
+    manpage_path = fs.stem(manpage) + '.' + category.to_string()
+    manpage_target = custom_target(
+      command: [
+        xmlto,
+        '-m',
+        meson.current_source_dir() / 'manpage-normal.xsl',
+        '-m',
+        meson.current_source_dir() / 'manpage-bold-literal.xsl',
+        '--stringparam',
+        'man.base.url.for.relative.links=' + get_option('prefix') / get_option('mandir'),
+        'man',
+        manpage_xml_target,
+        '-o',
+        meson.current_build_dir(),
+      ],
+      output: manpage_path,
+      install: true,
+      install_dir: get_option('mandir') / 'man' + category.to_string(),
+    )
+  endif
+
+  if get_option('docs').contains('html') and category == 1
+    custom_target(
+      command: asciidoc_common_options + [
+        '--backend=xhtml11',
+        '--doctype=manpage',
+        '--out-file=@OUTPUT@',
+        meson.current_source_dir() / manpage,
+      ],
+      depends: documentation_deps,
+      output: fs.stem(manpage) + '.html',
+      install: true,
+      install_dir: get_option('datadir') / 'doc/git-doc',
+    )
+  endif
+endforeach
diff --git a/bin-wrappers/meson.build b/bin-wrappers/meson.build
new file mode 100644
index 00000000000..6d03a19d7b8
--- /dev/null
+++ b/bin-wrappers/meson.build
@@ -0,0 +1,28 @@
+bin_wrappers_config = configuration_data()
+foreach key, value : {
+      'BUILD_DIR': meson.project_build_root(),
+      'MERGE_TOOLS_DIR': meson.project_source_root() / 'mergetools',
+      'TEMPLATE_DIR': meson.project_build_root() / 'templates',
+      'GIT_TEXTDOMAINDIR': meson.project_build_root() / 'po',
+      'GITPERLLIB': meson.project_build_root() / 'perl/lib',
+}
+  # Paths need to be Unix-style without drive prefixes as they get added to the
+  # PATH variable. And given that drive prefixes contain a colon we'd otherwise
+  # end up with a broken PATH if we didn't convert them.
+  if cygpath.found()
+    value = run_command(cygpath, value, check: true).stdout().strip()
+  endif
+  bin_wrappers_config.set(key, value)
+endforeach
+
+foreach executable : bin_wrappers
+  executable_config = configuration_data()
+  executable_config.merge_from(bin_wrappers_config)
+  executable_config.set('PROG', fs.relative_to(executable.full_path(), meson.project_build_root()))
+
+  configure_file(
+    input: 'wrap-for-bin.sh',
+    output: fs.stem(executable.full_path()),
+    configuration: executable_config,
+  )
+endforeach
diff --git a/contrib/completion/meson.build b/contrib/completion/meson.build
new file mode 100644
index 00000000000..a9bfe2da312
--- /dev/null
+++ b/contrib/completion/meson.build
@@ -0,0 +1,8 @@
+foreach script : [
+  'git-completion.bash',
+  'git-completion.tcsh',
+  'git-completion.zsh',
+  'git-prompt.sh'
+]
+  test_dependencies += fs.copyfile(script)
+endforeach
diff --git a/contrib/meson.build b/contrib/meson.build
new file mode 100644
index 00000000000..a7b77b87c22
--- /dev/null
+++ b/contrib/meson.build
@@ -0,0 +1 @@
+subdir('completion')
diff --git a/gitweb/meson.build b/gitweb/meson.build
new file mode 100644
index 00000000000..43c28cea453
--- /dev/null
+++ b/gitweb/meson.build
@@ -0,0 +1,63 @@
+gitweb_config = configuration_data()
+gitweb_config.set_quoted('PERL_PATH', perl.full_path())
+gitweb_config.set_quoted('CSSMIN', '')
+gitweb_config.set_quoted('JSMIN', '')
+gitweb_config.set_quoted('GIT_VERSION', git_version)
+gitweb_config.set_quoted('GIT_BINDIR', get_option('prefix') / get_option('bindir'))
+gitweb_config.set_quoted('GITWEB_CONFIG', get_option('gitweb_config'))
+gitweb_config.set_quoted('GITWEB_CONFIG_SYSTEM', get_option('gitweb_config_system'))
+gitweb_config.set_quoted('GITWEB_CONFIG_COMMON', get_option('gitweb_config_common'))
+gitweb_config.set_quoted('GITWEB_HOME_LINK_STR', get_option('gitweb_home_link_str'))
+gitweb_config.set_quoted('GITWEB_SITENAME', get_option('gitweb_sitename'))
+gitweb_config.set_quoted('GITWEB_PROJECTROOT', get_option('gitweb_projectroot'))
+gitweb_config.set_quoted('GITWEB_PROJECT_MAXDEPTH', get_option('gitweb_project_maxdepth'))
+gitweb_config.set_quoted('GITWEB_EXPORT_OK', get_option('gitweb_export_ok'))
+gitweb_config.set_quoted('GITWEB_STRICT_EXPORT', get_option('gitweb_strict_export'))
+gitweb_config.set_quoted('GITWEB_BASE_URL', get_option('gitweb_base_url'))
+gitweb_config.set_quoted('GITWEB_LIST', get_option('gitweb_list'))
+gitweb_config.set_quoted('GITWEB_HOMETEXT', get_option('gitweb_hometext'))
+gitweb_config.set_quoted('GITWEB_CSS', get_option('gitweb_css'))
+gitweb_config.set_quoted('GITWEB_LOGO', get_option('gitweb_logo'))
+gitweb_config.set_quoted('GITWEB_FAVICON', get_option('gitweb_favicon'))
+gitweb_config.set_quoted('GITWEB_JS', get_option('gitweb_js'))
+gitweb_config.set_quoted('GITWEB_SITE_HTML_HEAD_STRING', get_option('gitweb_site_html_head_string'))
+gitweb_config.set_quoted('GITWEB_SITE_HEADER', get_option('gitweb_site_header'))
+gitweb_config.set_quoted('GITWEB_SITE_FOOTER', get_option('gitweb_site_footer'))
+gitweb_config.set_quoted('HIGHLIGHT_BIN', get_option('highlight_bin'))
+
+configure_file(
+  input: 'GITWEB-BUILD-OPTIONS.in',
+  output: 'GITWEB-BUILD-OPTIONS',
+  configuration: gitweb_config,
+)
+
+test_dependencies += custom_target(
+  input: 'gitweb.perl',
+  output: 'gitweb.cgi',
+  command: [
+    shell,
+    meson.current_source_dir() / 'generate-gitweb.sh',
+    meson.current_build_dir() / 'GITWEB-BUILD-OPTIONS',
+    '@INPUT@',
+    '@OUTPUT@',
+  ],
+  install: true,
+  install_dir: get_option('datadir') / 'gitweb',
+)
+
+foreach asset : [
+  'static/git-favicon.png',
+  'static/git-logo.png',
+  'static/gitweb.css',
+  'static/js/adjust-timezone.js',
+  'static/js/blame_incremental.js',
+  'static/js/javascript-detection.js',
+  'static/js/lib/common-lib.js',
+  'static/js/lib/cookies.js',
+  'static/js/lib/datetime.js',
+]
+  fs.copyfile(asset,
+    install: true,
+    install_dir: get_option('datadir') / 'gitweb' / fs.parent(asset),
+  )
+endforeach
diff --git a/meson.build b/meson.build
new file mode 100644
index 00000000000..86d9a5c9f94
--- /dev/null
+++ b/meson.build
@@ -0,0 +1,1614 @@
+project('git', 'c',
+  meson_version: '>=1.3.0',
+  # MSVC does not support GNU99, and C99 does not define __STDC_VERSION__
+  # on MSVC. So we instead fall back to C11 there.
+  default_options: ['c_std=gnu99,c11'],
+  version: 'v2.47.GIT',
+)
+
+fs = import('fs')
+
+program_path = []
+# Git for Windows provides all the tools we need to build Git.
+if host_machine.system() == 'windows'
+  program_path += [ 'C:/Program Files/Git/bin', 'C:/Program Files/Git/usr/bin' ]
+endif
+
+awk = find_program('awk', dirs: program_path)
+cygpath = find_program('cygpath', dirs: program_path, required: false)
+diff = find_program('diff', dirs: program_path)
+shell = find_program('sh', dirs: program_path)
+tar = find_program('tar', dirs: program_path)
+
+script_environment = environment()
+foreach tool : ['cat', 'cut', 'git', 'grep', 'sed', 'sort', 'tr', 'uname']
+  program = find_program(tool, dirs: program_path)
+  script_environment.prepend('PATH', fs.parent(program.full_path()))
+endforeach
+
+git_version = run_command(shell, 'GIT-VERSION-GEN', check: false, env: script_environment).stdout().strip()
+if git_version == ''
+  git_version = meson.project_version()
+endif
+
+compiler = meson.get_compiler('c')
+
+libgit_sources = [
+  'abspath.c',
+  'add-interactive.c',
+  'add-patch.c',
+  'advice.c',
+  'alias.c',
+  'alloc.c',
+  'apply.c',
+  'archive-tar.c',
+  'archive-zip.c',
+  'archive.c',
+  'attr.c',
+  'base85.c',
+  'bisect.c',
+  'blame.c',
+  'blob.c',
+  'bloom.c',
+  'branch.c',
+  'bulk-checkin.c',
+  'bundle-uri.c',
+  'bundle.c',
+  'cache-tree.c',
+  'cbtree.c',
+  'chdir-notify.c',
+  'checkout.c',
+  'chunk-format.c',
+  'color.c',
+  'column.c',
+  'combine-diff.c',
+  'commit-graph.c',
+  'commit-reach.c',
+  'commit.c',
+  'compat/nonblock.c',
+  'compat/obstack.c',
+  'compat/terminal.c',
+  'compat/zlib-uncompress2.c',
+  'config.c',
+  'connect.c',
+  'connected.c',
+  'convert.c',
+  'copy.c',
+  'credential.c',
+  'csum-file.c',
+  'ctype.c',
+  'date.c',
+  'decorate.c',
+  'delta-islands.c',
+  'diagnose.c',
+  'diff-delta.c',
+  'diff-merges.c',
+  'diff-lib.c',
+  'diff-no-index.c',
+  'diff.c',
+  'diffcore-break.c',
+  'diffcore-delta.c',
+  'diffcore-order.c',
+  'diffcore-pickaxe.c',
+  'diffcore-rename.c',
+  'diffcore-rotate.c',
+  'dir-iterator.c',
+  'dir.c',
+  'editor.c',
+  'entry.c',
+  'environment.c',
+  'ewah/bitmap.c',
+  'ewah/ewah_bitmap.c',
+  'ewah/ewah_io.c',
+  'ewah/ewah_rlw.c',
+  'exec-cmd.c',
+  'fetch-negotiator.c',
+  'fetch-pack.c',
+  'fmt-merge-msg.c',
+  'fsck.c',
+  'fsmonitor.c',
+  'fsmonitor-ipc.c',
+  'fsmonitor-settings.c',
+  'gettext.c',
+  'git-zlib.c',
+  'gpg-interface.c',
+  'graph.c',
+  'grep.c',
+  'hash-lookup.c',
+  'hashmap.c',
+  'help.c',
+  'hex.c',
+  'hex-ll.c',
+  'hook.c',
+  'ident.c',
+  'json-writer.c',
+  'kwset.c',
+  'levenshtein.c',
+  'line-log.c',
+  'line-range.c',
+  'linear-assignment.c',
+  'list-objects-filter-options.c',
+  'list-objects-filter.c',
+  'list-objects.c',
+  'lockfile.c',
+  'log-tree.c',
+  'loose.c',
+  'ls-refs.c',
+  'mailinfo.c',
+  'mailmap.c',
+  'match-trees.c',
+  'mem-pool.c',
+  'merge-blobs.c',
+  'merge-ll.c',
+  'merge-ort.c',
+  'merge-ort-wrappers.c',
+  'merge-recursive.c',
+  'merge.c',
+  'midx.c',
+  'midx-write.c',
+  'name-hash.c',
+  'negotiator/default.c',
+  'negotiator/noop.c',
+  'negotiator/skipping.c',
+  'notes-cache.c',
+  'notes-merge.c',
+  'notes-utils.c',
+  'notes.c',
+  'object-file-convert.c',
+  'object-file.c',
+  'object-name.c',
+  'object.c',
+  'oid-array.c',
+  'oidmap.c',
+  'oidset.c',
+  'oidtree.c',
+  'pack-bitmap-write.c',
+  'pack-bitmap.c',
+  'pack-check.c',
+  'pack-mtimes.c',
+  'pack-objects.c',
+  'pack-revindex.c',
+  'pack-write.c',
+  'packfile.c',
+  'pager.c',
+  'parallel-checkout.c',
+  'parse.c',
+  'parse-options-cb.c',
+  'parse-options.c',
+  'patch-delta.c',
+  'patch-ids.c',
+  'path.c',
+  'pathspec.c',
+  'pkt-line.c',
+  'preload-index.c',
+  'pretty.c',
+  'prio-queue.c',
+  'progress.c',
+  'promisor-remote.c',
+  'prompt.c',
+  'protocol.c',
+  'protocol-caps.c',
+  'prune-packed.c',
+  'pseudo-merge.c',
+  'quote.c',
+  'range-diff.c',
+  'reachable.c',
+  'read-cache.c',
+  'rebase-interactive.c',
+  'rebase.c',
+  'ref-filter.c',
+  'reflog-walk.c',
+  'reflog.c',
+  'refs.c',
+  'refs/debug.c',
+  'refs/files-backend.c',
+  'refs/reftable-backend.c',
+  'refs/iterator.c',
+  'refs/packed-backend.c',
+  'refs/ref-cache.c',
+  'refspec.c',
+  'reftable/basics.c',
+  'reftable/error.c',
+  'reftable/block.c',
+  'reftable/blocksource.c',
+  'reftable/iter.c',
+  'reftable/merged.c',
+  'reftable/pq.c',
+  'reftable/reader.c',
+  'reftable/record.c',
+  'reftable/stack.c',
+  'reftable/tree.c',
+  'reftable/writer.c',
+  'remote.c',
+  'replace-object.c',
+  'repo-settings.c',
+  'repository.c',
+  'rerere.c',
+  'reset.c',
+  'resolve-undo.c',
+  'revision.c',
+  'run-command.c',
+  'send-pack.c',
+  'sequencer.c',
+  'serve.c',
+  'server-info.c',
+  'setup.c',
+  'shallow.c',
+  'sideband.c',
+  'sigchain.c',
+  'sparse-index.c',
+  'split-index.c',
+  'stable-qsort.c',
+  'statinfo.c',
+  'strbuf.c',
+  'streaming.c',
+  'string-list.c',
+  'strmap.c',
+  'strvec.c',
+  'sub-process.c',
+  'submodule-config.c',
+  'submodule.c',
+  'symlinks.c',
+  'tag.c',
+  'tempfile.c',
+  'thread-utils.c',
+  'tmp-objdir.c',
+  'trace.c',
+  'trace2.c',
+  'trace2/tr2_cfg.c',
+  'trace2/tr2_cmd_name.c',
+  'trace2/tr2_ctr.c',
+  'trace2/tr2_dst.c',
+  'trace2/tr2_sid.c',
+  'trace2/tr2_sysenv.c',
+  'trace2/tr2_tbuf.c',
+  'trace2/tr2_tgt_event.c',
+  'trace2/tr2_tgt_normal.c',
+  'trace2/tr2_tgt_perf.c',
+  'trace2/tr2_tls.c',
+  'trace2/tr2_tmr.c',
+  'trailer.c',
+  'transport-helper.c',
+  'transport.c',
+  'tree-diff.c',
+  'tree-walk.c',
+  'tree.c',
+  'unpack-trees.c',
+  'upload-pack.c',
+  'url.c',
+  'urlmatch.c',
+  'usage.c',
+  'userdiff.c',
+  'utf8.c',
+  'varint.c',
+  'versioncmp.c',
+  'walker.c',
+  'wildmatch.c',
+  'worktree.c',
+  'wrapper.c',
+  'write-or-die.c',
+  'ws.c',
+  'wt-status.c',
+  'xdiff-interface.c',
+  'xdiff/xdiffi.c',
+  'xdiff/xemit.c',
+  'xdiff/xhistogram.c',
+  'xdiff/xmerge.c',
+  'xdiff/xpatience.c',
+  'xdiff/xprepare.c',
+  'xdiff/xutils.c',
+]
+
+builtin_sources = [
+  'builtin/add.c',
+  'builtin/am.c',
+  'builtin/annotate.c',
+  'builtin/apply.c',
+  'builtin/archive.c',
+  'builtin/bisect.c',
+  'builtin/blame.c',
+  'builtin/branch.c',
+  'builtin/bugreport.c',
+  'builtin/bundle.c',
+  'builtin/cat-file.c',
+  'builtin/check-attr.c',
+  'builtin/check-ignore.c',
+  'builtin/check-mailmap.c',
+  'builtin/check-ref-format.c',
+  'builtin/checkout--worker.c',
+  'builtin/checkout-index.c',
+  'builtin/checkout.c',
+  'builtin/clean.c',
+  'builtin/clone.c',
+  'builtin/column.c',
+  'builtin/commit-graph.c',
+  'builtin/commit-tree.c',
+  'builtin/commit.c',
+  'builtin/config.c',
+  'builtin/count-objects.c',
+  'builtin/credential-cache--daemon.c',
+  'builtin/credential-cache.c',
+  'builtin/credential-store.c',
+  'builtin/credential.c',
+  'builtin/describe.c',
+  'builtin/diagnose.c',
+  'builtin/diff-files.c',
+  'builtin/diff-index.c',
+  'builtin/diff-tree.c',
+  'builtin/diff.c',
+  'builtin/difftool.c',
+  'builtin/fast-export.c',
+  'builtin/fast-import.c',
+  'builtin/fetch-pack.c',
+  'builtin/fetch.c',
+  'builtin/fmt-merge-msg.c',
+  'builtin/for-each-ref.c',
+  'builtin/for-each-repo.c',
+  'builtin/fsck.c',
+  'builtin/fsmonitor--daemon.c',
+  'builtin/gc.c',
+  'builtin/get-tar-commit-id.c',
+  'builtin/grep.c',
+  'builtin/hash-object.c',
+  'builtin/help.c',
+  'builtin/hook.c',
+  'builtin/index-pack.c',
+  'builtin/init-db.c',
+  'builtin/interpret-trailers.c',
+  'builtin/log.c',
+  'builtin/ls-files.c',
+  'builtin/ls-remote.c',
+  'builtin/ls-tree.c',
+  'builtin/mailinfo.c',
+  'builtin/mailsplit.c',
+  'builtin/merge-base.c',
+  'builtin/merge-file.c',
+  'builtin/merge-index.c',
+  'builtin/merge-ours.c',
+  'builtin/merge-recursive.c',
+  'builtin/merge-tree.c',
+  'builtin/merge.c',
+  'builtin/mktag.c',
+  'builtin/mktree.c',
+  'builtin/multi-pack-index.c',
+  'builtin/mv.c',
+  'builtin/name-rev.c',
+  'builtin/notes.c',
+  'builtin/pack-objects.c',
+  'builtin/pack-redundant.c',
+  'builtin/pack-refs.c',
+  'builtin/patch-id.c',
+  'builtin/prune-packed.c',
+  'builtin/prune.c',
+  'builtin/pull.c',
+  'builtin/push.c',
+  'builtin/range-diff.c',
+  'builtin/read-tree.c',
+  'builtin/rebase.c',
+  'builtin/receive-pack.c',
+  'builtin/reflog.c',
+  'builtin/refs.c',
+  'builtin/remote-ext.c',
+  'builtin/remote-fd.c',
+  'builtin/remote.c',
+  'builtin/repack.c',
+  'builtin/replace.c',
+  'builtin/replay.c',
+  'builtin/rerere.c',
+  'builtin/reset.c',
+  'builtin/rev-list.c',
+  'builtin/rev-parse.c',
+  'builtin/revert.c',
+  'builtin/rm.c',
+  'builtin/send-pack.c',
+  'builtin/shortlog.c',
+  'builtin/show-branch.c',
+  'builtin/show-index.c',
+  'builtin/show-ref.c',
+  'builtin/sparse-checkout.c',
+  'builtin/stash.c',
+  'builtin/stripspace.c',
+  'builtin/submodule--helper.c',
+  'builtin/symbolic-ref.c',
+  'builtin/tag.c',
+  'builtin/unpack-file.c',
+  'builtin/unpack-objects.c',
+  'builtin/update-index.c',
+  'builtin/update-ref.c',
+  'builtin/update-server-info.c',
+  'builtin/upload-archive.c',
+  'builtin/upload-pack.c',
+  'builtin/var.c',
+  'builtin/verify-commit.c',
+  'builtin/verify-pack.c',
+  'builtin/verify-tag.c',
+  'builtin/worktree.c',
+  'builtin/write-tree.c',
+]
+
+libgit_sources += custom_target(
+  input: 'command-list.txt',
+  output: 'command-list.h',
+  command: [shell, meson.current_source_dir() + '/generate-cmdlist.sh', meson.current_source_dir(), '@OUTPUT@'],
+  env: script_environment,
+)
+
+libgit_sources += custom_target(
+  output: 'config-list.h',
+  command: [
+    shell,
+    meson.current_source_dir() + '/generate-configlist.sh',
+    meson.current_source_dir(),
+    '@OUTPUT@',
+  ],
+  env: script_environment,
+)
+
+libgit_sources += custom_target(
+  input: 'Documentation/githooks.txt',
+  output: 'hook-list.h',
+  command: [
+    shell,
+    meson.current_source_dir() + '/generate-hooklist.sh',
+    meson.current_source_dir(),
+    '@OUTPUT@',
+  ],
+  env: script_environment,
+)
+
+# This contains the variables for GIT-BUILD-OPTIONS, which we use to propagate
+# build options to our tests.
+build_options_config = configuration_data()
+build_options_config.set('GIT_INTEROP_MAKE_OPTS', '')
+build_options_config.set('GIT_PERF_LARGE_REPO', '')
+build_options_config.set('GIT_PERF_MAKE_COMMAND', '')
+build_options_config.set('GIT_PERF_MAKE_OPTS', '')
+build_options_config.set('GIT_PERF_REPEAT_COUNT', '')
+build_options_config.set('GIT_PERF_REPO', '')
+build_options_config.set('GIT_TEST_CMP_USE_COPIED_CONTEXT', '')
+build_options_config.set('GIT_TEST_INDEX_VERSION', '')
+build_options_config.set('GIT_TEST_OPTS', '')
+build_options_config.set('GIT_TEST_PERL_FATAL_WARNINGS', '')
+build_options_config.set('GIT_TEST_UTF8_LOCALE', '')
+build_options_config.set('SANITIZE_ADDRESS', '')
+build_options_config.set('SANITIZE_LEAK', '')
+build_options_config.set('BROKEN_PATH_FIX', '')
+build_options_config.set_quoted('LOCALEDIR', fs.as_posix(get_option('prefix') / get_option('localedir')))
+build_options_config.set('GITWEBDIR', fs.as_posix(get_option('prefix') / get_option('datadir') / 'gitweb'))
+
+test_output_directory = get_option('test_output_directory')
+if test_output_directory == ''
+  test_output_directory = meson.project_build_root() / 'test-output'
+endif
+
+# These variables are used for building libgit.a.
+libgit_c_args = [
+  '-DBINDIR="' + get_option('bindir') + '"',
+  '-DDEFAULT_EDITOR="' + get_option('default_editor') + '"',
+  '-DDEFAULT_GIT_TEMPLATE_DIR="' + get_option('datadir') / 'git-core/templates' + '"',
+  '-DDEFAULT_HELP_FORMAT="' + get_option('default_help_format') + '"',
+  '-DDEFAULT_PAGER="' + get_option('default_pager') + '"',
+  '-DETC_GITATTRIBUTES="' + get_option('gitattributes') + '"',
+  '-DETC_GITCONFIG="' + get_option('gitconfig') + '"',
+  '-DFALLBACK_RUNTIME_PREFIX="' + get_option('prefix') + '"',
+  '-DGIT_EXEC_PATH="' + get_option('prefix') / get_option('libexecdir') / 'git-core"',
+  '-DGIT_HOST_CPU="' + host_machine.cpu_family() + '"',
+  '-DGIT_HTML_PATH="' + get_option('datadir') / 'doc/git-doc"',
+  '-DGIT_INFO_PATH="' + get_option('infodir') + '"',
+  '-DGIT_LOCALE_PATH="' + get_option('localedir') + '"',
+  '-DGIT_MAN_PATH="' + get_option('mandir') + '"',
+  '-DPAGER_ENV="' + get_option('pager_environment') + '"',
+  '-DSHELL_PATH="' + fs.as_posix(shell.full_path()) + '"',
+]
+libgit_include_directories = [ '.' ]
+libgit_dependencies = [ ]
+
+executable_suffix = ''
+if host_machine.system() == 'cygwin' or host_machine.system() == 'windows'
+  executable_suffix = '.exe'
+  libgit_c_args += '-DSTRIP_EXTENSION="' + executable_suffix + '"'
+endif
+build_options_config.set_quoted('X', executable_suffix)
+
+python = import('python').find_installation('python3', required: get_option('python'))
+if python.found()
+  build_options_config.set('NO_PYTHON', '')
+else
+  libgit_c_args += '-DNO_PYTHON'
+  build_options_config.set('NO_PYTHON', '1')
+endif
+
+# Perl is used for two different things: our test harness and to provide some
+# features. It is optional if you want to neither execute tests nor use any of
+# these optional features.
+perl_required = get_option('perl')
+if get_option('tests')
+  perl_required = true
+endif
+
+# Note that we only set NO_PERL if the Perl features were disabled by the user.
+# It may not be set when we have found Perl, but only use it to run tests.
+perl = find_program('perl', version: '>=5.8.1', dirs: program_path, required: perl_required)
+perl_features_enabled = perl.found() and get_option('perl').allowed()
+if perl_features_enabled
+  build_options_config.set('NO_PERL', '')
+
+  if get_option('runtime_prefix')
+    build_options_config.set('PERL_LOCALEDIR', '')
+  else
+    build_options_config.set_quoted('PERL_LOCALEDIR', fs.as_posix(get_option('prefix') / get_option('localedir')))
+  endif
+
+  if get_option('perl_cpan_fallback')
+    build_options_config.set('NO_PERL_CPAN_FALLBACKS', '')
+  else
+    build_options_config.set_quoted('NO_PERL_CPAN_FALLBACKS', 'YesPlease')
+  endif
+else
+  libgit_c_args += '-DNO_PERL'
+  build_options_config.set('NO_PERL', '1')
+  build_options_config.set('PERL_LOCALEDIR', '')
+  build_options_config.set('NO_PERL_CPAN_FALLBACKS', '')
+endif
+
+zlib = dependency('zlib', default_options: ['default_library=static', 'tests=disabled'])
+if zlib.version().version_compare('<1.2.0')
+  libgit_c_args += '-DNO_DEFLATE_BOUND'
+endif
+libgit_dependencies += zlib
+
+threads = dependency('threads', required: false)
+if threads.found()
+  libgit_dependencies += threads
+  build_options_config.set('NO_PTHREADS', '')
+else
+  libgit_c_args += '-DNO_PTHREADS'
+  build_options_config.set('NO_PTHREADS', '1')
+endif
+
+if get_option('gettext').allowed() and host_machine.system() == 'darwin' and get_option('macos_use_homebrew_gettext')
+  if host_machine.cpu_family() == 'x86_64'
+    libintl_prefix = '/usr/local'
+  elif host_machine.cpu_family() == 'aarch64'
+    libintl_prefix = '/opt/homebrew'
+  else
+    error('Homebrew workaround not supported on current architecture')
+  endif
+
+  intl = compiler.find_library('intl', dirs: libintl_prefix / 'lib', required: get_option('gettext'))
+  if intl.found()
+    intl = declare_dependency(
+      dependencies: intl,
+      include_directories: libintl_prefix / 'include',
+    )
+  endif
+else
+  intl = dependency('intl', required: get_option('gettext'))
+endif
+if intl.found()
+  libgit_dependencies += intl
+  build_options_config.set('NO_GETTEXT', '')
+  build_options_config.set('USE_GETTEXT_SCHEME', '')
+else
+  libgit_c_args += '-DNO_GETTEXT'
+  build_options_config.set('NO_GETTEXT', '1')
+  build_options_config.set('USE_GETTEXT_SCHEME', 'fallthrough')
+endif
+
+iconv = dependency('iconv', required: get_option('iconv'))
+if iconv.found()
+  libgit_dependencies += iconv
+  build_options_config.set('NO_ICONV', '')
+
+  have_old_iconv = false
+  if not compiler.compiles('''
+    #include <iconv.h>
+
+    extern size_t iconv(iconv_t cd,
+                        char **inbuf, size_t *inbytesleft,
+                        char **outbuf, size_t *outbytesleft);
+  ''', name: 'old iconv interface', dependencies: [iconv])
+    libgit_c_args += '-DOLD_ICONV'
+    have_old_iconv = true
+  endif
+
+  iconv_omits_bom_source = '''#
+    #include <iconv.h>
+
+    int main(int argc, const char **argv)
+    {
+  '''
+  if have_old_iconv
+    iconv_omits_bom_source += '''
+      typedef const char *iconv_ibp;
+    '''
+  else
+    iconv_omits_bom_source += '''
+      typedef char *iconv_ibp;
+    '''
+  endif
+  iconv_omits_bom_source += '''
+      int v;
+      iconv_t conv;
+      char in[] = "a"; iconv_ibp pin = in;
+      char out[20] = ""; char *pout = out;
+      size_t isz = sizeof in;
+      size_t osz = sizeof out;
+
+      conv = iconv_open("UTF-16", "UTF-8");
+      iconv(conv, &pin, &isz, &pout, &osz);
+      iconv_close(conv);
+      v = (unsigned char)(out[0]) + (unsigned char)(out[1]);
+      return v != 0xfe + 0xff;
+    }
+  '''
+
+  if compiler.run(iconv_omits_bom_source,
+    dependencies: iconv,
+    name: 'iconv omits BOM',
+  ).returncode() != 0
+    libgit_c_args += '-DICONV_OMITS_BOM'
+  endif
+else
+  libgit_c_args += '-DNO_ICONV'
+  build_options_config.set('NO_ICONV', '1')
+endif
+
+pcre2 = dependency('libpcre2-8', required: get_option('pcre2'), default_options: ['default_library=static', 'test=false'])
+if pcre2.found()
+  libgit_dependencies += pcre2
+  libgit_c_args += '-DUSE_LIBPCRE2'
+  build_options_config.set('USE_LIBPCRE2', '1')
+else
+  build_options_config.set('USE_LIBPCRE2', '')
+endif
+
+curl = dependency('libcurl', version: '>=7.21.3', required: get_option('curl'), default_options: ['default_library=static', 'tests=disabled'])
+use_curl_for_imap_send = false
+if curl.found()
+  if curl.version().version_compare('>=7.34.0')
+    libgit_c_args += '-DUSE_CURL_FOR_IMAP_SEND'
+    use_curl_for_imap_send = true
+  endif
+
+  libgit_dependencies += curl
+  libgit_c_args += '-DCURL_DISABLE_TYPECHECK'
+  build_options_config.set('NO_CURL', '')
+else
+  libgit_c_args += '-DNO_CURL'
+  build_options_config.set('NO_CURL', '1')
+endif
+
+expat = dependency('expat', required: get_option('expat'), default_options: ['default_library=static', 'build_tests=false'])
+if expat.found()
+  libgit_dependencies += expat
+
+  if expat.version().version_compare('<=1.2')
+    libgit_c_args += '-DEXPAT_NEEDS_XMLPARSE_H'
+  endif
+  build_options_config.set('NO_EXPAT', '')
+else
+  libgit_c_args += '-DNO_EXPAT'
+  build_options_config.set('NO_EXPAT', '1')
+endif
+
+if not compiler.has_header('sys/select.h')
+  libgit_c_args += '-DNO_SYS_SELECT_H'
+endif
+
+has_poll_h = compiler.has_header('poll.h')
+if not has_poll_h
+  libgit_c_args += '-DNO_POLL_H'
+endif
+
+has_sys_poll_h = compiler.has_header('sys/poll.h')
+if not has_sys_poll_h
+  libgit_c_args += '-DNO_SYS_POLL_H'
+endif
+
+if not has_poll_h and not has_sys_poll_h
+  libgit_c_args += '-DNO_POLL'
+  libgit_sources += 'compat/poll/poll.c'
+  libgit_include_directories += 'compat/poll'
+endif
+
+if not compiler.has_header('inttypes.h')
+  libgit_c_args += '-DNO_INTTYPES_H'
+endif
+
+if compiler.has_header('libcharset.h')
+  libcharset = compiler.find_library('charset')
+
+  if compiler.has_function('locale_charset',
+    prefix: '#include <libcharset.h>',
+    dependencies: iconv,
+  )
+    libgit_c_args += '-DHAVE_LIBCHARSET_H'
+  elif compiler.has_function('locale_charset',
+    prefix: '#include <libcharset.h>',
+    dependencies: libcharset,
+  )
+    libgit_c_args += '-DHAVE_LIBCHARSET_H'
+  endif
+endif
+
+if compiler.has_header('alloca.h')
+  libgit_c_args += '-DHAVE_ALLOCA_H'
+endif
+
+if compiler.has_header('sys/sysinfo.h')
+  libgit_c_args += '-DHAVE_SYSINFO'
+endif
+
+# Windows has libgen.h and a basename implementation, but we still need our own
+# implementation to threat things like drive prefixes specially.
+if host_machine.system() == 'windows' or not compiler.has_header('libgen.h')
+  libgit_c_args += '-DNO_LIBGEN_H'
+  libgit_sources += 'compat/basename.c'
+endif
+
+if compiler.has_header('paths.h')
+  libgit_c_args += '-DHAVE_PATHS_H'
+endif
+
+if compiler.has_header('strings.h')
+  libgit_c_args += '-DHAVE_STRINGS_H'
+endif
+
+networking_dependencies = [ ]
+if host_machine.system() == 'windows'
+  winsock = compiler.find_library('ws2_32', required: false)
+  if winsock.found()
+    networking_dependencies += winsock
+  endif
+else
+  libresolv = compiler.find_library('resolv', required: false)
+  if libresolv.found()
+    networking_dependencies += libresolv
+  endif
+endif
+libgit_dependencies += networking_dependencies
+
+foreach symbol : ['inet_ntop', 'inet_pton', 'strerror']
+  if not compiler.has_function(symbol, dependencies: networking_dependencies)
+    libgit_c_args += '-DNO_' + symbol.to_upper()
+  endif
+endforeach
+
+has_ipv6 = compiler.has_function('getaddrinfo', dependencies: networking_dependencies)
+if not has_ipv6
+  libgit_c_args += '-DNO_IPV6'
+endif
+
+if not compiler.compiles('''
+  #ifdef _WIN32
+  # include <winsock2.h>
+  #else
+  # include <sys/types.h>
+  # include <sys/socket.h>
+  #endif
+
+  void func(void)
+  {
+    struct sockaddr_storage x;
+  }
+''', name: 'struct sockaddr_storage')
+  if has_ipv6
+    libgit_c_args += '-Dsockaddr_storage=sockaddr_in6'
+  else
+    libgit_c_args += '-Dsockaddr_storage=sockaddr_in'
+  endif
+endif
+
+if compiler.has_function('socket', dependencies: networking_dependencies)
+  libgit_sources += [
+    'unix-socket.c',
+    'unix-stream-server.c',
+  ]
+  build_options_config.set('NO_UNIX_SOCKETS', '')
+else
+  libgit_c_args += '-DNO_UNIX_SOCKETS'
+  build_options_config.set('NO_UNIX_SOCKETS', '1')
+endif
+
+if not compiler.has_function('pread')
+  libgit_c_args += '-DNO_PREAD'
+  libgit_sources += 'compat/pread.c'
+endif
+
+if host_machine.system() == 'darwin'
+  libgit_sources += 'compat/precompose_utf8.c'
+  libgit_c_args += '-DPRECOMPOSE_UNICODE'
+  libgit_c_args += '-DPROTECT_HFS_DEFAULT'
+endif
+
+# Configure general compatibility wrappers.
+if host_machine.system() == 'cygwin'
+  libgit_sources += [
+    'compat/win32/path-utils.c',
+  ]
+elif host_machine.system() == 'windows'
+  libgit_sources += [
+    'compat/mingw.c',
+    'compat/winansi.c',
+    'compat/win32/flush.c',
+    'compat/win32/path-utils.c',
+    'compat/win32/pthread.c',
+    'compat/win32/syslog.c',
+    'compat/win32/dirent.c',
+    'compat/win32mmap.c',
+    'compat/nedmalloc/nedmalloc.c',
+  ]
+
+  libgit_c_args += [
+    '-DDETECT_MSYS_TTY',
+    '-DENSURE_MSYSTEM_IS_SET',
+    '-DNATIVE_CRLF',
+    '-DNOGDI',
+    '-DNO_POSIX_GOODIES',
+    '-DWIN32',
+    '-D_CONSOLE',
+    '-D_CONSOLE_DETECT_MSYS_TTY',
+    '-D__USE_MINGW_ANSI_STDIO=0',
+  ]
+
+  libgit_dependencies += compiler.find_library('ntdll')
+  libgit_include_directories += 'compat/win32'
+  if compiler.get_id() == 'msvc'
+    libgit_include_directories += 'compat/vcbuild/include'
+  endif
+endif
+
+if host_machine.system() == 'linux'
+  libgit_sources += 'compat/linux/procinfo.c'
+elif host_machine.system() == 'windows'
+  libgit_sources += 'compat/win32/trace2_win32_process_info.c'
+else
+  libgit_sources += 'compat/stub/procinfo.c'
+endif
+
+if host_machine.system() == 'cygwin' or host_machine.system() == 'windows'
+  libgit_c_args += [
+    '-DUNRELIABLE_FSTAT',
+    '-DMMAP_PREVENTS_DELETE',
+    '-DOBJECT_CREATION_MODE=1',
+  ]
+endif
+
+# Configure the simple-ipc subsystem required fro the fsmonitor.
+if host_machine.system() == 'windows'
+  libgit_sources += [
+    'compat/simple-ipc/ipc-shared.c',
+    'compat/simple-ipc/ipc-win32.c',
+  ]
+  libgit_c_args += '-DSUPPORTS_SIMPLE_IPC'
+else
+  libgit_sources += [
+    'compat/simple-ipc/ipc-shared.c',
+    'compat/simple-ipc/ipc-unix-socket.c',
+  ]
+  libgit_c_args += '-DSUPPORTS_SIMPLE_IPC'
+endif
+
+fsmonitor_backend = ''
+if host_machine.system() == 'windows'
+  fsmonitor_backend = 'win32'
+elif host_machine.system() == 'darwin'
+  fsmonitor_backend = 'darwin'
+  libgit_dependencies += dependency('CoreServices')
+endif
+if fsmonitor_backend != ''
+  libgit_c_args += '-DHAVE_FSMONITOR_DAEMON_BACKEND'
+  libgit_c_args += '-DHAVE_FSMONITOR_OS_SETTINGS'
+
+  libgit_sources += [
+    'compat/fsmonitor/fsm-health-' + fsmonitor_backend + '.c',
+    'compat/fsmonitor/fsm-ipc-' + fsmonitor_backend + '.c',
+    'compat/fsmonitor/fsm-listen-' + fsmonitor_backend + '.c',
+    'compat/fsmonitor/fsm-path-utils-' + fsmonitor_backend + '.c',
+    'compat/fsmonitor/fsm-settings-' + fsmonitor_backend + '.c',
+  ]
+endif
+build_options_config.set_quoted('FSMONITOR_DAEMON_BACKEND', fsmonitor_backend)
+build_options_config.set_quoted('FSMONITOR_OS_SETTINGS', fsmonitor_backend)
+
+if compiler.has_header('regex.h') and compiler.get_define('REG_STARTEND', prefix: '#include <regex.h>') != ''
+  build_options_config.set('NO_REGEX', '')
+
+  if compiler.get_define('REG_ENHANCED', prefix: '#include <regex.h>') != ''
+    libgit_c_args += '-DUSE_ENHANCED_BASIC_REGULAR_EXPRESSIONS'
+    libgit_sources += 'compat/regcomp_enhanced.c'
+  endif
+else
+  libgit_c_args += [
+    '-DNO_REGEX',
+    '-DGAWK',
+    '-DNO_MBSUPPORT',
+  ]
+  build_options_config.set('NO_REGEX', '1')
+  libgit_sources += 'compat/regex/regex.c'
+  libgit_include_directories += 'compat/regex'
+endif
+
+# setitimer and friends are provided by compat/mingw.c.
+if host_machine.system() != 'windows'
+  if not compiler.compiles('''
+    #include <sys/time.h>
+    void func(void)
+    {
+      struct itimerval value;
+    }
+  ''', name: 'struct itimerval')
+    libgit_c_args += '-DNO_STRUCT_ITIMERVAL'
+    libgit_c_args += '-DNO_SETITIMER'
+  elif not compiler.has_function('setitimer')
+    libgit_c_args += '-DNO_SETITIMER'
+  endif
+endif
+
+if compiler.has_member('struct stat', 'st_mtimespec.tv_nsec', prefix: '#include <sys/stat.h>')
+  libgit_c_args += '-DUSE_ST_TIMESPEC'
+elif not compiler.has_member('struct stat', 'st_mtim.tv_nsec', prefix: '#include <sys/stat.h>')
+  libgit_c_args += '-DNO_NSEC'
+endif
+
+if not compiler.has_member('struct stat', 'st_blocks', prefix: '#include <sys/stat.h>')
+  libgit_c_args += '-DNO_ST_BLOCKS_IN_STRUCT_STAT'
+endif
+
+if not compiler.has_member('struct dirent', 'd_type', prefix: '#include <dirent.h>')
+  libgit_c_args += '-DNO_D_TYPE_IN_DIRENT'
+endif
+
+if not compiler.has_member('struct passwd', 'pw_gecos', prefix: '#include <pwd.h>')
+  libgit_c_args += '-DNO_GECOS_IN_PWENT'
+endif
+
+if compiler.has_function('sync_file_range')
+  libgit_c_args += '-DHAVE_SYNC_FILE_RANGE'
+endif
+
+if not compiler.has_function('strcasestr')
+  libgit_c_args += '-DNO_STRCASESTR'
+  libgit_sources += 'compat/strcasestr.c'
+endif
+
+if not compiler.has_function('memmem')
+  libgit_c_args += '-DNO_MEMMEM'
+  libgit_sources += 'compat/memmem.c'
+endif
+
+if not compiler.has_function('strlcpy')
+  libgit_c_args += '-DNO_STRLCPY'
+  libgit_sources += 'compat/strlcpy.c'
+endif
+
+if not compiler.has_function('strdup')
+  libgit_c_args += '-DOVERRIDE_STRDUP'
+  libgit_sources += 'compat/strdup.c'
+endif
+
+if not compiler.has_function('strtoumax')
+  libgit_c_args += '-DNO_STRTOUMAX'
+  libgit_sources += [
+    'compat/strtoumax.c',
+    'compat/strtoimax.c',
+  ]
+endif
+
+if not compiler.has_function('strtoull')
+  libgit_c_args += '-DNO_STRTOULL'
+endif
+
+if not compiler.has_function('setenv')
+  libgit_c_args += '-DNO_SETENV'
+  libgit_sources += 'compat/setenv.c'
+endif
+
+if not compiler.has_function('qsort')
+  libgit_c_args += '-DINTERNAL_QSORT'
+endif
+libgit_sources += 'compat/qsort_s.c'
+
+# unsetenv is provided by compat/mingw.c.
+if host_machine.system() != 'windows' and not compiler.has_function('unsetenv')
+  libgit_c_args += '-DNO_UNSETENV'
+  libgit_sources += 'compat/unsetenv.c'
+endif
+
+if not compiler.has_function('mkdtemp')
+  libgit_c_args += '-DNO_MKDTEMP'
+  libgit_sources += 'compat/mkdtemp.c'
+endif
+
+if not compiler.has_function('initgroups')
+  libgit_c_args += '-DNO_INITGROUPS'
+endif
+
+if compiler.has_function('getdelim')
+  libgit_c_args += '-DHAVE_GETDELIM'
+endif
+
+if host_machine.system() == 'windows'
+  libgit_c_args += '-DUSE_WIN32_MMAP'
+elif not compiler.has_function('mmap')
+  libgit_c_args += '-DNO_MMAP'
+  libgit_sources += 'compat/mmap.c'
+endif
+
+if compiler.has_function('clock_gettime')
+  libgit_c_args += '-DHAVE_CLOCK_GETTIME'
+endif
+
+if compiler.compiles('''
+  #include <time.h>
+
+  void func(void)
+  {
+    clockid_t id = CLOCK_MONOTONIC;
+  }
+''', name: 'monotonic clock')
+  libgit_c_args += '-DHAVE_CLOCK_MONOTONIC'
+endif
+
+if compiler.compiles('''
+  #include <inttypes.h>
+
+  void func(void)
+  {
+    uintmax_t x = 0;
+  }
+''', name: 'uintmax_t')
+  libgit_c_args += '-DNO_UINTMAX_T'
+endif
+
+has_bsd_sysctl = false
+if compiler.has_header('sys/sysctl.h')
+  if compiler.compiles('''
+    #include <stddef.h>
+    #include <sys/sysctl.h>
+
+    void func(void)
+    {
+      int val, mib[2] = { 0 };
+      size_t len = sizeof(val);
+      sysctl(mib, 2, &val, &len, NULL, 0);
+    }
+  ''', name: 'BSD sysctl')
+    libgit_c_args += '-DHAVE_BSD_SYSCTL'
+    has_bsd_sysctl = true
+  endif
+endif
+
+if compiler.run('''
+  #include <stdio.h>
+
+  int main(int argc, const char **argv)
+  {
+    FILE *f = fopen(".", "r");
+    return f ? 0 : 1;
+  }
+''', name: 'fread reads directories').returncode() == 0
+  libgit_c_args += '-DFREAD_READS_DIRECTORIES'
+  libgit_sources += 'compat/fopen.c'
+endif
+
+if not meson.is_cross_build() and fs.exists('/dev/tty')
+  libgit_c_args += '-DHAVE_DEV_TTY'
+endif
+
+if get_option('openssl').enabled() and get_option('CommonCrypto').enabled()
+  error('Can only use one SSL backend')
+endif
+
+security_framework = dependency('Security', required: get_option('CommonCrypto').disable_auto_if(host_machine.system() != 'darwin'))
+core_foundation_framework = dependency('CoreFoundation', required: security_framework.found())
+if security_framework.found()
+  libgit_dependencies += security_framework
+  libgit_dependencies += core_foundation_framework
+  libgit_c_args += '-DAPPLE_COMMON_CRYPTO'
+endif
+
+# OpenSSL is required when requested via the 'openssl' feature or via one of
+# the SHA1/SHA256 backends.
+openssl_required = get_option('openssl').disable_auto_if(security_framework.found())
+if get_option('sha1_backend') == 'openssl' or get_option('sha256_backend') == 'openssl'
+  openssl_required = true
+endif
+
+openssl = dependency('openssl', required: openssl_required, default_options: ['default_library=static'])
+if openssl.found()
+  libgit_dependencies += openssl
+endif
+
+# We may not want to use OpenSSL for anything but our SHA1/SHA256 backends, so
+# we cannot just set NO_OPENSSL based on whether or not the library was found.
+if not openssl.found() or get_option('openssl').disabled()
+  libgit_c_args += '-DNO_OPENSSL'
+endif
+
+sha1_backend = get_option('sha1_backend')
+if sha1_backend == 'sha1dc'
+  libgit_c_args += '-DSHA1_DC'
+  libgit_c_args += '-DSHA1DC_NO_STANDARD_INCLUDES=1'
+  libgit_c_args += '-DSHA1DC_INIT_SAFE_HASH_DEFAULT=0'
+  libgit_c_args += '-DSHA1DC_CUSTOM_INCLUDE_SHA1_C="git-compat-util.h"'
+  libgit_c_args += '-DSHA1DC_CUSTOM_INCLUDE_UBC_CHECK_C="git-compat-util.h"'
+
+  libgit_sources += [
+    'sha1dc_git.c',
+    'sha1dc/sha1.c',
+    'sha1dc/ubc_check.c',
+  ]
+elif sha1_backend == 'common-crypto'
+  libgit_c_args += '-DCOMMON_DIGEST_FOR_OPENSSL'
+  libgit_c_args += '-DSHA1_APPLE'
+  libgit_c_args += '-DSHA1_MAX_BLOCK_SIZE=1024L*1024L*1024L'
+elif sha1_backend == 'openssl'
+  if not openssl.found()
+    openssl = dependency('openssl', required: true)
+  endif
+
+  libgit_c_args += '-DSHA1_OPENSSL'
+  # Apple CommonCrypto requires chunking
+elif sha1_backend == 'block'
+  libgit_c_args += '-DSHA1_BLK'
+  libgit_sources += 'block-sha1/sha1.c'
+else
+  error('Unhandled SHA1 backend ' + sha1_backend)
+endif
+
+sha256_backend = get_option('sha256_backend')
+if sha256_backend == 'openssl'
+  libgit_c_args += '-DSHA256_OPENSSL'
+elif sha256_backend == 'nettle'
+  nettle = dependency('nettle')
+  libgit_dependencies += nettle
+  libgit_c_args += '-DSHA256_NETTLE'
+elif sha256_backend == 'gcrypt'
+  gcrypt = dependency('gcrypt')
+  libgit_dependencies += gcrypt
+  libgit_c_args += '-DSHA256_GCRYPT'
+elif sha256_backend == 'block'
+  libgit_c_args += '-DSHA256_BLK'
+  libgit_sources += 'sha256/block/sha256.c'
+else
+  error('Unhandled SHA256 backend ' + sha256_backend)
+endif
+
+if compiler.has_header_symbol('stdlib.h', 'arc4random_buf')
+  libgit_c_args += '-DHAVE_ARC4RANDOM'
+elif compiler.has_header_symbol('bsd/stdlib.h', 'arc4random_buf')
+  libgit_c_args += '-DHAVE_ARC4RANDOM_BSD'
+elif compiler.has_function('getrandom', prefix: '#include <sys/random.h>')
+  libgit_c_args += '-DHAVE_GETRANDOM'
+elif compiler.has_function('getentropy', prefix: '#include <unistd.h>')
+  libgit_c_args += '-DHAVE_GETENTROPY'
+elif compiler.has_function('RtlGenRandom', prefix: '#include <windows.h>\n#include <ntsecapi.h>')
+  libgit_c_args += '-DHAVE_RTLGENRANDOM'
+elif openssl.found()
+  libgit_c_args += '-DHAVE_OPENSSL_CSPRNG'
+endif
+
+if get_option('runtime_prefix')
+  libgit_c_args += '-DRUNTIME_PREFIX'
+  build_options_config.set('RUNTIME_PREFIX', '1')
+
+  if compiler.has_header('mach-o/dyld.h')
+    libgit_c_args += '-DHAVE_NS_GET_EXECUTABLE_PATH'
+  endif
+
+  if has_bsd_sysctl and compiler.compiles('''
+    #include <sys/sysctl.h>
+
+    void func(void)
+    {
+      KERN_PROC_PATHNAME; KERN_PROC;
+    }
+  ''', name: 'BSD KERN_PROC_PATHNAME')
+    libgit_c_args += '-DHAVE_NS_GET_EXECUTABLE_PATH'
+  endif
+
+  if host_machine.system() == 'linux'
+    libgit_c_args += '-DPROCFS_EXECUTABLE_PATH="/proc/self/exe' + '"'
+  elif host_machine.system() == 'openbsd'
+    libgit_c_args += '-DPROCFS_EXECUTABLE_PATH="' + '/proc/curproc/file' + '"'
+  elif host_machine.system() == 'netbsd'
+    libgit_c_args += '-DPROCFS_EXECUTABLE_PATH="' + '/proc/curproc/exe' + '"'
+  endif
+
+  if host_machine.system() == 'windows' and compiler.compiles('''
+    #include <stdlib.h>
+
+    void func(void)
+    {
+      _wpgmptr;
+    }
+  ''', name: 'Win32 _wpgmptr')
+    libgit_c_args += '-DHAVE_WPGMPTR'
+  endif
+else
+  build_options_config.set('RUNTIME_PREFIX', '')
+endif
+
+foreach key, value : {
+  'DIFF': diff.full_path(),
+  'GIT_TEST_CMP': diff.full_path() + ' -u',
+  'GIT_TEST_GITPERLLIB': meson.project_build_root() / 'perl',
+  'GIT_TEST_MERGE_TOOLS_DIR': meson.project_source_root() / 'mergetools',
+  'GIT_TEST_POPATH': meson.project_source_root() / 'po',
+  'GIT_TEST_TEMPLATE_DIR': meson.project_build_root() / 'templates',
+  'GIT_TEST_TEXTDOMAINDIR': meson.project_build_root() / 'po',
+  'PAGER_ENV': get_option('pager_environment'),
+  'PERL_PATH': perl.found() ? perl.full_path() : '',
+  'PYTHON_PATH': python.found () ? python.full_path() : '',
+  'SHELL_PATH': shell.full_path(),
+  'TAR': tar.full_path(),
+  'TEST_OUTPUT_DIRECTORY': test_output_directory,
+  'TEST_SHELL_PATH': shell.full_path(),
+}
+  if value != '' and cygpath.found()
+    value = run_command(cygpath, value, check: true).stdout().strip()
+  endif
+  build_options_config.set_quoted(key, value)
+endforeach
+
+configure_file(
+  input: 'GIT-BUILD-OPTIONS.in',
+  output: 'GIT-BUILD-OPTIONS',
+  configuration: build_options_config,
+)
+
+# Build a separate library for "version.c" so that we do not have to rebuild
+# everything when the current Git commit changes. TODO: this only gets set up
+# at configuration time, so we do not notice version changes unless the build
+# instructions get regenerated. We should refactor the source file such that we
+# can substitute tags in the file via `vcs_tag()`.
+libgit_version_library = static_library('git-version',
+  sources: ['version.c'],
+  c_args: libgit_c_args + [
+    '-DGIT_VERSION="' + git_version + '"',
+    '-DGIT_USER_AGENT="' + 'git/' + git_version + '"',
+    '-DGIT_BUILT_FROM_COMMIT="' + run_command('git', 'rev-parse', '-q', '--verify', 'HEAD', check: false).stdout().strip() + '"',
+  ],
+  dependencies: libgit_dependencies,
+  include_directories: libgit_include_directories,
+)
+
+libgit_library = static_library('git',
+  sources: libgit_sources,
+  c_args: libgit_c_args,
+  link_with: libgit_version_library,
+  dependencies: libgit_dependencies,
+  include_directories: libgit_include_directories,
+)
+
+libgit = declare_dependency(
+  compile_args: libgit_c_args,
+  link_with: libgit_library,
+  dependencies: libgit_dependencies,
+  include_directories: libgit_include_directories,
+)
+
+common_main_sources = ['common-main.c']
+common_main_link_args = [ ]
+if host_machine.system() == 'windows'
+  # TODO: wire these up properly.
+  common_main_sources += import('windows').compile_resources('git.rc', args: [
+    '-DMAJOR=1',
+    '-DMINOR=1',
+    '-DMICRO=1',
+    '-DPATCHLEVEL=0',
+    '-DGIT_VERSION=\\\"' + git_version + '.GIT\\\"',
+  ])
+  if compiler.get_argument_syntax() == 'gcc'
+    common_main_link_args += [
+      '-municode',
+      '-Wl,-nxcompat',
+      '-Wl,-dynamicbase',
+      '-Wl,-pic-executable,-e,mainCRTStartup',
+    ]
+  elif compiler.get_argument_syntax() == 'msvc'
+    common_main_link_args += [
+      '/ENTRY:wmainCRTStartup',
+      'invalidcontinue.obj',
+    ]
+  else
+    error('Unsupported compiler ' + compiler.get_id())
+  endif
+endif
+common_main_library = static_library('common-main',
+  sources: common_main_sources,
+  c_args: libgit_c_args,
+  dependencies: libgit_dependencies,
+  include_directories: libgit_include_directories,
+)
+common_main = declare_dependency(
+  link_with: common_main_library,
+  link_args: common_main_link_args,
+)
+
+bin_wrappers = [ ]
+test_dependencies = [ ]
+
+git = executable('git',
+  sources: builtin_sources + 'git.c',
+  dependencies: [libgit, common_main],
+  install: true,
+  install_dir: get_option('libexecdir') / 'git-core',
+)
+bin_wrappers += git
+
+test_dependencies += executable('git-daemon',
+  sources: 'daemon.c',
+  dependencies: [libgit, common_main],
+  install: true,
+  install_dir: get_option('libexecdir') / 'git-core',
+)
+
+test_dependencies += executable('git-sh-i18n--envsubst',
+  sources: 'sh-i18n--envsubst.c',
+  dependencies: [libgit, common_main],
+  install: true,
+  install_dir: get_option('libexecdir') / 'git-core',
+)
+
+bin_wrappers += executable('git-shell',
+  sources: 'shell.c',
+  dependencies: [libgit, common_main],
+  install: true,
+  install_dir: get_option('libexecdir') / 'git-core',
+)
+
+test_dependencies += executable('git-http-backend',
+  sources: 'http-backend.c',
+  dependencies: [libgit, common_main],
+  install: true,
+  install_dir: get_option('libexecdir') / 'git-core',
+)
+
+bin_wrappers += executable('scalar',
+  sources: 'scalar.c',
+  dependencies: [libgit, common_main],
+  install: true,
+  install_dir: get_option('libexecdir') / 'git-core',
+)
+
+if get_option('curl').enabled()
+  curl_sources = [
+    'http.c',
+    'http-walker.c',
+  ]
+
+  git_remote_http = executable('git-remote-http',
+    sources: curl_sources + 'remote-curl.c',
+    dependencies: [libgit, common_main],
+    install: true,
+    install_dir: get_option('libexecdir') / 'git-core',
+  )
+  test_dependencies += git_remote_http
+
+  test_dependencies += executable('git-http-fetch',
+    sources: curl_sources + 'http-fetch.c',
+    dependencies: [libgit, common_main],
+    install: true,
+    install_dir: get_option('libexecdir') / 'git-core',
+  )
+
+  if expat.found()
+    test_dependencies += executable('git-http-push',
+      sources: curl_sources + 'http-push.c',
+      dependencies: [libgit, common_main],
+      install: true,
+      install_dir: get_option('libexecdir') / 'git-core',
+    )
+  endif
+
+  foreach alias : [ 'git-remote-https', 'git-remote-ftp', 'git-remote-ftps' ]
+    test_dependencies += executable(alias,
+      objects: git_remote_http.extract_all_objects(recursive: false),
+      dependencies: [libgit, common_main],
+    )
+
+    install_symlink(alias + executable_suffix,
+      install_dir: get_option('libexecdir') / 'git-core',
+      pointing_to: 'git-remote-http',
+    )
+  endforeach
+endif
+
+imap_send_sources = ['imap-send.c']
+if use_curl_for_imap_send
+  imap_send_sources += curl_sources
+endif
+
+test_dependencies += executable('git-imap-send',
+  sources: imap_send_sources,
+  dependencies: [libgit, common_main],
+  install: true,
+  install_dir: get_option('libexecdir') / 'git-core',
+)
+
+foreach alias : [ 'git-receive-pack', 'git-upload-archive', 'git-upload-pack' ]
+  bin_wrappers += executable(alias,
+    objects: git.extract_all_objects(recursive: false),
+    dependencies: [libgit, common_main],
+  )
+
+  install_symlink(alias + executable_suffix,
+    install_dir: get_option('libexecdir') / 'git-core',
+    pointing_to: 'git-remote-http',
+  )
+endforeach
+
+foreach symlink : [
+  'git',
+  'git-http-backend',
+  'git-receive-pack',
+  'git-shell',
+  'git-upload-archive',
+  'git-upload-pack',
+  'scalar',
+]
+  install_symlink(symlink,
+    install_dir: get_option('bindir'),
+    pointing_to: fs.relative_to(get_option('libexecdir') / 'git-core' / symlink, get_option('bindir')),
+  )
+endforeach
+
+scripts_sh = [
+  'git-difftool--helper.sh',
+  'git-filter-branch.sh',
+  'git-merge-octopus.sh',
+  'git-merge-one-file.sh',
+  'git-merge-resolve.sh',
+  'git-mergetool--lib.sh',
+  'git-mergetool.sh',
+  'git-quiltimport.sh',
+  'git-request-pull.sh',
+  'git-sh-i18n.sh',
+  'git-sh-setup.sh',
+  'git-submodule.sh',
+  'git-web--browse.sh',
+]
+if perl_features_enabled
+  scripts_sh += 'git-instaweb.sh'
+endif
+
+foreach script : scripts_sh
+  test_dependencies += custom_target(
+    input: script,
+    output: fs.stem(script),
+    command: [
+      shell,
+      meson.project_source_root() / 'generate-script.sh',
+      '@INPUT@',
+      '@OUTPUT@',
+      meson.project_build_root() / 'GIT-BUILD-OPTIONS',
+    ],
+    install: true,
+    install_dir: get_option('libexecdir') / 'git-core',
+  )
+endforeach
+
+if perl_features_enabled
+  scripts_perl = [
+    'git-archimport.perl',
+    'git-cvsexportcommit.perl',
+    'git-cvsimport.perl',
+    'git-cvsserver.perl',
+    'git-send-email.perl',
+    'git-svn.perl',
+  ]
+
+  pathsep = ':'
+  if host_machine.system() == 'windows'
+    pathsep = ';'
+  endif
+
+  perl_header_template = 'perl/header_templates/fixed_prefix.template.pl'
+  if get_option('runtime_prefix')
+    perl_header_template = 'perl/header_templates/runtime_prefix.template.pl'
+  endif
+
+  perl_header = configure_file(
+    input: perl_header_template,
+    output: 'GIT-PERL-HEADER',
+    configuration: {
+      'GITEXECDIR_REL': get_option('libexecdir') / 'git-core',
+      'PERLLIBDIR_REL': get_option('datadir') / 'perl5',
+      'LOCALEDIR_REL': get_option('datadir') / 'locale',
+      'INSTLIBDIR': get_option('datadir') / 'perl5',
+      'PATHSEP': pathsep,
+    },
+  )
+
+  generate_perl_command = [
+    shell,
+    meson.project_source_root() / 'generate-perl.sh',
+    meson.project_build_root() / 'GIT-BUILD-OPTIONS',
+    git_version,
+    perl_header,
+    '@INPUT@',
+    '@OUTPUT@',
+  ]
+
+  foreach script : scripts_perl
+    generated_script = custom_target(
+      input: script,
+      output: fs.stem(script),
+      command: generate_perl_command,
+      install: true,
+      install_dir: get_option('datadir') / 'perl5',
+    )
+    test_dependencies += generated_script
+    if script == 'git-cvsserver.perl'
+      bin_wrappers += generated_script
+    endif
+  endforeach
+
+  subdir('perl')
+endif
+
+if python.found()
+  scripts_python = [
+    'git-p4.py'
+  ]
+
+  foreach script : scripts_python
+    fs.copyfile(script, fs.stem(script),
+      install: true,
+      install_dir: get_option('libexecdir') / 'git-core',
+    )
+  endforeach
+endif
+
+mergetools = [
+  'mergetools/araxis',
+  'mergetools/bc',
+  'mergetools/codecompare',
+  'mergetools/deltawalker',
+  'mergetools/diffmerge',
+  'mergetools/diffuse',
+  'mergetools/ecmerge',
+  'mergetools/emerge',
+  'mergetools/examdiff',
+  'mergetools/guiffy',
+  'mergetools/gvimdiff',
+  'mergetools/kdiff3',
+  'mergetools/kompare',
+  'mergetools/meld',
+  'mergetools/nvimdiff',
+  'mergetools/opendiff',
+  'mergetools/p4merge',
+  'mergetools/smerge',
+  'mergetools/tkdiff',
+  'mergetools/tortoisemerge',
+  'mergetools/vimdiff',
+  'mergetools/vscode',
+  'mergetools/winmerge',
+  'mergetools/xxdiff',
+]
+
+foreach mergetool : mergetools
+  install_data(mergetool, install_dir: get_option('libexecdir') / 'git-core' / 'mergetools')
+endforeach
+
+if intl.found()
+  subdir('po')
+endif
+subdir('contrib')
+subdir('gitweb')
+subdir('templates')
+
+# Everything but the bin-wrappers need to come before this target such that we
+# can properly set up test dependencies. The bin-wrappers themselves are set up
+# at configuration time, so these are fine.
+if get_option('tests')
+  subdir('t')
+endif
+
+subdir('bin-wrappers')
+if get_option('docs') != []
+  subdir('Documentation')
+endif
diff --git a/meson_options.txt b/meson_options.txt
new file mode 100644
index 00000000000..9164ed69eaf
--- /dev/null
+++ b/meson_options.txt
@@ -0,0 +1,73 @@
+option('default_pager', type: 'string', value: 'less',
+  description: 'Fall-back pager.')
+option('default_editor', type: 'string', value: 'vi',
+  description: 'Fall-back editor.')
+option('gitconfig', type: 'string', value: '/etc/gitconfig',
+  description: 'Path to the global git configuration file.')
+option('gitattributes', type: 'string', value: '/etc/gitattributes',
+  description: 'Path to the global git attributes file.')
+option('pager_environment', type: 'string', value: 'LESS=FRX LV=-c',
+  description: 'Environment used when spawning the pager')
+option('runtime_prefix', type: 'boolean', value: false,
+  description: 'Resolve ancillary tooling and support files relative to the location of the runtime binary instead of hard-coding them into the binary.')
+
+option('curl', type: 'feature', value: 'enabled',
+  description: 'Build helpers used to access remotes with the HTTP transport.')
+option('expat', type: 'feature', value: 'enabled',
+  description: 'Build helpers used to push to remotes with the HTTP transport.')
+option('gettext', type: 'feature', value: 'auto',
+  description: 'Build translation files.')
+option('iconv', type: 'feature', value: 'auto',
+  description: 'Support reencoding strings with different encodings.')
+option('pcre2', type: 'feature', value: 'enabled',
+  description: 'Support Perl-compatible regular expressions in e.g. git-grep(1).')
+option('perl', type: 'feature', value: 'auto',
+  description: 'Build tools written in Perl.')
+option('perl_cpan_fallback', type: 'boolean', value: true,
+  description: 'Install bundled copies of CPAN modules that serve as a fallback in case the modules are not available on the system.')
+option('python', type: 'feature', value: 'auto',
+  description: 'Build tools written in Python.')
+
+option('openssl', type: 'feature', value: 'auto',
+  description: 'Support access to HTTPS remotes. OpenSSL may still be pulled in if configured as SHA1 or SHA256 backend.')
+option('CommonCrypto', type: 'feature', value: 'auto',
+  description: 'Build tools written in Python.')
+
+option('sha1_backend', type: 'combo', choices: ['openssl', 'block', 'sha1dc', 'common-crypto'], value: 'sha1dc',
+  description: 'The backend used for hashing objects with the SHA1 object format')
+option('sha256_backend', type: 'combo', choices: ['openssl', 'nettle', 'gcrypt', 'block'], value: 'block',
+  description: 'The backend used for hashing objects with the SHA256 object format')
+
+option('macos_use_homebrew_gettext', type: 'boolean', value: true,
+  description: 'Use gettext from Homebrew instead of the slightly-broken system-provided one.')
+
+option('gitweb_config', type: 'string', value: 'gitweb_config.perl')
+option('gitweb_config_system', type: 'string', value: '/etc/gitweb.conf')
+option('gitweb_config_common', type: 'string', value: '/etc/gitweb-common.conf')
+option('gitweb_home_link_str', type: 'string', value: 'projects')
+option('gitweb_sitename', type: 'string', value: '')
+option('gitweb_projectroot', type: 'string', value: '/pub/git')
+option('gitweb_project_maxdepth', type: 'string', value: '2007')
+option('gitweb_export_ok', type: 'string', value: '')
+option('gitweb_strict_export', type: 'string', value: '')
+option('gitweb_base_url', type: 'string', value: '')
+option('gitweb_list', type: 'string', value: '')
+option('gitweb_hometext', type: 'string', value: 'indextext.html')
+option('gitweb_css', type: 'string', value: 'static/gitweb.css')
+option('gitweb_logo', type: 'string', value: 'static/git-logo.png')
+option('gitweb_favicon', type: 'string', value: 'static/git-favicon.png')
+option('gitweb_js', type: 'string', value: 'static/gitweb.js')
+option('gitweb_site_html_head_string', type: 'string', value: '')
+option('gitweb_site_header', type: 'string', value: '')
+option('gitweb_site_footer', type: 'string', value: '')
+option('highlight_bin', type: 'string', value: 'highlight')
+
+option('docs', type: 'array', choices: ['man', 'html'], value: [],
+  description: 'Which documenattion formats to build and install.')
+option('default_help_format', type: 'combo', choices: ['man', 'html'], value: 'man',
+  description: 'Default format used when executing git-help(1).')
+
+option('tests', type: 'boolean', value: true,
+  description: 'Enable building tests. This requires Perl, but is separate from the "perl" option such that you can build tests without Perl features enabled.')
+option('test_output_directory', type: 'string',
+  description: 'Path to the directory used to store test outputs')
diff --git a/perl/FromCPAN/Mail/meson.build b/perl/FromCPAN/Mail/meson.build
new file mode 100644
index 00000000000..129cff161c5
--- /dev/null
+++ b/perl/FromCPAN/Mail/meson.build
@@ -0,0 +1,7 @@
+test_dependencies += custom_target(
+  input: 'Address.pm',
+  output: 'Address.pm',
+  command: generate_perl_command,
+  install: true,
+  install_dir: get_option('datadir') / 'perl5/FromCPAN/Mail',
+)
diff --git a/perl/FromCPAN/meson.build b/perl/FromCPAN/meson.build
new file mode 100644
index 00000000000..4e7ea909df3
--- /dev/null
+++ b/perl/FromCPAN/meson.build
@@ -0,0 +1,9 @@
+test_dependencies += custom_target(
+  input: 'Error.pm',
+  output: 'Error.pm',
+  command: generate_perl_command,
+  install: true,
+  install_dir: get_option('datadir') / 'perl5/FromCPAN',
+)
+
+subdir('Mail')
diff --git a/perl/Git/LoadCPAN/Mail/meson.build b/perl/Git/LoadCPAN/Mail/meson.build
new file mode 100644
index 00000000000..7da5b37adb2
--- /dev/null
+++ b/perl/Git/LoadCPAN/Mail/meson.build
@@ -0,0 +1,7 @@
+test_dependencies += custom_target(
+  input: 'Address.pm',
+  output: 'Address.pm',
+  command: generate_perl_command,
+  install: true,
+  install_dir: get_option('datadir') / 'perl5/Git/LoadCPAN/Mail',
+)
diff --git a/perl/Git/LoadCPAN/meson.build b/perl/Git/LoadCPAN/meson.build
new file mode 100644
index 00000000000..9468c073aeb
--- /dev/null
+++ b/perl/Git/LoadCPAN/meson.build
@@ -0,0 +1,9 @@
+test_dependencies += custom_target(
+  input: 'Error.pm',
+  output: 'Error.pm',
+  command: generate_perl_command,
+  install: true,
+  install_dir: get_option('datadir') / 'perl5/Git/LoadCPAN',
+)
+
+subdir('Mail')
diff --git a/perl/Git/SVN/Memoize/meson.build b/perl/Git/SVN/Memoize/meson.build
new file mode 100644
index 00000000000..515ab3dd926
--- /dev/null
+++ b/perl/Git/SVN/Memoize/meson.build
@@ -0,0 +1,7 @@
+test_dependencies += custom_target(
+  input: 'YAML.pm',
+  output: 'YAML.pm',
+  command: generate_perl_command,
+  install: true,
+  install_dir: get_option('datadir') / 'perl5/Git/SVN',
+)
diff --git a/perl/Git/SVN/meson.build b/perl/Git/SVN/meson.build
new file mode 100644
index 00000000000..8338531041d
--- /dev/null
+++ b/perl/Git/SVN/meson.build
@@ -0,0 +1,20 @@
+foreach source : [
+  'Editor.pm',
+  'Fetcher.pm',
+  'GlobSpec.pm',
+  'Log.pm',
+  'Migration.pm',
+  'Prompt.pm',
+  'Ra.pm',
+  'Utils.pm',
+]
+  test_dependencies += custom_target(
+    input: source,
+    output: source,
+    command: generate_perl_command,
+    install: true,
+    install_dir: get_option('datadir') / 'perl5/Git/SVN',
+  )
+endforeach
+
+subdir('Memoize')
diff --git a/perl/Git/meson.build b/perl/Git/meson.build
new file mode 100644
index 00000000000..259209d7302
--- /dev/null
+++ b/perl/Git/meson.build
@@ -0,0 +1,18 @@
+foreach source : [
+  'I18N.pm',
+  'IndexInfo.pm',
+  'LoadCPAN.pm',
+  'Packet.pm',
+  'SVN.pm',
+]
+  test_dependencies += custom_target(
+    input: source,
+    output: source,
+    command: generate_perl_command,
+    install: true,
+    install_dir: get_option('datadir') / 'perl5/Git',
+  )
+endforeach
+
+subdir('LoadCPAN')
+subdir('SVN')
diff --git a/perl/meson.build b/perl/meson.build
new file mode 100644
index 00000000000..c22d6f8a1a3
--- /dev/null
+++ b/perl/meson.build
@@ -0,0 +1,12 @@
+test_dependencies += custom_target(
+  input: 'Git.pm',
+  output: 'Git.pm',
+  command: generate_perl_command,
+  install: true,
+  install_dir: get_option('datadir') / 'perl5',
+)
+
+subdir('Git')
+if get_option('perl_cpan_fallback')
+  subdir('FromCPAN')
+endif
diff --git a/po/meson.build b/po/meson.build
new file mode 100644
index 00000000000..d7154b6395b
--- /dev/null
+++ b/po/meson.build
@@ -0,0 +1,27 @@
+i18n = import('i18n')
+
+translations = i18n.gettext('git',
+  languages: [
+    'bg',
+    'ca',
+    'de',
+    'el',
+    'es',
+    'fr',
+    'id',
+    'is',
+    'it',
+    'ko',
+    'pl',
+    'pt_PT',
+    'ru',
+    'sv',
+    'tr',
+    'uk',
+    'vi',
+    'zh_CN',
+    'zh_TW',
+  ],
+  install: true,
+)
+test_dependencies += translations[0]
diff --git a/subprojects/.gitignore b/subprojects/.gitignore
new file mode 100644
index 00000000000..63ea916ef5f
--- /dev/null
+++ b/subprojects/.gitignore
@@ -0,0 +1 @@
+/*/
diff --git a/subprojects/curl.wrap b/subprojects/curl.wrap
new file mode 100644
index 00000000000..f7e384b85cf
--- /dev/null
+++ b/subprojects/curl.wrap
@@ -0,0 +1,13 @@
+[wrap-file]
+directory = curl-8.10.1
+source_url = https://github.com/curl/curl/releases/download/curl-8_10_1/curl-8.10.1.tar.xz
+source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/curl_8.10.1-1/curl-8.10.1.tar.xz
+source_filename = curl-8.10.1.tar.xz
+source_hash = 73a4b0e99596a09fa5924a4fb7e4b995a85fda0d18a2c02ab9cf134bebce04ee
+patch_filename = curl_8.10.1-1_patch.zip
+patch_url = https://wrapdb.mesonbuild.com/v2/curl_8.10.1-1/get_patch
+patch_hash = 707c28f35fc9b0e8d68c0c2800712007612f922a31da9637ce706a2159f3ddd8
+wrapdb_version = 8.10.1-1
+
+[provide]
+dependency_names = libcurl
diff --git a/subprojects/expat.wrap b/subprojects/expat.wrap
new file mode 100644
index 00000000000..2e0427dcfd1
--- /dev/null
+++ b/subprojects/expat.wrap
@@ -0,0 +1,13 @@
+[wrap-file]
+directory = expat-2.6.3
+source_url = https://github.com/libexpat/libexpat/releases/download/R_2_6_3/expat-2.6.3.tar.xz
+source_filename = expat-2.6.3.tar.bz2
+source_hash = 274db254a6979bde5aad404763a704956940e465843f2a9bd9ed7af22e2c0efc
+patch_filename = expat_2.6.3-1_patch.zip
+patch_url = https://wrapdb.mesonbuild.com/v2/expat_2.6.3-1/get_patch
+patch_hash = cf017fbe105e31428b2768360bd9be39094df4e948a1e8d1c54b6f7c76460cb1
+source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/expat_2.6.3-1/expat-2.6.3.tar.bz2
+wrapdb_version = 2.6.3-1
+
+[provide]
+expat = expat_dep
diff --git a/subprojects/openssl.wrap b/subprojects/openssl.wrap
new file mode 100644
index 00000000000..873d55106e9
--- /dev/null
+++ b/subprojects/openssl.wrap
@@ -0,0 +1,15 @@
+[wrap-file]
+directory = openssl-3.0.8
+source_url = https://www.openssl.org/source/openssl-3.0.8.tar.gz
+source_filename = openssl-3.0.8.tar.gz
+source_hash = 6c13d2bf38fdf31eac3ce2a347073673f5d63263398f1f69d0df4a41253e4b3e
+patch_filename = openssl_3.0.8-3_patch.zip
+patch_url = https://wrapdb.mesonbuild.com/v2/openssl_3.0.8-3/get_patch
+patch_hash = 300da189e106942347d61a4a4295aa2edbcf06184f8d13b4cee0bed9fb936963
+source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/openssl_3.0.8-3/openssl-3.0.8.tar.gz
+wrapdb_version = 3.0.8-3
+
+[provide]
+libcrypto = libcrypto_dep
+libssl = libssl_dep
+openssl = openssl_dep
diff --git a/subprojects/pcre2.wrap b/subprojects/pcre2.wrap
new file mode 100644
index 00000000000..7e184472543
--- /dev/null
+++ b/subprojects/pcre2.wrap
@@ -0,0 +1,16 @@
+[wrap-file]
+directory = pcre2-10.44
+source_url = https://github.com/PCRE2Project/pcre2/releases/download/pcre2-10.44/pcre2-10.44.tar.bz2
+source_filename = pcre2-10.44.tar.bz2
+source_hash = d34f02e113cf7193a1ebf2770d3ac527088d485d4e047ed10e5d217c6ef5de96
+patch_filename = pcre2_10.44-2_patch.zip
+patch_url = https://wrapdb.mesonbuild.com/v2/pcre2_10.44-2/get_patch
+patch_hash = 4336d422ee9043847e5e10dbbbd01940d4c9e5027f31ccdc33a7898a1ca94009
+source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/pcre2_10.44-2/pcre2-10.44.tar.bz2
+wrapdb_version = 10.44-2
+
+[provide]
+libpcre2-8 = libpcre2_8
+libpcre2-16 = libpcre2_16
+libpcre2-32 = libpcre2_32
+libpcre2-posix = libpcre2_posix
diff --git a/subprojects/zlib.wrap b/subprojects/zlib.wrap
new file mode 100644
index 00000000000..aa14de17740
--- /dev/null
+++ b/subprojects/zlib.wrap
@@ -0,0 +1,13 @@
+[wrap-file]
+directory = zlib-1.3.1
+source_url = http://zlib.net/fossils/zlib-1.3.1.tar.gz
+source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/zlib_1.3.1-1/zlib-1.3.1.tar.gz
+source_filename = zlib-1.3.1.tar.gz
+source_hash = 9a93b2b7dfdac77ceba5a558a580e74667dd6fede4585b91eefb60f03b72df23
+patch_filename = zlib_1.3.1-1_patch.zip
+patch_url = https://wrapdb.mesonbuild.com/v2/zlib_1.3.1-1/get_patch
+patch_hash = e79b98eb24a75392009cec6f99ca5cdca9881ff20bfa174e8b8926d5c7a47095
+wrapdb_version = 1.3.1-1
+
+[provide]
+zlib = zlib_dep
diff --git a/t/helper/meson.build b/t/helper/meson.build
new file mode 100644
index 00000000000..5e83884246e
--- /dev/null
+++ b/t/helper/meson.build
@@ -0,0 +1,91 @@
+test_tool_sources = [
+  '../unit-tests/test-lib.c',
+  'test-advise.c',
+  'test-bitmap.c',
+  'test-bloom.c',
+  'test-bundle-uri.c',
+  'test-cache-tree.c',
+  'test-chmtime.c',
+  'test-config.c',
+  'test-crontab.c',
+  'test-csprng.c',
+  'test-date.c',
+  'test-delete-gpgsig.c',
+  'test-delta.c',
+  'test-dir-iterator.c',
+  'test-drop-caches.c',
+  'test-dump-cache-tree.c',
+  'test-dump-fsmonitor.c',
+  'test-dump-split-index.c',
+  'test-dump-untracked-cache.c',
+  'test-env-helper.c',
+  'test-example-tap.c',
+  'test-find-pack.c',
+  'test-fsmonitor-client.c',
+  'test-genrandom.c',
+  'test-genzeros.c',
+  'test-getcwd.c',
+  'test-hash-speed.c',
+  'test-hash.c',
+  'test-hashmap.c',
+  'test-hexdump.c',
+  'test-json-writer.c',
+  'test-lazy-init-name-hash.c',
+  'test-match-trees.c',
+  'test-mergesort.c',
+  'test-mktemp.c',
+  'test-online-cpus.c',
+  'test-pack-mtimes.c',
+  'test-parse-options.c',
+  'test-parse-pathspec-file.c',
+  'test-partial-clone.c',
+  'test-path-utils.c',
+  'test-pcre2-config.c',
+  'test-pkt-line.c',
+  'test-proc-receive.c',
+  'test-progress.c',
+  'test-reach.c',
+  'test-read-cache.c',
+  'test-read-graph.c',
+  'test-read-midx.c',
+  'test-ref-store.c',
+  'test-reftable.c',
+  'test-regex.c',
+  'test-repository.c',
+  'test-revision-walking.c',
+  'test-rot13-filter.c',
+  'test-run-command.c',
+  'test-scrap-cache-tree.c',
+  'test-serve-v2.c',
+  'test-sha1.c',
+  'test-sha256.c',
+  'test-sigchain.c',
+  'test-simple-ipc.c',
+  'test-string-list.c',
+  'test-submodule-config.c',
+  'test-submodule-nested-repo-config.c',
+  'test-submodule.c',
+  'test-subprocess.c',
+  'test-tool.c',
+  'test-trace2.c',
+  'test-truncate.c',
+  'test-userdiff.c',
+  'test-wildmatch.c',
+  'test-windows-named-pipe.c',
+  'test-write-cache.c',
+  'test-xml-encode.c',
+]
+
+test_tool = executable('test-tool',
+  sources: test_tool_sources,
+  dependencies: [libgit, common_main],
+)
+bin_wrappers += test_tool
+test_dependencies += test_tool
+
+test_fake_ssh = executable('test-fake-ssh',
+  sources: 'test-fake-ssh.c',
+  dependencies: [libgit, common_main],
+)
+bin_wrappers += test_fake_ssh
+test_dependencies += test_fake_ssh
diff --git a/t/meson.build b/t/meson.build
new file mode 100644
index 00000000000..9ec0b7fa34a
--- /dev/null
+++ b/t/meson.build
@@ -0,0 +1,1106 @@
+clar_test_suites = [
+  'unit-tests/ctype.c',
+  'unit-tests/strvec.c',
+]
+
+clar_sources = [
+  'unit-tests/clar/clar.c',
+  'unit-tests/unit-test.c',
+]
+
+clar_decls_h = custom_target(
+  input: clar_test_suites,
+  output: 'clar-decls.h',
+  command : [shell, meson.current_source_dir() + '/unit-tests/generate-clar-decls.sh', '@OUTPUT@', '@INPUT@'],
+  env: script_environment,
+)
+clar_sources += clar_decls_h
+
+clar_sources += custom_target(
+  input: clar_decls_h,
+  output: 'clar.suite',
+  feed: true,
+  capture: true,
+  command : [awk, '-f', meson.current_source_dir() + '/unit-tests/clar-generate.awk'],
+)
+
+clar_unit_tests = executable('unit-tests',
+  sources: clar_sources + clar_test_suites,
+  dependencies: [libgit, common_main],
+)
+test('unit-tests', clar_unit_tests)
+
+unit_test_programs = [
+  'unit-tests/t-example-decorate.c',
+  'unit-tests/t-hash.c',
+  'unit-tests/t-hashmap.c',
+  'unit-tests/t-mem-pool.c',
+  'unit-tests/t-oid-array.c',
+  'unit-tests/t-oidmap.c',
+  'unit-tests/t-oidtree.c',
+  'unit-tests/t-prio-queue.c',
+  'unit-tests/t-reftable-basics.c',
+  'unit-tests/t-reftable-block.c',
+  'unit-tests/t-reftable-merged.c',
+  'unit-tests/t-reftable-pq.c',
+  'unit-tests/t-reftable-reader.c',
+  'unit-tests/t-reftable-readwrite.c',
+  'unit-tests/t-reftable-record.c',
+  'unit-tests/t-reftable-stack.c',
+  'unit-tests/t-reftable-tree.c',
+  'unit-tests/t-strbuf.c',
+  'unit-tests/t-strcmp-offset.c',
+  'unit-tests/t-trailer.c',
+  'unit-tests/t-urlmatch-normalization.c',
+]
+
+foreach unit_test_program : unit_test_programs
+  unit_test_name = fs.stem(unit_test_program)
+  unit_test = executable(unit_test_name,
+    sources: [
+      'unit-tests/test-lib.c',
+      'unit-tests/lib-oid.c',
+      'unit-tests/lib-reftable.c',
+      unit_test_program,
+    ],
+    dependencies: [libgit, common_main],
+  )
+  test(unit_test_name, unit_test,
+    workdir: meson.current_source_dir(),
+    timeout: 0,
+  )
+endforeach
+
+subdir('helper')
+
+integration_tests = [
+  't0000-basic.sh',
+  't0001-init.sh',
+  't0002-gitfile.sh',
+  't0003-attributes.sh',
+  't0004-unwritable.sh',
+  't0005-signals.sh',
+  't0006-date.sh',
+  't0007-git-var.sh',
+  't0008-ignores.sh',
+  't0010-racy-git.sh',
+  't0012-help.sh',
+  't0013-sha1dc.sh',
+  't0014-alias.sh',
+  't0017-env-helper.sh',
+  't0018-advice.sh',
+  't0019-json-writer.sh',
+  't0020-crlf.sh',
+  't0021-conversion.sh',
+  't0022-crlf-rename.sh',
+  't0023-crlf-am.sh',
+  't0024-crlf-archive.sh',
+  't0025-crlf-renormalize.sh',
+  't0026-eol-config.sh',
+  't0027-auto-crlf.sh',
+  't0028-working-tree-encoding.sh',
+  't0029-core-unsetenvvars.sh',
+  't0030-stripspace.sh',
+  't0033-safe-directory.sh',
+  't0034-root-safe-directory.sh',
+  't0035-safe-bare-repository.sh',
+  't0040-parse-options.sh',
+  't0041-usage.sh',
+  't0050-filesystem.sh',
+  't0051-windows-named-pipe.sh',
+  't0052-simple-ipc.sh',
+  't0055-beyond-symlinks.sh',
+  't0056-git-C.sh',
+  't0060-path-utils.sh',
+  't0061-run-command.sh',
+  't0062-revision-walking.sh',
+  't0063-string-list.sh',
+  't0066-dir-iterator.sh',
+  't0067-parse_pathspec_file.sh',
+  't0068-for-each-repo.sh',
+  't0070-fundamental.sh',
+  't0071-sort.sh',
+  't0080-unit-test-output.sh',
+  't0081-find-pack.sh',
+  't0090-cache-tree.sh',
+  't0091-bugreport.sh',
+  't0092-diagnose.sh',
+  't0095-bloom.sh',
+  't0100-previous.sh',
+  't0101-at-syntax.sh',
+  't0200-gettext-basic.sh',
+  't0201-gettext-fallbacks.sh',
+  't0202-gettext-perl.sh',
+  't0203-gettext-setlocale-sanity.sh',
+  't0204-gettext-reencode-sanity.sh',
+  't0210-trace2-normal.sh',
+  't0211-trace2-perf.sh',
+  't0212-trace2-event.sh',
+  't0300-credentials.sh',
+  't0301-credential-cache.sh',
+  't0302-credential-store.sh',
+  't0303-credential-external.sh',
+  't0410-partial-clone.sh',
+  't0411-clone-from-partial.sh',
+  't0450-txt-doc-vs-help.sh',
+  't0500-progress-display.sh',
+  't0600-reffiles-backend.sh',
+  't0601-reffiles-pack-refs.sh',
+  't0602-reffiles-fsck.sh',
+  't0610-reftable-basics.sh',
+  't0611-reftable-httpd.sh',
+  't0612-reftable-jgit-compatibility.sh',
+  't0613-reftable-write-options.sh',
+  't1000-read-tree-m-3way.sh',
+  't1001-read-tree-m-2way.sh',
+  't1002-read-tree-m-u-2way.sh',
+  't1003-read-tree-prefix.sh',
+  't1004-read-tree-m-u-wf.sh',
+  't1005-read-tree-reset.sh',
+  't1006-cat-file.sh',
+  't1007-hash-object.sh',
+  't1008-read-tree-overlay.sh',
+  't1009-read-tree-new-index.sh',
+  't1010-mktree.sh',
+  't1011-read-tree-sparse-checkout.sh',
+  't1012-read-tree-df.sh',
+  't1013-read-tree-submodule.sh',
+  't1014-read-tree-confusing.sh',
+  't1015-read-index-unmerged.sh',
+  't1016-compatObjectFormat.sh',
+  't1020-subdirectory.sh',
+  't1021-rerere-in-workdir.sh',
+  't1022-read-tree-partial-clone.sh',
+  't1050-large.sh',
+  't1051-large-conversion.sh',
+  't1060-object-corruption.sh',
+  't1090-sparse-checkout-scope.sh',
+  't1091-sparse-checkout-builtin.sh',
+  't1092-sparse-checkout-compatibility.sh',
+  't1100-commit-tree-options.sh',
+  't1300-config.sh',
+  't1301-shared-repo.sh',
+  't1302-repo-version.sh',
+  't1303-wacky-config.sh',
+  't1304-default-acl.sh',
+  't1305-config-include.sh',
+  't1306-xdg-files.sh',
+  't1307-config-blob.sh',
+  't1308-config-set.sh',
+  't1309-early-config.sh',
+  't1310-config-default.sh',
+  't1350-config-hooks-path.sh',
+  't1400-update-ref.sh',
+  't1401-symbolic-ref.sh',
+  't1402-check-ref-format.sh',
+  't1403-show-ref.sh',
+  't1404-update-ref-errors.sh',
+  't1405-main-ref-store.sh',
+  't1406-submodule-ref-store.sh',
+  't1407-worktree-ref-store.sh',
+  't1408-packed-refs.sh',
+  't1409-avoid-packing-refs.sh',
+  't1410-reflog.sh',
+  't1411-reflog-show.sh',
+  't1412-reflog-loop.sh',
+  't1413-reflog-detach.sh',
+  't1414-reflog-walk.sh',
+  't1415-worktree-refs.sh',
+  't1416-ref-transaction-hooks.sh',
+  't1417-reflog-updateref.sh',
+  't1418-reflog-exists.sh',
+  't1419-exclude-refs.sh',
+  't1420-lost-found.sh',
+  't1430-bad-ref-name.sh',
+  't1450-fsck.sh',
+  't1451-fsck-buffer.sh',
+  't1460-refs-migrate.sh',
+  't1500-rev-parse.sh',
+  't1501-work-tree.sh',
+  't1502-rev-parse-parseopt.sh',
+  't1503-rev-parse-verify.sh',
+  't1504-ceiling-dirs.sh',
+  't1505-rev-parse-last.sh',
+  't1506-rev-parse-diagnosis.sh',
+  't1507-rev-parse-upstream.sh',
+  't1508-at-combinations.sh',
+  't1509-root-work-tree.sh',
+  't1510-repo-setup.sh',
+  't1511-rev-parse-caret.sh',
+  't1512-rev-parse-disambiguation.sh',
+  't1513-rev-parse-prefix.sh',
+  't1514-rev-parse-push.sh',
+  't1515-rev-parse-outside-repo.sh',
+  't1517-outside-repo.sh',
+  't1600-index.sh',
+  't1601-index-bogus.sh',
+  't1700-split-index.sh',
+  't1701-racy-split-index.sh',
+  't1800-hook.sh',
+  't2000-conflict-when-checking-files-out.sh',
+  't2002-checkout-cache-u.sh',
+  't2003-checkout-cache-mkdir.sh',
+  't2004-checkout-cache-temp.sh',
+  't2005-checkout-index-symlinks.sh',
+  't2006-checkout-index-basic.sh',
+  't2007-checkout-symlink.sh',
+  't2008-checkout-subdir.sh',
+  't2009-checkout-statinfo.sh',
+  't2010-checkout-ambiguous.sh',
+  't2011-checkout-invalid-head.sh',
+  't2012-checkout-last.sh',
+  't2013-checkout-submodule.sh',
+  't2014-checkout-switch.sh',
+  't2015-checkout-unborn.sh',
+  't2016-checkout-patch.sh',
+  't2017-checkout-orphan.sh',
+  't2018-checkout-branch.sh',
+  't2019-checkout-ambiguous-ref.sh',
+  't2020-checkout-detach.sh',
+  't2021-checkout-overwrite.sh',
+  't2022-checkout-paths.sh',
+  't2023-checkout-m.sh',
+  't2024-checkout-dwim.sh',
+  't2025-checkout-no-overlay.sh',
+  't2026-checkout-pathspec-file.sh',
+  't2027-checkout-track.sh',
+  't2030-unresolve-info.sh',
+  't2050-git-dir-relative.sh',
+  't2060-switch.sh',
+  't2070-restore.sh',
+  't2071-restore-patch.sh',
+  't2072-restore-pathspec-file.sh',
+  't2080-parallel-checkout-basics.sh',
+  't2081-parallel-checkout-collisions.sh',
+  't2082-parallel-checkout-attributes.sh',
+  't2100-update-cache-badpath.sh',
+  't2101-update-index-reupdate.sh',
+  't2102-update-index-symlinks.sh',
+  't2103-update-index-ignore-missing.sh',
+  't2104-update-index-skip-worktree.sh',
+  't2105-update-index-gitfile.sh',
+  't2106-update-index-assume-unchanged.sh',
+  't2107-update-index-basic.sh',
+  't2108-update-index-refresh-racy.sh',
+  't2200-add-update.sh',
+  't2201-add-update-typechange.sh',
+  't2202-add-addremove.sh',
+  't2203-add-intent.sh',
+  't2204-add-ignored.sh',
+  't2205-add-worktree-config.sh',
+  't2300-cd-to-toplevel.sh',
+  't2400-worktree-add.sh',
+  't2401-worktree-prune.sh',
+  't2402-worktree-list.sh',
+  't2403-worktree-move.sh',
+  't2404-worktree-config.sh',
+  't2405-worktree-submodule.sh',
+  't2406-worktree-repair.sh',
+  't2407-worktree-heads.sh',
+  't2408-worktree-relative.sh',
+  't2500-untracked-overwriting.sh',
+  't2501-cwd-empty.sh',
+  't3000-ls-files-others.sh',
+  't3001-ls-files-others-exclude.sh',
+  't3002-ls-files-dashpath.sh',
+  't3003-ls-files-exclude.sh',
+  't3004-ls-files-basic.sh',
+  't3005-ls-files-relative.sh',
+  't3006-ls-files-long.sh',
+  't3007-ls-files-recurse-submodules.sh',
+  't3008-ls-files-lazy-init-name-hash.sh',
+  't3009-ls-files-others-nonsubmodule.sh',
+  't3010-ls-files-killed-modified.sh',
+  't3011-common-prefixes-and-directory-traversal.sh',
+  't3012-ls-files-dedup.sh',
+  't3013-ls-files-format.sh',
+  't3020-ls-files-error-unmatch.sh',
+  't3040-subprojects-basic.sh',
+  't3050-subprojects-fetch.sh',
+  't3060-ls-files-with-tree.sh',
+  't3070-wildmatch.sh',
+  't3100-ls-tree-restrict.sh',
+  't3101-ls-tree-dirname.sh',
+  't3102-ls-tree-wildcards.sh',
+  't3103-ls-tree-misc.sh',
+  't3104-ls-tree-format.sh',
+  't3105-ls-tree-output.sh',
+  't3200-branch.sh',
+  't3201-branch-contains.sh',
+  't3202-show-branch.sh',
+  't3203-branch-output.sh',
+  't3204-branch-name-interpretation.sh',
+  't3205-branch-color.sh',
+  't3206-range-diff.sh',
+  't3207-branch-submodule.sh',
+  't3211-peel-ref.sh',
+  't3300-funny-names.sh',
+  't3301-notes.sh',
+  't3302-notes-index-expensive.sh',
+  't3303-notes-subtrees.sh',
+  't3304-notes-mixed.sh',
+  't3305-notes-fanout.sh',
+  't3306-notes-prune.sh',
+  't3307-notes-man.sh',
+  't3308-notes-merge.sh',
+  't3309-notes-merge-auto-resolve.sh',
+  't3310-notes-merge-manual-resolve.sh',
+  't3311-notes-merge-fanout.sh',
+  't3320-notes-merge-worktrees.sh',
+  't3321-notes-stripspace.sh',
+  't3400-rebase.sh',
+  't3401-rebase-and-am-rename.sh',
+  't3402-rebase-merge.sh',
+  't3403-rebase-skip.sh',
+  't3404-rebase-interactive.sh',
+  't3405-rebase-malformed.sh',
+  't3406-rebase-message.sh',
+  't3407-rebase-abort.sh',
+  't3408-rebase-multi-line.sh',
+  't3409-rebase-environ.sh',
+  't3412-rebase-root.sh',
+  't3413-rebase-hook.sh',
+  't3415-rebase-autosquash.sh',
+  't3416-rebase-onto-threedots.sh',
+  't3417-rebase-whitespace-fix.sh',
+  't3418-rebase-continue.sh',
+  't3419-rebase-patch-id.sh',
+  't3420-rebase-autostash.sh',
+  't3421-rebase-topology-linear.sh',
+  't3422-rebase-incompatible-options.sh',
+  't3423-rebase-reword.sh',
+  't3424-rebase-empty.sh',
+  't3425-rebase-topology-merges.sh',
+  't3426-rebase-submodule.sh',
+  't3427-rebase-subtree.sh',
+  't3428-rebase-signoff.sh',
+  't3429-rebase-edit-todo.sh',
+  't3430-rebase-merges.sh',
+  't3431-rebase-fork-point.sh',
+  't3432-rebase-fast-forward.sh',
+  't3433-rebase-across-mode-change.sh',
+  't3434-rebase-i18n.sh',
+  't3435-rebase-gpg-sign.sh',
+  't3436-rebase-more-options.sh',
+  't3437-rebase-fixup-options.sh',
+  't3438-rebase-broken-files.sh',
+  't3500-cherry.sh',
+  't3501-revert-cherry-pick.sh',
+  't3502-cherry-pick-merge.sh',
+  't3503-cherry-pick-root.sh',
+  't3504-cherry-pick-rerere.sh',
+  't3505-cherry-pick-empty.sh',
+  't3506-cherry-pick-ff.sh',
+  't3507-cherry-pick-conflict.sh',
+  't3508-cherry-pick-many-commits.sh',
+  't3509-cherry-pick-merge-df.sh',
+  't3510-cherry-pick-sequence.sh',
+  't3511-cherry-pick-x.sh',
+  't3512-cherry-pick-submodule.sh',
+  't3513-revert-submodule.sh',
+  't3514-cherry-pick-revert-gpg.sh',
+  't3600-rm.sh',
+  't3601-rm-pathspec-file.sh',
+  't3602-rm-sparse-checkout.sh',
+  't3650-replay-basics.sh',
+  't3700-add.sh',
+  't3701-add-interactive.sh',
+  't3702-add-edit.sh',
+  't3703-add-magic-pathspec.sh',
+  't3704-add-pathspec-file.sh',
+  't3705-add-sparse-checkout.sh',
+  't3800-mktag.sh',
+  't3900-i18n-commit.sh',
+  't3901-i18n-patch.sh',
+  't3902-quoted.sh',
+  't3903-stash.sh',
+  't3904-stash-patch.sh',
+  't3905-stash-include-untracked.sh',
+  't3906-stash-submodule.sh',
+  't3907-stash-show-config.sh',
+  't3908-stash-in-worktree.sh',
+  't3909-stash-pathspec-file.sh',
+  't3910-mac-os-precompose.sh',
+  't3920-crlf-messages.sh',
+  't4000-diff-format.sh',
+  't4001-diff-rename.sh',
+  't4002-diff-basic.sh',
+  't4003-diff-rename-1.sh',
+  't4004-diff-rename-symlink.sh',
+  't4005-diff-rename-2.sh',
+  't4006-diff-mode.sh',
+  't4007-rename-3.sh',
+  't4008-diff-break-rewrite.sh',
+  't4009-diff-rename-4.sh',
+  't4010-diff-pathspec.sh',
+  't4011-diff-symlink.sh',
+  't4012-diff-binary.sh',
+  't4013-diff-various.sh',
+  't4014-format-patch.sh',
+  't4015-diff-whitespace.sh',
+  't4016-diff-quote.sh',
+  't4017-diff-retval.sh',
+  't4018-diff-funcname.sh',
+  't4019-diff-wserror.sh',
+  't4020-diff-external.sh',
+  't4021-format-patch-numbered.sh',
+  't4022-diff-rewrite.sh',
+  't4023-diff-rename-typechange.sh',
+  't4024-diff-optimize-common.sh',
+  't4025-hunk-header.sh',
+  't4026-color.sh',
+  't4027-diff-submodule.sh',
+  't4028-format-patch-mime-headers.sh',
+  't4029-diff-trailing-space.sh',
+  't4030-diff-textconv.sh',
+  't4031-diff-rewrite-binary.sh',
+  't4032-diff-inter-hunk-context.sh',
+  't4033-diff-patience.sh',
+  't4034-diff-words.sh',
+  't4035-diff-quiet.sh',
+  't4036-format-patch-signer-mime.sh',
+  't4037-diff-r-t-dirs.sh',
+  't4038-diff-combined.sh',
+  't4039-diff-assume-unchanged.sh',
+  't4040-whitespace-status.sh',
+  't4041-diff-submodule-option.sh',
+  't4042-diff-textconv-caching.sh',
+  't4043-diff-rename-binary.sh',
+  't4044-diff-index-unique-abbrev.sh',
+  't4045-diff-relative.sh',
+  't4046-diff-unmerged.sh',
+  't4047-diff-dirstat.sh',
+  't4048-diff-combined-binary.sh',
+  't4049-diff-stat-count.sh',
+  't4050-diff-histogram.sh',
+  't4051-diff-function-context.sh',
+  't4052-stat-output.sh',
+  't4053-diff-no-index.sh',
+  't4054-diff-bogus-tree.sh',
+  't4055-diff-context.sh',
+  't4056-diff-order.sh',
+  't4057-diff-combined-paths.sh',
+  't4058-diff-duplicates.sh',
+  't4059-diff-submodule-not-initialized.sh',
+  't4060-diff-submodule-option-diff-format.sh',
+  't4061-diff-indent.sh',
+  't4062-diff-pickaxe.sh',
+  't4063-diff-blobs.sh',
+  't4064-diff-oidfind.sh',
+  't4065-diff-anchored.sh',
+  't4066-diff-emit-delay.sh',
+  't4067-diff-partial-clone.sh',
+  't4068-diff-symmetric-merge-base.sh',
+  't4069-remerge-diff.sh',
+  't4100-apply-stat.sh',
+  't4101-apply-nonl.sh',
+  't4102-apply-rename.sh',
+  't4103-apply-binary.sh',
+  't4104-apply-boundary.sh',
+  't4105-apply-fuzz.sh',
+  't4106-apply-stdin.sh',
+  't4107-apply-ignore-whitespace.sh',
+  't4108-apply-threeway.sh',
+  't4109-apply-multifrag.sh',
+  't4110-apply-scan.sh',
+  't4111-apply-subdir.sh',
+  't4112-apply-renames.sh',
+  't4113-apply-ending.sh',
+  't4114-apply-typechange.sh',
+  't4115-apply-symlink.sh',
+  't4116-apply-reverse.sh',
+  't4117-apply-reject.sh',
+  't4118-apply-empty-context.sh',
+  't4119-apply-config.sh',
+  't4120-apply-popt.sh',
+  't4121-apply-diffs.sh',
+  't4122-apply-symlink-inside.sh',
+  't4123-apply-shrink.sh',
+  't4124-apply-ws-rule.sh',
+  't4125-apply-ws-fuzz.sh',
+  't4126-apply-empty.sh',
+  't4127-apply-same-fn.sh',
+  't4128-apply-root.sh',
+  't4129-apply-samemode.sh',
+  't4130-apply-criss-cross-rename.sh',
+  't4131-apply-fake-ancestor.sh',
+  't4132-apply-removal.sh',
+  't4133-apply-filenames.sh',
+  't4134-apply-submodule.sh',
+  't4135-apply-weird-filenames.sh',
+  't4136-apply-check.sh',
+  't4137-apply-submodule.sh',
+  't4138-apply-ws-expansion.sh',
+  't4139-apply-escape.sh',
+  't4140-apply-ita.sh',
+  't4141-apply-too-large.sh',
+  't4150-am.sh',
+  't4151-am-abort.sh',
+  't4152-am-subjects.sh',
+  't4153-am-resume-override-opts.sh',
+  't4200-rerere.sh',
+  't4201-shortlog.sh',
+  't4202-log.sh',
+  't4203-mailmap.sh',
+  't4204-patch-id.sh',
+  't4205-log-pretty-formats.sh',
+  't4206-log-follow-harder-copies.sh',
+  't4207-log-decoration-colors.sh',
+  't4208-log-magic-pathspec.sh',
+  't4209-log-pickaxe.sh',
+  't4210-log-i18n.sh',
+  't4211-line-log.sh',
+  't4212-log-corrupt.sh',
+  't4213-log-tabexpand.sh',
+  't4214-log-graph-octopus.sh',
+  't4215-log-skewed-merges.sh',
+  't4216-log-bloom.sh',
+  't4217-log-limit.sh',
+  't4252-am-options.sh',
+  't4253-am-keep-cr-dos.sh',
+  't4254-am-corrupt.sh',
+  't4255-am-submodule.sh',
+  't4256-am-format-flowed.sh',
+  't4257-am-interactive.sh',
+  't4258-am-quoted-cr.sh',
+  't4300-merge-tree.sh',
+  't4301-merge-tree-write-tree.sh',
+  't5000-tar-tree.sh',
+  't5001-archive-attr.sh',
+  't5002-archive-attr-pattern.sh',
+  't5003-archive-zip.sh',
+  't5004-archive-corner-cases.sh',
+  't5100-mailinfo.sh',
+  't5150-request-pull.sh',
+  't5200-update-server-info.sh',
+  't5300-pack-object.sh',
+  't5301-sliding-window.sh',
+  't5302-pack-index.sh',
+  't5303-pack-corruption-resilience.sh',
+  't5304-prune.sh',
+  't5305-include-tag.sh',
+  't5306-pack-nobase.sh',
+  't5307-pack-missing-commit.sh',
+  't5308-pack-detect-duplicates.sh',
+  't5309-pack-delta-cycles.sh',
+  't5310-pack-bitmaps.sh',
+  't5311-pack-bitmaps-shallow.sh',
+  't5312-prune-corruption.sh',
+  't5313-pack-bounds-checks.sh',
+  't5314-pack-cycle-detection.sh',
+  't5315-pack-objects-compression.sh',
+  't5316-pack-delta-depth.sh',
+  't5317-pack-objects-filter-objects.sh',
+  't5318-commit-graph.sh',
+  't5319-multi-pack-index.sh',
+  't5320-delta-islands.sh',
+  't5321-pack-large-objects.sh',
+  't5322-pack-objects-sparse.sh',
+  't5323-pack-redundant.sh',
+  't5324-split-commit-graph.sh',
+  't5325-reverse-index.sh',
+  't5326-multi-pack-bitmaps.sh',
+  't5327-multi-pack-bitmaps-rev.sh',
+  't5328-commit-graph-64bit-time.sh',
+  't5329-pack-objects-cruft.sh',
+  't5330-no-lazy-fetch-with-commit-graph.sh',
+  't5331-pack-objects-stdin.sh',
+  't5332-multi-pack-reuse.sh',
+  't5333-pseudo-merge-bitmaps.sh',
+  't5334-incremental-multi-pack-index.sh',
+  't5351-unpack-large-objects.sh',
+  't5400-send-pack.sh',
+  't5401-update-hooks.sh',
+  't5402-post-merge-hook.sh',
+  't5403-post-checkout-hook.sh',
+  't5404-tracking-branches.sh',
+  't5405-send-pack-rewind.sh',
+  't5406-remote-rejects.sh',
+  't5407-post-rewrite-hook.sh',
+  't5408-send-pack-stdin.sh',
+  't5409-colorize-remote-messages.sh',
+  't5410-receive-pack-alternates.sh',
+  't5411-proc-receive-hook.sh',
+  't5500-fetch-pack.sh',
+  't5501-fetch-push-alternates.sh',
+  't5502-quickfetch.sh',
+  't5503-tagfollow.sh',
+  't5504-fetch-receive-strict.sh',
+  't5505-remote.sh',
+  't5506-remote-groups.sh',
+  't5507-remote-environment.sh',
+  't5509-fetch-push-namespaces.sh',
+  't5510-fetch.sh',
+  't5511-refspec.sh',
+  't5512-ls-remote.sh',
+  't5513-fetch-track.sh',
+  't5514-fetch-multiple.sh',
+  't5515-fetch-merge-logic.sh',
+  't5516-fetch-push.sh',
+  't5517-push-mirror.sh',
+  't5518-fetch-exit-status.sh',
+  't5519-push-alternates.sh',
+  't5520-pull.sh',
+  't5521-pull-options.sh',
+  't5522-pull-symlink.sh',
+  't5523-push-upstream.sh',
+  't5524-pull-msg.sh',
+  't5525-fetch-tagopt.sh',
+  't5526-fetch-submodules.sh',
+  't5527-fetch-odd-refs.sh',
+  't5528-push-default.sh',
+  't5529-push-errors.sh',
+  't5530-upload-pack-error.sh',
+  't5531-deep-submodule-push.sh',
+  't5532-fetch-proxy.sh',
+  't5533-push-cas.sh',
+  't5534-push-signed.sh',
+  't5535-fetch-push-symref.sh',
+  't5536-fetch-conflicts.sh',
+  't5537-fetch-shallow.sh',
+  't5538-push-shallow.sh',
+  't5539-fetch-http-shallow.sh',
+  't5540-http-push-webdav.sh',
+  't5541-http-push-smart.sh',
+  't5542-push-http-shallow.sh',
+  't5543-atomic-push.sh',
+  't5544-pack-objects-hook.sh',
+  't5545-push-options.sh',
+  't5546-receive-limits.sh',
+  't5547-push-quarantine.sh',
+  't5548-push-porcelain.sh',
+  't5549-fetch-push-http.sh',
+  't5550-http-fetch-dumb.sh',
+  't5551-http-fetch-smart.sh',
+  't5552-skipping-fetch-negotiator.sh',
+  't5553-set-upstream.sh',
+  't5554-noop-fetch-negotiator.sh',
+  't5555-http-smart-common.sh',
+  't5557-http-get.sh',
+  't5558-clone-bundle-uri.sh',
+  't5559-http-fetch-smart-http2.sh',
+  't5560-http-backend-noserver.sh',
+  't5561-http-backend.sh',
+  't5562-http-backend-content-length.sh',
+  't5563-simple-http-auth.sh',
+  't5564-http-proxy.sh',
+  't5570-git-daemon.sh',
+  't5571-pre-push-hook.sh',
+  't5572-pull-submodule.sh',
+  't5573-pull-verify-signatures.sh',
+  't5574-fetch-output.sh',
+  't5580-unc-paths.sh',
+  't5581-http-curl-verbose.sh',
+  't5582-fetch-negative-refspec.sh',
+  't5583-push-branches.sh',
+  't5600-clone-fail-cleanup.sh',
+  't5601-clone.sh',
+  't5602-clone-remote-exec.sh',
+  't5603-clone-dirname.sh',
+  't5604-clone-reference.sh',
+  't5605-clone-local.sh',
+  't5606-clone-options.sh',
+  't5607-clone-bundle.sh',
+  't5608-clone-2gb.sh',
+  't5609-clone-branch.sh',
+  't5610-clone-detached.sh',
+  't5611-clone-config.sh',
+  't5612-clone-refspec.sh',
+  't5613-info-alternate.sh',
+  't5614-clone-submodules-shallow.sh',
+  't5615-alternate-env.sh',
+  't5616-partial-clone.sh',
+  't5617-clone-submodules-remote.sh',
+  't5618-alternate-refs.sh',
+  't5619-clone-local-ambiguous-transport.sh',
+  't5700-protocol-v1.sh',
+  't5701-git-serve.sh',
+  't5702-protocol-v2.sh',
+  't5703-upload-pack-ref-in-want.sh',
+  't5704-protocol-violations.sh',
+  't5705-session-id-in-capabilities.sh',
+  't5730-protocol-v2-bundle-uri-file.sh',
+  't5731-protocol-v2-bundle-uri-git.sh',
+  't5732-protocol-v2-bundle-uri-http.sh',
+  't5750-bundle-uri-parse.sh',
+  't5801-remote-helpers.sh',
+  't5802-connect-helper.sh',
+  't5810-proto-disable-local.sh',
+  't5811-proto-disable-git.sh',
+  't5812-proto-disable-http.sh',
+  't5813-proto-disable-ssh.sh',
+  't5814-proto-disable-ext.sh',
+  't5815-submodule-protos.sh',
+  't5900-repo-selection.sh',
+  't6000-rev-list-misc.sh',
+  't6001-rev-list-graft.sh',
+  't6002-rev-list-bisect.sh',
+  't6003-rev-list-topo-order.sh',
+  't6004-rev-list-path-optim.sh',
+  't6005-rev-list-count.sh',
+  't6006-rev-list-format.sh',
+  't6007-rev-list-cherry-pick-file.sh',
+  't6008-rev-list-submodule.sh',
+  't6009-rev-list-parent.sh',
+  't6010-merge-base.sh',
+  't6011-rev-list-with-bad-commit.sh',
+  't6012-rev-list-simplify.sh',
+  't6013-rev-list-reverse-parents.sh',
+  't6014-rev-list-all.sh',
+  't6016-rev-list-graph-simplify-history.sh',
+  't6017-rev-list-stdin.sh',
+  't6018-rev-list-glob.sh',
+  't6019-rev-list-ancestry-path.sh',
+  't6020-bundle-misc.sh',
+  't6021-rev-list-exclude-hidden.sh',
+  't6022-rev-list-missing.sh',
+  't6030-bisect-porcelain.sh',
+  't6040-tracking-info.sh',
+  't6041-bisect-submodule.sh',
+  't6050-replace.sh',
+  't6060-merge-index.sh',
+  't6100-rev-list-in-order.sh',
+  't6101-rev-parse-parents.sh',
+  't6102-rev-list-unexpected-objects.sh',
+  't6110-rev-list-sparse.sh',
+  't6111-rev-list-treesame.sh',
+  't6112-rev-list-filters-objects.sh',
+  't6113-rev-list-bitmap-filters.sh',
+  't6114-keep-packs.sh',
+  't6115-rev-list-du.sh',
+  't6120-describe.sh',
+  't6130-pathspec-noglob.sh',
+  't6131-pathspec-icase.sh',
+  't6132-pathspec-exclude.sh',
+  't6133-pathspec-rev-dwim.sh',
+  't6134-pathspec-in-submodule.sh',
+  't6135-pathspec-with-attrs.sh',
+  't6136-pathspec-in-bare.sh',
+  't6200-fmt-merge-msg.sh',
+  't6300-for-each-ref.sh',
+  't6301-for-each-ref-errors.sh',
+  't6302-for-each-ref-filter.sh',
+  't6400-merge-df.sh',
+  't6401-merge-criss-cross.sh',
+  't6402-merge-rename.sh',
+  't6403-merge-file.sh',
+  't6404-recursive-merge.sh',
+  't6405-merge-symlinks.sh',
+  't6406-merge-attr.sh',
+  't6407-merge-binary.sh',
+  't6408-merge-up-to-date.sh',
+  't6409-merge-subtree.sh',
+  't6411-merge-filemode.sh',
+  't6412-merge-large-rename.sh',
+  't6413-merge-crlf.sh',
+  't6414-merge-rename-nocruft.sh',
+  't6415-merge-dir-to-symlink.sh',
+  't6416-recursive-corner-cases.sh',
+  't6417-merge-ours-theirs.sh',
+  't6418-merge-text-auto.sh',
+  't6419-merge-ignorecase.sh',
+  't6421-merge-partial-clone.sh',
+  't6422-merge-rename-corner-cases.sh',
+  't6423-merge-rename-directories.sh',
+  't6424-merge-unrelated-index-changes.sh',
+  't6425-merge-rename-delete.sh',
+  't6426-merge-skip-unneeded-updates.sh',
+  't6427-diff3-conflict-markers.sh',
+  't6428-merge-conflicts-sparse.sh',
+  't6429-merge-sequence-rename-caching.sh',
+  't6430-merge-recursive.sh',
+  't6431-merge-criscross.sh',
+  't6432-merge-recursive-space-options.sh',
+  't6433-merge-toplevel.sh',
+  't6434-merge-recursive-rename-options.sh',
+  't6435-merge-sparse.sh',
+  't6436-merge-overwrite.sh',
+  't6437-submodule-merge.sh',
+  't6438-submodule-directory-file-conflicts.sh',
+  't6439-merge-co-error-msgs.sh',
+  't6500-gc.sh',
+  't6501-freshen-objects.sh',
+  't6600-test-reach.sh',
+  't6700-tree-depth.sh',
+  't7001-mv.sh',
+  't7002-mv-sparse-checkout.sh',
+  't7003-filter-branch.sh',
+  't7004-tag.sh',
+  't7005-editor.sh',
+  't7006-pager.sh',
+  't7007-show.sh',
+  't7008-filter-branch-null-sha1.sh',
+  't7010-setup.sh',
+  't7011-skip-worktree-reading.sh',
+  't7012-skip-worktree-writing.sh',
+  't7030-verify-tag.sh',
+  't7031-verify-tag-signed-ssh.sh',
+  't7060-wtstatus.sh',
+  't7061-wtstatus-ignore.sh',
+  't7062-wtstatus-ignorecase.sh',
+  't7063-status-untracked-cache.sh',
+  't7064-wtstatus-pv2.sh',
+  't7101-reset-empty-subdirs.sh',
+  't7102-reset.sh',
+  't7103-reset-bare.sh',
+  't7104-reset-hard.sh',
+  't7105-reset-patch.sh',
+  't7106-reset-unborn-branch.sh',
+  't7107-reset-pathspec-file.sh',
+  't7110-reset-merge.sh',
+  't7111-reset-table.sh',
+  't7112-reset-submodule.sh',
+  't7113-post-index-change-hook.sh',
+  't7201-co.sh',
+  't7300-clean.sh',
+  't7301-clean-interactive.sh',
+  't7400-submodule-basic.sh',
+  't7401-submodule-summary.sh',
+  't7402-submodule-rebase.sh',
+  't7403-submodule-sync.sh',
+  't7406-submodule-update.sh',
+  't7407-submodule-foreach.sh',
+  't7408-submodule-reference.sh',
+  't7409-submodule-detached-work-tree.sh',
+  't7411-submodule-config.sh',
+  't7412-submodule-absorbgitdirs.sh',
+  't7413-submodule-is-active.sh',
+  't7414-submodule-mistakes.sh',
+  't7416-submodule-dash-url.sh',
+  't7417-submodule-path-url.sh',
+  't7418-submodule-sparse-gitmodules.sh',
+  't7419-submodule-set-branch.sh',
+  't7420-submodule-set-url.sh',
+  't7421-submodule-summary-add.sh',
+  't7422-submodule-output.sh',
+  't7423-submodule-symlinks.sh',
+  't7424-submodule-mixed-ref-formats.sh',
+  't7450-bad-git-dotfiles.sh',
+  't7500-commit-template-squash-signoff.sh',
+  't7501-commit-basic-functionality.sh',
+  't7502-commit-porcelain.sh',
+  't7503-pre-commit-and-pre-merge-commit-hooks.sh',
+  't7504-commit-msg-hook.sh',
+  't7505-prepare-commit-msg-hook.sh',
+  't7506-status-submodule.sh',
+  't7507-commit-verbose.sh',
+  't7508-status.sh',
+  't7509-commit-authorship.sh',
+  't7510-signed-commit.sh',
+  't7511-status-index.sh',
+  't7512-status-help.sh',
+  't7513-interpret-trailers.sh',
+  't7514-commit-patch.sh',
+  't7515-status-symlinks.sh',
+  't7516-commit-races.sh',
+  't7517-per-repo-email.sh',
+  't7518-ident-corner-cases.sh',
+  't7519-status-fsmonitor.sh',
+  't7520-ignored-hook-warning.sh',
+  't7521-ignored-mode.sh',
+  't7524-commit-summary.sh',
+  't7525-status-rename.sh',
+  't7526-commit-pathspec-file.sh',
+  't7527-builtin-fsmonitor.sh',
+  't7528-signed-commit-ssh.sh',
+  't7600-merge.sh',
+  't7601-merge-pull-config.sh',
+  't7602-merge-octopus-many.sh',
+  't7603-merge-reduce-heads.sh',
+  't7604-merge-custom-message.sh',
+  't7605-merge-resolve.sh',
+  't7606-merge-custom.sh',
+  't7607-merge-state.sh',
+  't7608-merge-messages.sh',
+  't7609-mergetool--lib.sh',
+  't7610-mergetool.sh',
+  't7611-merge-abort.sh',
+  't7612-merge-verify-signatures.sh',
+  't7614-merge-signoff.sh',
+  't7615-diff-algo-with-mergy-operations.sh',
+  't7700-repack.sh',
+  't7701-repack-unpack-unreachable.sh',
+  't7702-repack-cyclic-alternate.sh',
+  't7703-repack-geometric.sh',
+  't7704-repack-cruft.sh',
+  't7800-difftool.sh',
+  't7810-grep.sh',
+  't7811-grep-open.sh',
+  't7812-grep-icase-non-ascii.sh',
+  't7813-grep-icase-iso.sh',
+  't7814-grep-recurse-submodules.sh',
+  't7815-grep-binary.sh',
+  't7816-grep-binary-pattern.sh',
+  't7817-grep-sparse-checkout.sh',
+  't7900-maintenance.sh',
+  't8001-annotate.sh',
+  't8002-blame.sh',
+  't8003-blame-corner-cases.sh',
+  't8004-blame-with-conflicts.sh',
+  't8005-blame-i18n.sh',
+  't8006-blame-textconv.sh',
+  't8007-cat-file-textconv.sh',
+  't8008-blame-formats.sh',
+  't8009-blame-vs-topicbranches.sh',
+  't8010-cat-file-filters.sh',
+  't8011-blame-split-file.sh',
+  't8012-blame-colors.sh',
+  't8013-blame-ignore-revs.sh',
+  't8014-blame-ignore-fuzzy.sh',
+  't9001-send-email.sh',
+  't9002-column.sh',
+  't9003-help-autocorrect.sh',
+  't9100-git-svn-basic.sh',
+  't9101-git-svn-props.sh',
+  't9102-git-svn-deep-rmdir.sh',
+  't9103-git-svn-tracked-directory-removed.sh',
+  't9104-git-svn-follow-parent.sh',
+  't9105-git-svn-commit-diff.sh',
+  't9106-git-svn-commit-diff-clobber.sh',
+  't9107-git-svn-migrate.sh',
+  't9108-git-svn-glob.sh',
+  't9109-git-svn-multi-glob.sh',
+  't9110-git-svn-use-svm-props.sh',
+  't9111-git-svn-use-svnsync-props.sh',
+  't9112-git-svn-md5less-file.sh',
+  't9113-git-svn-dcommit-new-file.sh',
+  't9114-git-svn-dcommit-merge.sh',
+  't9115-git-svn-dcommit-funky-renames.sh',
+  't9116-git-svn-log.sh',
+  't9117-git-svn-init-clone.sh',
+  't9118-git-svn-funky-branch-names.sh',
+  't9119-git-svn-info.sh',
+  't9120-git-svn-clone-with-percent-escapes.sh',
+  't9121-git-svn-fetch-renamed-dir.sh',
+  't9122-git-svn-author.sh',
+  't9123-git-svn-rebuild-with-rewriteroot.sh',
+  't9124-git-svn-dcommit-auto-props.sh',
+  't9125-git-svn-multi-glob-branch-names.sh',
+  't9126-git-svn-follow-deleted-readded-directory.sh',
+  't9127-git-svn-partial-rebuild.sh',
+  't9128-git-svn-cmd-branch.sh',
+  't9129-git-svn-i18n-commitencoding.sh',
+  't9130-git-svn-authors-file.sh',
+  't9131-git-svn-empty-symlink.sh',
+  't9132-git-svn-broken-symlink.sh',
+  't9133-git-svn-nested-git-repo.sh',
+  't9134-git-svn-ignore-paths.sh',
+  't9135-git-svn-moved-branch-empty-file.sh',
+  't9136-git-svn-recreated-branch-empty-file.sh',
+  't9137-git-svn-dcommit-clobber-series.sh',
+  't9138-git-svn-authors-prog.sh',
+  't9139-git-svn-non-utf8-commitencoding.sh',
+  't9140-git-svn-reset.sh',
+  't9141-git-svn-multiple-branches.sh',
+  't9142-git-svn-shallow-clone.sh',
+  't9143-git-svn-gc.sh',
+  't9144-git-svn-old-rev_map.sh',
+  't9145-git-svn-master-branch.sh',
+  't9146-git-svn-empty-dirs.sh',
+  't9147-git-svn-include-paths.sh',
+  't9148-git-svn-propset.sh',
+  't9150-svk-mergetickets.sh',
+  't9151-svn-mergeinfo.sh',
+  't9152-svn-empty-dirs-after-gc.sh',
+  't9153-git-svn-rewrite-uuid.sh',
+  't9154-git-svn-fancy-glob.sh',
+  't9155-git-svn-fetch-deleted-tag.sh',
+  't9156-git-svn-fetch-deleted-tag-2.sh',
+  't9157-git-svn-fetch-merge.sh',
+  't9158-git-svn-mergeinfo.sh',
+  't9159-git-svn-no-parent-mergeinfo.sh',
+  't9160-git-svn-preserve-empty-dirs.sh',
+  't9161-git-svn-mergeinfo-push.sh',
+  't9162-git-svn-dcommit-interactive.sh',
+  't9163-git-svn-reset-clears-caches.sh',
+  't9164-git-svn-dcommit-concurrent.sh',
+  't9165-git-svn-fetch-merge-branch-of-branch.sh',
+  't9166-git-svn-fetch-merge-branch-of-branch2.sh',
+  't9167-git-svn-cmd-branch-subproject.sh',
+  't9168-git-svn-partially-globbed-names.sh',
+  't9169-git-svn-dcommit-crlf.sh',
+  't9200-git-cvsexportcommit.sh',
+  't9210-scalar.sh',
+  't9211-scalar-clone.sh',
+  't9300-fast-import.sh',
+  't9301-fast-import-notes.sh',
+  't9302-fast-import-unpack-limit.sh',
+  't9303-fast-import-compression.sh',
+  't9304-fast-import-marks.sh',
+  't9350-fast-export.sh',
+  't9351-fast-export-anonymize.sh',
+  't9400-git-cvsserver-server.sh',
+  't9401-git-cvsserver-crlf.sh',
+  't9402-git-cvsserver-refs.sh',
+  't9500-gitweb-standalone-no-errors.sh',
+  't9501-gitweb-standalone-http-status.sh',
+  't9502-gitweb-standalone-parse-output.sh',
+  't9600-cvsimport.sh',
+  't9601-cvsimport-vendor-branch.sh',
+  't9602-cvsimport-branches-tags.sh',
+  't9603-cvsimport-patchsets.sh',
+  't9604-cvsimport-timestamps.sh',
+  't9700-perl-git.sh',
+  't9800-git-p4-basic.sh',
+  't9801-git-p4-branch.sh',
+  't9802-git-p4-filetype.sh',
+  't9803-git-p4-shell-metachars.sh',
+  't9804-git-p4-label.sh',
+  't9805-git-p4-skip-submit-edit.sh',
+  't9806-git-p4-options.sh',
+  't9807-git-p4-submit.sh',
+  't9808-git-p4-chdir.sh',
+  't9809-git-p4-client-view.sh',
+  't9810-git-p4-rcs.sh',
+  't9811-git-p4-label-import.sh',
+  't9812-git-p4-wildcards.sh',
+  't9813-git-p4-preserve-users.sh',
+  't9814-git-p4-rename.sh',
+  't9815-git-p4-submit-fail.sh',
+  't9816-git-p4-locked.sh',
+  't9817-git-p4-exclude.sh',
+  't9818-git-p4-block.sh',
+  't9819-git-p4-case-folding.sh',
+  't9820-git-p4-editor-handling.sh',
+  't9821-git-p4-path-variations.sh',
+  't9822-git-p4-path-encoding.sh',
+  't9823-git-p4-mock-lfs.sh',
+  't9824-git-p4-git-lfs.sh',
+  't9825-git-p4-handle-utf16-without-bom.sh',
+  't9826-git-p4-keep-empty-commits.sh',
+  't9827-git-p4-change-filetype.sh',
+  't9828-git-p4-map-user.sh',
+  't9829-git-p4-jobs.sh',
+  't9830-git-p4-symlink-dir.sh',
+  't9831-git-p4-triggers.sh',
+  't9832-unshelve.sh',
+  't9833-errors.sh',
+  't9834-git-p4-file-dir-bug.sh',
+  't9835-git-p4-metadata-encoding-python2.sh',
+  't9836-git-p4-metadata-encoding-python3.sh',
+  't9850-shell.sh',
+  't9901-git-web--browse.sh',
+  't9902-completion.sh',
+  't9903-bash-prompt.sh',
+]
+
+# GIT_BUILD_DIR needs to be Unix-style without drive prefixes as it get added
+# to the PATH variable. And given that drive prefixes contain a colon we'd
+# otherwise end up with a broken PATH if we didn't convert it.
+git_build_dir = meson.project_build_root()
+if cygpath.found()
+  git_build_dir = run_command(cygpath, git_build_dir, check: true).stdout().strip()
+endif
+
+test_environment = script_environment
+test_environment.set('GIT_BUILD_DIR', git_build_dir)
+
+foreach integration_test : integration_tests
+  test(fs.stem(integration_test), shell,
+    args: [ integration_test ],
+    workdir: meson.current_source_dir(),
+    env: test_environment,
+    depends: test_dependencies + bin_wrappers,
+    timeout: 0,
+  )
+endforeach
diff --git a/templates/hooks/meson.build b/templates/hooks/meson.build
new file mode 100644
index 00000000000..f948b9fb145
--- /dev/null
+++ b/templates/hooks/meson.build
@@ -0,0 +1,24 @@
+hooks = [
+  'applypatch-msg.sample',
+  'commit-msg.sample',
+  'fsmonitor-watchman.sample',
+  'post-update.sample',
+  'pre-applypatch.sample',
+  'pre-commit.sample',
+  'pre-merge-commit.sample',
+  'prepare-commit-msg.sample',
+  'pre-push.sample',
+  'pre-rebase.sample',
+  'pre-receive.sample',
+  'push-to-checkout.sample',
+  'sendemail-validate.sample',
+  'update.sample',
+]
+
+foreach hook : hooks
+  configure_file(
+    input: hook,
+    output: hook,
+    configuration: template_config,
+  )
+endforeach
diff --git a/templates/info/meson.build b/templates/info/meson.build
new file mode 100644
index 00000000000..1a2f2f84d2f
--- /dev/null
+++ b/templates/info/meson.build
@@ -0,0 +1,5 @@
+configure_file(
+  input: 'exclude',
+  output: 'exclude',
+  configuration: template_config,
+)
diff --git a/templates/meson.build b/templates/meson.build
new file mode 100644
index 00000000000..010b9ef6d3a
--- /dev/null
+++ b/templates/meson.build
@@ -0,0 +1,13 @@
+template_config = configuration_data()
+template_config.set('PERL_PATH', perl.found() ? fs.as_posix(perl.full_path()) : '')
+template_config.set('SHELL_PATH', fs.as_posix(shell.full_path()))
+template_config.set('GITWEBDIR', fs.as_posix(get_option('prefix') / get_option('datadir') / 'gitweb'))
+
+configure_file(
+  input: 'description',
+  output: 'description',
+  configuration: template_config,
+)
+
+subdir('hooks')
+subdir('info')
-- 
2.47.0.229.g8f8d6eee53.dirty
Previous: Patrick SteinhardtNext: Patrick Steinhardt
Message 205 of 355 in “Modernize the build system”
  1. 00/21 Modernize the build systemPatrick Steinhardt, Oct 2, 2024
  2. 01/21 Documentation: add comparison of build systemsPatrick Steinhardt, Oct 2, 2024
  3. Junio C HamanoOct 2, 2024
  4. Eli SchwartzOct 6, 2024
  5. Patrick SteinhardtOct 7, 2024
  6. Junio C HamanoOct 7, 2024
  7. Eric SunshineOct 2, 2024
  8. Patrick SteinhardtOct 7, 2024
  9. 02/21 t/test-lib: fix quoting of TEST_RESULTS_SAN_FILEPatrick Steinhardt, Oct 2, 2024
  10. 03/21 t/lib-gitweb: test against the build version of gitwebPatrick Steinhardt, Oct 2, 2024
  11. 04/21 t/lib-gpg: fix setup of GNUPGHOME in MinGWPatrick Steinhardt, Oct 2, 2024
  12. Eric SunshineOct 2, 2024
  13. Patrick SteinhardtOct 7, 2024
  14. 05/21 t3404: work around platform-specific behaviour on macOS 10.15Patrick Steinhardt, Oct 2, 2024
  15. Eric SunshineOct 2, 2024
  16. Phillip WoodOct 3, 2024
  17. Eric SunshineOct 3, 2024
  18. Junio C HamanoOct 3, 2024
  19. Patrick SteinhardtOct 7, 2024
  20. Patrick SteinhardtOct 7, 2024
  21. Patrick SteinhardtOct 7, 2024
  22. 06/21 t/unit-tests: update clar unit test frameworkPatrick Steinhardt, Oct 2, 2024
  23. 07/21 t/clar: simplify how the clar derives `struct stat`Patrick Steinhardt, Oct 2, 2024
  24. 08/21 builtin/credential-cache: fix missing parameter for stub functionPatrick Steinhardt, Oct 2, 2024
  25. 09/21 http: fix build error on FreeBSDPatrick Steinhardt, Oct 2, 2024
  26. 10/21 Makefile: extract script to generate clar declarationsPatrick Steinhardt, Oct 2, 2024
  27. 11/21 Makefile: extract script to massage Perl scriptsPatrick Steinhardt, Oct 2, 2024
  28. 12/21 Makefile: refactor GIT-VERSION-GEN to be reusablePatrick Steinhardt, Oct 2, 2024
  29. 13/21 Makefile: refactor generators to be PWD-independentPatrick Steinhardt, Oct 2, 2024
  30. 14/21 Makefile: use common template for GIT-BUILD-OPTIONSPatrick Steinhardt, Oct 2, 2024
  31. 15/21 Makefile: consistently use @PLACEHOLDER@ to substitutePatrick Steinhardt, Oct 2, 2024
  32. Phillip WoodOct 8, 2024
  33. Patrick SteinhardtOct 8, 2024
  34. 16/21 Makefile: consistently use PERL_PATHPatrick Steinhardt, Oct 2, 2024
  35. 17/21 Makefile: allow "bin-wrappers/" directory to existPatrick Steinhardt, Oct 2, 2024
  36. 18/21 Makefile: simplify building of templatesPatrick Steinhardt, Oct 2, 2024
  37. 19/21 t: better support for out-of-tree buildsPatrick Steinhardt, Oct 2, 2024
  38. 20/21 t: allow overriding build dirPatrick Steinhardt, Oct 2, 2024
  39. Phillip WoodOct 8, 2024
  40. Patrick SteinhardtOct 8, 2024
  41. 21/21 Introduce support for the Meson build systemPatrick Steinhardt, Oct 2, 2024
  42. Phillip WoodOct 8, 2024
  43. Patrick SteinhardtOct 8, 2024
  44. 00/24 Modernize our build systemPatrick Steinhardt, Oct 9, 2024
  45. 01/24 t/test-lib: fix quoting of TEST_RESULTS_SAN_FILEPatrick Steinhardt, Oct 9, 2024
  46. 02/24 t/test-lib: wire up NO_ICONV prerequisitePatrick Steinhardt, Oct 9, 2024
  47. 03/24 t/lib-gitweb: test against the build version of gitwebPatrick Steinhardt, Oct 9, 2024
  48. 04/24 t/lib-gpg: fix setup of GNUPGHOME in MinGWPatrick Steinhardt, Oct 9, 2024
  49. 05/24 t1401: make invocation of tar(1) work with Win32-provided onePatrick Steinhardt, Oct 9, 2024
  50. 06/24 t3404: work around platform-specific behaviour on macOS 10.15Patrick Steinhardt, Oct 9, 2024
  51. 07/24 t5500, t5601: skip tests which exercise paths with '[::1]' on CygwinPatrick Steinhardt, Oct 9, 2024
  52. 08/24 t7300: work around platform-specific behaviour with long paths on MinGWPatrick Steinhardt, Oct 9, 2024
  53. 09/24 t/unit-tests: update clar unit test frameworkPatrick Steinhardt, Oct 9, 2024
  54. 10/24 builtin/credential-cache: fix missing parameter for stub functionPatrick Steinhardt, Oct 9, 2024
  55. 11/24 http: fix build error on FreeBSDPatrick Steinhardt, Oct 9, 2024
  56. 12/24 Makefile: extract script to generate clar declarationsPatrick Steinhardt, Oct 9, 2024
  57. 13/24 Makefile: extract script to massage Perl scriptsPatrick Steinhardt, Oct 9, 2024
  58. 14/24 Makefile: refactor GIT-VERSION-GEN to be reusablePatrick Steinhardt, Oct 9, 2024
  59. 15/24 Makefile: refactor generators to be PWD-independentPatrick Steinhardt, Oct 9, 2024
  60. 16/24 Makefile: use common template for GIT-BUILD-OPTIONSPatrick Steinhardt, Oct 9, 2024
  61. 17/24 Makefile: consistently use @PLACEHOLDER@ to substitutePatrick Steinhardt, Oct 9, 2024
  62. 18/24 Makefile: consistently use PERL_PATHPatrick Steinhardt, Oct 9, 2024
  63. 19/24 Makefile: allow "bin-wrappers/" directory to existPatrick Steinhardt, Oct 9, 2024
  64. 20/24 Makefile: simplify building of templatesPatrick Steinhardt, Oct 9, 2024
  65. 21/24 t: better support for out-of-tree buildsPatrick Steinhardt, Oct 9, 2024
  66. 22/24 t: allow overriding build dirPatrick Steinhardt, Oct 9, 2024
  67. 23/24 Documentation: add comparison of build systemsPatrick Steinhardt, Oct 9, 2024
  68. Phillip WoodOct 14, 2024
  69. Patrick SteinhardtOct 15, 2024
  70. phillip.wood123@gmail.comOct 16, 2024
  71. Patrick SteinhardtOct 17, 2024
  72. Patrick SteinhardtOct 17, 2024
  73. 24/24 Introduce support for the Meson build systemPatrick Steinhardt, Oct 9, 2024
  74. Eli SchwartzOct 14, 2024
  75. Patrick SteinhardtOct 14, 2024
  76. Junio C HamanoOct 10, 2024
  77. Patrick SteinhardtOct 10, 2024
  78. Patrick SteinhardtOct 10, 2024
  79. Junio C HamanoOct 12, 2024
  80. Taylor BlauOct 12, 2024
  81. 00/15 Modernize the build systemPatrick Steinhardt, Oct 18, 2024
  82. 01/15 Makefile: use common template for GIT-BUILD-OPTIONSPatrick Steinhardt, Oct 18, 2024
  83. Eric SunshineOct 19, 2024
  84. Patrick SteinhardtOct 23, 2024
  85. 02/15 Makefile: consistently use @PLACEHOLDER@ to substitutePatrick Steinhardt, Oct 18, 2024
  86. 03/15 Makefile: consistently use PERL_PATHPatrick Steinhardt, Oct 18, 2024
  87. 04/15 Makefile: extract script to massage Perl scriptsPatrick Steinhardt, Oct 18, 2024
  88. 05/15 Makefile: use "generate-perl.sh" to massage Perl libraryPatrick Steinhardt, Oct 18, 2024
  89. 06/15 Makefile: extract script to massage Shell scriptsPatrick Steinhardt, Oct 18, 2024
  90. 07/15 Makefile: extract script to generate gitweb.cgiPatrick Steinhardt, Oct 18, 2024
  91. 08/15 Makefile: refactor GIT-VERSION-GEN to be reusablePatrick Steinhardt, Oct 18, 2024
  92. 09/15 Makefile: refactor generators to be PWD-independentPatrick Steinhardt, Oct 18, 2024
  93. Eric SunshineOct 19, 2024
  94. 10/15 Makefile: allow "bin-wrappers/" directory to existPatrick Steinhardt, Oct 18, 2024
  95. 11/15 Makefile: simplify building of templatesPatrick Steinhardt, Oct 18, 2024
  96. Eric SunshineOct 19, 2024
  97. 12/15 t: better support for out-of-tree buildsPatrick Steinhardt, Oct 18, 2024
  98. 13/15 t: allow overriding build dirPatrick Steinhardt, Oct 18, 2024
  99. Eric SunshineOct 19, 2024
  100. 14/15 Documentation: add comparison of build systemsPatrick Steinhardt, Oct 18, 2024
  101. 15/15 Introduce support for the Meson build systemPatrick Steinhardt, Oct 18, 2024
  102. Eric SunshineOct 19, 2024
  103. Ramsay JonesOct 18, 2024
  104. Eli SchwartzOct 20, 2024
  105. Ramsay JonesOct 21, 2024
  106. Patrick SteinhardtOct 23, 2024
  107. Ramsay JonesOct 23, 2024
  108. Eli SchwartzOct 23, 2024
  109. Ramsay JonesOct 24, 2024
  110. Patrick SteinhardtOct 24, 2024
  111. Patrick SteinhardtOct 24, 2024
  112. Ramsay JonesOct 24, 2024
  113. Patrick SteinhardtOct 25, 2024
  114. Ramsay JonesOct 25, 2024
  115. Patrick SteinhardtNov 4, 2024
  116. Patrick SteinhardtOct 23, 2024
  117. Taylor BlauOct 18, 2024
  118. Patrick SteinhardtOct 23, 2024
  119. Taylor BlauOct 23, 2024
  120. Patrick SteinhardtOct 24, 2024
  121. Taylor BlauOct 21, 2024
  122. Patrick SteinhardtOct 23, 2024
  123. Taylor BlauOct 23, 2024
  124. 00/19 Modernize the build systemPatrick Steinhardt, Oct 24, 2024
  125. 01/19 Makefile: use common template for GIT-BUILD-OPTIONSPatrick Steinhardt, Oct 24, 2024
  126. 02/19 Makefile: consistently use @PLACEHOLDER@ to substitutePatrick Steinhardt, Oct 24, 2024
  127. 03/19 Makefile: consistently use PERL_PATHPatrick Steinhardt, Oct 24, 2024
  128. 04/19 Makefile: extract script to massage Perl scriptsPatrick Steinhardt, Oct 24, 2024
  129. Phillip WoodNov 10, 2024
  130. Patrick SteinhardtNov 11, 2024
  131. 05/19 Makefile: use "generate-perl.sh" to massage Perl libraryPatrick Steinhardt, Oct 24, 2024
  132. Phillip WoodNov 11, 2024
  133. Patrick SteinhardtNov 11, 2024
  134. Paul SmithNov 11, 2024
  135. Patrick SteinhardtNov 11, 2024
  136. 06/19 Makefile: extract script to massage Shell scriptsPatrick Steinhardt, Oct 24, 2024
  137. Phillip WoodNov 10, 2024
  138. 07/19 Makefile: extract script to generate gitweb.cgiPatrick Steinhardt, Oct 24, 2024
  139. 08/19 Makefile: refactor GIT-VERSION-GEN to be reusablePatrick Steinhardt, Oct 24, 2024
  140. 09/19 Makefile: refactor generators to be PWD-independentPatrick Steinhardt, Oct 24, 2024
  141. 10/19 Makefile: allow "bin-wrappers/" directory to existPatrick Steinhardt, Oct 24, 2024
  142. 11/19 Makefile: simplify building of templatesPatrick Steinhardt, Oct 24, 2024
  143. 12/19 Documentation: allow sourcing generated includes from separate dirPatrick Steinhardt, Oct 24, 2024
  144. 13/19 Documentation: teach "cmd-list.perl" about out-of-tree buildsPatrick Steinhardt, Oct 24, 2024
  145. 14/19 Documentation: extract script to generate a list of mergetoolsPatrick Steinhardt, Oct 24, 2024
  146. 15/19 t: better support for out-of-tree buildsPatrick Steinhardt, Oct 24, 2024
  147. 16/19 t: allow overriding build dirPatrick Steinhardt, Oct 24, 2024
  148. 17/19 Documentation: add comparison of build systemsPatrick Steinhardt, Oct 24, 2024
  149. 18/19 Introduce support for the Meson build systemPatrick Steinhardt, Oct 24, 2024
  150. 19/19 meson: fix conflicts with in-flight topicsPatrick Steinhardt, Oct 24, 2024
  151. Taylor BlauOct 24, 2024
  152. Taylor BlauOct 25, 2024
  153. Patrick SteinhardtNov 4, 2024
  154. Eli SchwartzNov 4, 2024
  155. Patrick SteinhardtNov 11, 2024
  156. Taylor BlauNov 4, 2024
  157. David AguilarNov 9, 2024
  158. Eli SchwartzNov 10, 2024
  159. Patrick SteinhardtNov 11, 2024
  160. Eli SchwartzNov 11, 2024
  161. Patrick SteinhardtNov 12, 2024
  162. Patrick SteinhardtNov 12, 2024
  163. David AguilarNov 13, 2024
  164. Patrick SteinhardtNov 13, 2024
  165. Eli SchwartzNov 13, 2024
  166. Patrick SteinhardtNov 14, 2024
  167. Junio C HamanoNov 14, 2024
  168. Eli SchwartzNov 14, 2024
  169. Patrick SteinhardtNov 14, 2024
  170. Junio C HamanoNov 14, 2024
  171. Eli SchwartzNov 13, 2024
  172. Patrick SteinhardtNov 14, 2024
  173. Patrick SteinhardtNov 11, 2024
  174. Jeff KingNov 11, 2024
  175. Eli SchwartzNov 11, 2024
  176. Jeff KingNov 11, 2024
  177. Eli SchwartzNov 11, 2024
  178. Jeff KingNov 12, 2024
  179. Eli SchwartzNov 12, 2024
  180. Jeff KingNov 12, 2024
  181. Junio C HamanoNov 12, 2024
  182. Patrick SteinhardtNov 12, 2024
  183. Eli SchwartzNov 12, 2024
  184. Eli SchwartzNov 4, 2024
  185. Ramsay JonesOct 28, 2024
  186. Patrick SteinhardtNov 4, 2024
  187. 00/19 Modernize the build systemPatrick Steinhardt, Nov 11, 2024
  188. 01/19 Makefile: use common template for GIT-BUILD-OPTIONSPatrick Steinhardt, Nov 11, 2024
  189. 02/19 Makefile: consistently use @PLACEHOLDER@ to substitutePatrick Steinhardt, Nov 11, 2024
  190. 03/19 Makefile: consistently use PERL_PATHPatrick Steinhardt, Nov 11, 2024
  191. 04/19 Makefile: extract script to massage Perl scriptsPatrick Steinhardt, Nov 11, 2024
  192. 05/19 Makefile: use "generate-perl.sh" to massage Perl libraryPatrick Steinhardt, Nov 11, 2024
  193. 06/19 Makefile: extract script to massage Shell scriptsPatrick Steinhardt, Nov 11, 2024
  194. 07/19 Makefile: extract script to generate gitweb.cgiPatrick Steinhardt, Nov 11, 2024
  195. 08/19 Makefile: refactor GIT-VERSION-GEN to be reusablePatrick Steinhardt, Nov 11, 2024
  196. 09/19 Makefile: refactor generators to be PWD-independentPatrick Steinhardt, Nov 11, 2024
  197. 10/19 Makefile: allow "bin-wrappers/" directory to existPatrick Steinhardt, Nov 11, 2024
  198. 11/19 Makefile: simplify building of templatesPatrick Steinhardt, Nov 11, 2024
  199. 12/19 Documentation: allow sourcing generated includes from separate dirPatrick Steinhardt, Nov 11, 2024
  200. 13/19 Documentation: teach "cmd-list.perl" about out-of-tree buildsPatrick Steinhardt, Nov 11, 2024
  201. 14/19 Documentation: extract script to generate a list of mergetoolsPatrick Steinhardt, Nov 11, 2024
  202. 15/19 t: better support for out-of-tree buildsPatrick Steinhardt, Nov 11, 2024
  203. 16/19 t: allow overriding build dirPatrick Steinhardt, Nov 11, 2024
  204. 17/19 Documentation: add comparison of build systemsPatrick Steinhardt, Nov 11, 2024
  205. 18/19 Introduce support for the Meson build systemPatrick Steinhardt, Nov 11, 2024
  206. 19/19 meson: fix conflicts with in-flight topicsPatrick Steinhardt, Nov 11, 2024
  207. Ramsay JonesNov 13, 2024
  208. 00/19 Modernize the build systemPatrick Steinhardt, Nov 12, 2024
  209. 01/19 Makefile: use common template for GIT-BUILD-OPTIONSPatrick Steinhardt, Nov 12, 2024
  210. Junio C HamanoNov 13, 2024
  211. Patrick SteinhardtNov 13, 2024
  212. 03/19 Makefile: consistently use PERL_PATHPatrick Steinhardt, Nov 12, 2024
  213. 02/19 Makefile: consistently use @PLACEHOLDER@ to substitutePatrick Steinhardt, Nov 12, 2024
  214. 04/19 Makefile: extract script to massage Perl scriptsPatrick Steinhardt, Nov 12, 2024
  215. 05/19 Makefile: use "generate-perl.sh" to massage Perl libraryPatrick Steinhardt, Nov 12, 2024
  216. 06/19 Makefile: extract script to massage Shell scriptsPatrick Steinhardt, Nov 12, 2024
  217. 07/19 Makefile: extract script to generate gitweb.cgiPatrick Steinhardt, Nov 12, 2024
  218. 08/19 Makefile: refactor GIT-VERSION-GEN to be reusablePatrick Steinhardt, Nov 12, 2024
  219. Phillip WoodNov 13, 2024
  220. Patrick SteinhardtNov 14, 2024
  221. Junio C HamanoNov 14, 2024
  222. 09/19 Makefile: refactor generators to be PWD-independentPatrick Steinhardt, Nov 12, 2024
  223. 10/19 Makefile: allow "bin-wrappers/" directory to existPatrick Steinhardt, Nov 12, 2024
  224. 11/19 Makefile: simplify building of templatesPatrick Steinhardt, Nov 12, 2024
  225. 12/19 Documentation: allow sourcing generated includes from separate dirPatrick Steinhardt, Nov 12, 2024
  226. 13/19 Documentation: teach "cmd-list.perl" about out-of-tree buildsPatrick Steinhardt, Nov 12, 2024
  227. 14/19 Documentation: extract script to generate a list of mergetoolsPatrick Steinhardt, Nov 12, 2024
  228. 15/19 t: better support for out-of-tree buildsPatrick Steinhardt, Nov 12, 2024
  229. 16/19 t: allow overriding build dirPatrick Steinhardt, Nov 12, 2024
  230. 17/19 Documentation: add comparison of build systemsPatrick Steinhardt, Nov 12, 2024
  231. 18/19 Introduce support for the Meson build systemPatrick Steinhardt, Nov 12, 2024
  232. Junio C HamanoNov 13, 2024
  233. Patrick SteinhardtNov 13, 2024
  234. Phillip WoodNov 13, 2024
  235. 19/19 meson: fix conflicts with in-flight topicsPatrick Steinhardt, Nov 12, 2024
  236. Ramsay JonesNov 13, 2024
  237. Patrick SteinhardtNov 13, 2024
  238. Christian CouderNov 13, 2024
  239. Patrick SteinhardtNov 13, 2024
  240. 00/23 Modernize the build systemPatrick Steinhardt, Nov 19, 2024
  241. 02/23 Makefile: consistently use @PLACEHOLDER@ to substitutePatrick Steinhardt, Nov 19, 2024
  242. Johannes SixtNov 19, 2024
  243. Patrick SteinhardtNov 20, 2024
  244. 01/23 Makefile: use common template for GIT-BUILD-OPTIONSPatrick Steinhardt, Nov 19, 2024
  245. 03/23 Makefile: refactor GIT-VERSION-GEN to be reusablePatrick Steinhardt, Nov 19, 2024
  246. Junio C HamanoNov 20, 2024
  247. Patrick SteinhardtNov 20, 2024
  248. Junio C HamanoNov 21, 2024
  249. Patrick SteinhardtNov 25, 2024
  250. 05/23 Makefile: generate "git.rc" via GIT-VERSION-GENPatrick Steinhardt, Nov 19, 2024
  251. 04/23 Makefile: propagate Git version via generated headerPatrick Steinhardt, Nov 19, 2024
  252. 06/23 Makefile: generate doc versions via GIT-VERSION-GENPatrick Steinhardt, Nov 19, 2024
  253. 07/23 Makefile: consistently use PERL_PATHPatrick Steinhardt, Nov 19, 2024
  254. 08/23 Makefile: extract script to massage Perl scriptsPatrick Steinhardt, Nov 19, 2024
  255. 09/23 Makefile: use "generate-perl.sh" to massage Perl libraryPatrick Steinhardt, Nov 19, 2024
  256. 10/23 Makefile: extract script to massage Shell scriptsPatrick Steinhardt, Nov 19, 2024
  257. 11/23 Makefile: extract script to generate gitweb.cgiPatrick Steinhardt, Nov 19, 2024
  258. 12/23 Makefile: extract script to generate gitweb.jsPatrick Steinhardt, Nov 19, 2024
  259. 13/23 Makefile: refactor generators to be PWD-independentPatrick Steinhardt, Nov 19, 2024
  260. 14/23 Makefile: allow "bin-wrappers/" directory to existPatrick Steinhardt, Nov 19, 2024
  261. 15/23 Makefile: simplify building of templatesPatrick Steinhardt, Nov 19, 2024
  262. 16/23 Documentation: allow sourcing generated includes from separate dirPatrick Steinhardt, Nov 19, 2024
  263. 17/23 Documentation: teach "cmd-list.perl" about out-of-tree buildsPatrick Steinhardt, Nov 19, 2024
  264. 18/23 Documentation: extract script to generate a list of mergetoolsPatrick Steinhardt, Nov 19, 2024
  265. 19/23 t: better support for out-of-tree buildsPatrick Steinhardt, Nov 19, 2024
  266. 20/23 t: allow overriding build dirPatrick Steinhardt, Nov 19, 2024
  267. 21/23 Documentation: add comparison of build systemsPatrick Steinhardt, Nov 19, 2024
  268. 23/23 meson: fix conflicts with in-flight topicsPatrick Steinhardt, Nov 19, 2024
  269. 22/23 Introduce support for the Meson build systemPatrick Steinhardt, Nov 19, 2024
  270. Junio C HamanoNov 20, 2024
  271. Patrick SteinhardtNov 20, 2024
  272. 00/23 Modernize the build systemPatrick Steinhardt, Nov 25, 2024
  273. 01/23 Makefile: use common template for GIT-BUILD-OPTIONSPatrick Steinhardt, Nov 25, 2024
  274. 02/23 Makefile: consistently use @PLACEHOLDER@ to substitutePatrick Steinhardt, Nov 25, 2024
  275. 04/23 Makefile: propagate Git version via generated headerPatrick Steinhardt, Nov 25, 2024
  276. 03/23 Makefile: refactor GIT-VERSION-GEN to be reusablePatrick Steinhardt, Nov 25, 2024
  277. 05/23 Makefile: generate "git.rc" via GIT-VERSION-GENPatrick Steinhardt, Nov 25, 2024
  278. 06/23 Makefile: generate doc versions via GIT-VERSION-GENPatrick Steinhardt, Nov 25, 2024
  279. Renato BotelhoJan 13, 2025
  280. Patrick SteinhardtJan 17, 2025
  281. 07/23 Makefile: consistently use PERL_PATHPatrick Steinhardt, Nov 25, 2024
  282. 08/23 Makefile: extract script to massage Perl scriptsPatrick Steinhardt, Nov 25, 2024
  283. 09/23 Makefile: use "generate-perl.sh" to massage Perl libraryPatrick Steinhardt, Nov 25, 2024
  284. 10/23 Makefile: extract script to massage Shell scriptsPatrick Steinhardt, Nov 25, 2024
  285. 11/23 Makefile: extract script to generate gitweb.cgiPatrick Steinhardt, Nov 25, 2024
  286. 12/23 Makefile: extract script to generate gitweb.jsPatrick Steinhardt, Nov 25, 2024
  287. 13/23 Makefile: refactor generators to be PWD-independentPatrick Steinhardt, Nov 25, 2024
  288. 14/23 Makefile: allow "bin-wrappers/" directory to existPatrick Steinhardt, Nov 25, 2024
  289. 15/23 Makefile: simplify building of templatesPatrick Steinhardt, Nov 25, 2024
  290. 16/23 Documentation: allow sourcing generated includes from separate dirPatrick Steinhardt, Nov 25, 2024
  291. 17/23 Documentation: teach "cmd-list.perl" about out-of-tree buildsPatrick Steinhardt, Nov 25, 2024
  292. 18/23 Documentation: extract script to generate a list of mergetoolsPatrick Steinhardt, Nov 25, 2024
  293. 19/23 t: better support for out-of-tree buildsPatrick Steinhardt, Nov 25, 2024
  294. 20/23 t: allow overriding build dirPatrick Steinhardt, Nov 25, 2024
  295. 21/23 Documentation: add comparison of build systemsPatrick Steinhardt, Nov 25, 2024
  296. 23/23 meson: fix conflicts with in-flight topicsPatrick Steinhardt, Nov 25, 2024
  297. 22/23 Introduce support for the Meson build systemPatrick Steinhardt, Nov 25, 2024
  298. 00/23 Modernize the build systemPatrick Steinhardt, Nov 28, 2024
  299. 01/23 Makefile: use common template for GIT-BUILD-OPTIONSPatrick Steinhardt, Nov 28, 2024
  300. 02/23 Makefile: consistently use @PLACEHOLDER@ to substitutePatrick Steinhardt, Nov 28, 2024
  301. 03/23 Makefile: refactor GIT-VERSION-GEN to be reusablePatrick Steinhardt, Nov 28, 2024
  302. 04/23 Makefile: propagate Git version via generated headerPatrick Steinhardt, Nov 28, 2024
  303. 05/23 Makefile: generate "git.rc" via GIT-VERSION-GENPatrick Steinhardt, Nov 28, 2024
  304. 06/23 Makefile: generate doc versions via GIT-VERSION-GENPatrick Steinhardt, Nov 28, 2024
  305. 07/23 Makefile: consistently use PERL_PATHPatrick Steinhardt, Nov 28, 2024
  306. 08/23 Makefile: extract script to massage Perl scriptsPatrick Steinhardt, Nov 28, 2024
  307. 10/23 Makefile: extract script to massage Shell scriptsPatrick Steinhardt, Nov 28, 2024
  308. 11/23 Makefile: extract script to generate gitweb.cgiPatrick Steinhardt, Nov 28, 2024
  309. 09/23 Makefile: use "generate-perl.sh" to massage Perl libraryPatrick Steinhardt, Nov 28, 2024
  310. 14/23 Makefile: allow "bin-wrappers/" directory to existPatrick Steinhardt, Nov 28, 2024
  311. 12/23 Makefile: extract script to generate gitweb.jsPatrick Steinhardt, Nov 28, 2024
  312. 13/23 Makefile: refactor generators to be PWD-independentPatrick Steinhardt, Nov 28, 2024
  313. 15/23 Makefile: simplify building of templatesPatrick Steinhardt, Nov 28, 2024
  314. 17/23 Documentation: teach "cmd-list.perl" about out-of-tree buildsPatrick Steinhardt, Nov 28, 2024
  315. 16/23 Documentation: allow sourcing generated includes from separate dirPatrick Steinhardt, Nov 28, 2024
  316. 18/23 Documentation: extract script to generate a list of mergetoolsPatrick Steinhardt, Nov 28, 2024
  317. 19/23 t: better support for out-of-tree buildsPatrick Steinhardt, Nov 28, 2024
  318. 20/23 t: allow overriding build dirPatrick Steinhardt, Nov 28, 2024
  319. 21/23 Documentation: add comparison of build systemsPatrick Steinhardt, Nov 28, 2024
  320. 23/23 meson: fix conflicts with in-flight topicsPatrick Steinhardt, Nov 28, 2024
  321. 22/23 Introduce support for the Meson build systemPatrick Steinhardt, Nov 28, 2024
  322. 00/26 Modernize the build systemPatrick Steinhardt, Dec 6, 2024
  323. 01/26 Makefile: use common template for GIT-BUILD-OPTIONSPatrick Steinhardt, Dec 6, 2024
  324. 02/26 Makefile: consistently use @PLACEHOLDER@ to substitutePatrick Steinhardt, Dec 6, 2024
  325. 03/26 Makefile: refactor GIT-VERSION-GEN to be reusablePatrick Steinhardt, Dec 6, 2024
  326. 04/26 Makefile: propagate Git version via generated headerPatrick Steinhardt, Dec 6, 2024
  327. 05/26 Makefile: generate "git.rc" via GIT-VERSION-GENPatrick Steinhardt, Dec 6, 2024
  328. 06/26 Makefile: generate doc versions via GIT-VERSION-GENPatrick Steinhardt, Dec 6, 2024
  329. 07/26 Makefile: consistently use PERL_PATHPatrick Steinhardt, Dec 6, 2024
  330. 08/26 Makefile: extract script to massage Perl scriptsPatrick Steinhardt, Dec 6, 2024
  331. 09/26 Makefile: use "generate-perl.sh" to massage Perl libraryPatrick Steinhardt, Dec 6, 2024
  332. 11/26 Makefile: extract script to massage Python scriptsPatrick Steinhardt, Dec 6, 2024
  333. 10/26 Makefile: extract script to massage Shell scriptsPatrick Steinhardt, Dec 6, 2024
  334. 12/26 Makefile: extract script to generate gitweb.cgiPatrick Steinhardt, Dec 6, 2024
  335. 13/26 Makefile: extract script to generate gitweb.jsPatrick Steinhardt, Dec 6, 2024
  336. 14/26 Makefile: refactor generators to be PWD-independentPatrick Steinhardt, Dec 6, 2024
  337. 15/26 Makefile: allow "bin-wrappers/" directory to existPatrick Steinhardt, Dec 6, 2024
  338. 16/26 Makefile: write absolute program path into bin-wrappersPatrick Steinhardt, Dec 6, 2024
  339. 17/26 Makefile: simplify building of templatesPatrick Steinhardt, Dec 6, 2024
  340. 18/26 Documentation: allow sourcing generated includes from separate dirPatrick Steinhardt, Dec 6, 2024
  341. 19/26 Documentation: teach "cmd-list.perl" about out-of-tree buildsPatrick Steinhardt, Dec 6, 2024
  342. 20/26 Documentation: extract script to generate a list of mergetoolsPatrick Steinhardt, Dec 6, 2024
  343. 21/26 t: better support for out-of-tree buildsPatrick Steinhardt, Dec 6, 2024
  344. 22/26 t: allow overriding build dirPatrick Steinhardt, Dec 6, 2024
  345. 23/26 Documentation: add comparison of build systemsPatrick Steinhardt, Dec 6, 2024
  346. 24/26 Introduce support for the Meson build systemPatrick Steinhardt, Dec 6, 2024
  347. 25/26 meson: fix conflicts with in-flight topicsPatrick Steinhardt, Dec 6, 2024
  348. Junio C HamanoDec 8, 2024
  349. Junio C HamanoDec 9, 2024
  350. Patrick SteinhardtDec 9, 2024
  351. Junio C HamanoDec 9, 2024
  352. Patrick SteinhardtDec 10, 2024
  353. Junio C HamanoDec 10, 2024
  354. 26/26 Revert "meson: fix conflicts with in-flight topics"Patrick Steinhardt, Dec 6, 2024
  355. Patrick SteinhardtDec 6, 2024

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.