diff --git a/Documentation/howto/meson.build b/Documentation/howto/meson.build
new file mode 100644
index 0000000000000000000000000000000000000000..c023c104161e61ca0399b5390d59e20343746621
--- /dev/null
+++ b/Documentation/howto/meson.build
@@ -0,0 +1,62 @@
+howto_sources = [
+  'coordinate-embargoed-releases.txt',
+  'keep-canonical-history-correct.txt',
+  'maintain-git.txt',
+  'new-command.txt',
+  'rebase-from-internal-branch.txt',
+  'rebuild-from-update-hook.txt',
+  'recover-corrupted-blob-object.txt',
+  'recover-corrupted-object-harder.txt',
+  'revert-a-faulty-merge.txt',
+  'revert-branch-rebase.txt',
+  'separating-topic-branches.txt',
+  'setup-git-server-over-http.txt',
+  'update-hook-example.txt',
+  'use-git-daemon.txt',
+  'using-merge-subtree.txt',
+  'using-signed-tag-in-pull-request.txt',
+]
+
+howto_index = custom_target(
+  command: [
+    shell,
+    meson.current_source_dir() / 'howto-index.sh',
+    '@INPUT@',
+  ],
+  env: script_environment,
+  capture: true,
+  input: howto_sources,
+  output: 'howto-index.txt',
+)
+
+custom_target(
+  command: asciidoc_html_options,
+  input: howto_index,
+  output: 'howto-index.html',
+  depends: documentation_deps,
+  install: true,
+  install_dir: get_option('datadir') / 'doc/git-doc',
+)
+
+foreach howto : howto_sources
+  howto_stripped = custom_target(
+    command: [
+      find_program('sed'),
+      '-e',
+      '1,/^$/d',
+      '@INPUT@',
+    ],
+    input: howto,
+    output: fs.stem(howto) + '.stripped',
+    capture: true,
+  )
+
+  custom_target(
+    command: asciidoc_html_options,
+    input: howto_stripped,
+    output: fs.stem(howto_stripped.full_path()) + '.html',
+    depends: documentation_deps,
+    install: true,
+    install_dir: get_option('datadir') / 'doc/git-doc/howto',
+  )
+endforeach
diff --git a/Documentation/meson.build b/Documentation/meson.build
index 404cb20d10a2fbbe4e014bd8a7df74c49dad40a7..8c6ff0bce1206d988cc0d3b7997fa0f338d01194 100644
--- a/Documentation/meson.build
+++ b/Documentation/meson.build
@@ -413,4 +413,40 @@ if get_option('docs').contains('html')
     install: true,
     install_dir: get_option('datadir') / 'doc/git-doc',
   )
+
+  articles = [
+    'DecisionMaking.txt',
+    'MyFirstContribution.txt',
+    'MyFirstObjectWalk.txt',
+    'ReviewingGuidelines.txt',
+    'SubmittingPatches',
+    'ToolsForGit.txt',
+    'git-bisect-lk2009.txt',
+    'git-tools.txt',
+  ]
+
+  foreach article : articles
+    custom_target(
+      command: asciidoc_common_options + [
+        '--backend=' + asciidoc_html,
+        '--out-file=@OUTPUT@',
+        '@INPUT@',
+      ],
+      input: article,
+      output: fs.stem(article) + '.html',
+      depends: documentation_deps,
+      install: true,
+      install_dir: get_option('datadir') / 'doc/git-doc',
+    )
+  endforeach
+
+  asciidoc_html_options = asciidoc_common_options + [
+    '--backend=' + asciidoc_html,
+    '--out-file=@OUTPUT@',
+    '--attribute', 'git-relative-html-prefix=../',
+    '@INPUT@',
+  ]
+
+  subdir('howto')
+  subdir('technical')
 endif
diff --git a/Documentation/technical/meson.build b/Documentation/technical/meson.build
new file mode 100644
index 0000000000000000000000000000000000000000..21dfb8b5c9d93490f16c24bab1d49631e0395571
--- /dev/null
+++ b/Documentation/technical/meson.build
@@ -0,0 +1,66 @@
+api_docs = [
+  'api-error-handling.txt',
+  'api-merge.txt',
+  'api-parse-options.txt',
+  'api-simple-ipc.txt',
+  'api-trace2.txt',
+]
+
+articles = [
+  'bitmap-format.txt',
+  'build-systems.txt',
+  'bundle-uri.txt',
+  'commit-graph.txt',
+  'directory-rename-detection.txt',
+  'hash-function-transition.txt',
+  'long-running-process-protocol.txt',
+  'multi-pack-index.txt',
+  'packfile-uri.txt',
+  'pack-heuristics.txt',
+  'parallel-checkout.txt',
+  'partial-clone.txt',
+  'platform-support.txt',
+  'racy-git.txt',
+  'reftable.txt',
+  'remembering-renames.txt',
+  'repository-version.txt',
+  'rerere.txt',
+  'scalar.txt',
+  'send-pack-pipeline.txt',
+  'shallow.txt',
+  'sparse-checkout.txt',
+  'sparse-index.txt',
+  'trivial-merge.txt',
+  'unit-tests.txt',
+]
+
+api_index = custom_target(
+  command: [
+    shell,
+    meson.current_source_dir() / 'api-index.sh',
+    meson.current_source_dir(),
+    '@OUTPUT@',
+  ],
+  env: script_environment,
+  input: api_docs,
+  output: 'api-index.txt',
+)
+
+custom_target(
+  command: asciidoc_html_options,
+  input: api_index,
+  output: 'api-index.html',
+  depends: documentation_deps,
+  install: true,
+  install_dir: get_option('datadir') / 'doc/git-doc/technical',
+)
+
+foreach article : api_docs + articles
+  custom_target(
+    command: asciidoc_html_options,
+    input: article,
+    output: fs.stem(article) + '.html',
+    install: true,
+    install_dir: get_option('datadir') / 'doc/git-doc/technical',
+  )
+endforeach
