git-nested 1.2.0__tar.gz → 1.2.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (202) hide show
  1. {git_nested-1.2.0 → git_nested-1.2.2}/.github/workflows/docs.yml +12 -6
  2. {git_nested-1.2.0 → git_nested-1.2.2}/.github/workflows/publish.yml +1 -1
  3. {git_nested-1.2.0 → git_nested-1.2.2}/.github/workflows/test-binary.yml +1 -1
  4. {git_nested-1.2.0 → git_nested-1.2.2}/.github/workflows/test.yml +33 -2
  5. {git_nested-1.2.0/src/git_nested.egg-info → git_nested-1.2.2}/PKG-INFO +13 -2
  6. {git_nested-1.2.0 → git_nested-1.2.2}/README.md +11 -0
  7. {git_nested-1.2.0 → git_nested-1.2.2}/doc/README.md +2 -0
  8. {git_nested-1.2.0 → git_nested-1.2.2}/doc/_static/custom.css +9 -0
  9. git_nested-1.2.2/doc/_static/favicon.svg +29 -0
  10. git_nested-1.2.2/doc/_static/logo.svg +30 -0
  11. {git_nested-1.2.0 → git_nested-1.2.2}/doc/architecture/diagrams.md +234 -9
  12. {git_nested-1.2.0 → git_nested-1.2.2}/doc/architecture/index.md +3 -1
  13. {git_nested-1.2.0 → git_nested-1.2.2}/doc/cli/branch.md +11 -0
  14. {git_nested-1.2.0 → git_nested-1.2.2}/doc/cli/clone.md +8 -0
  15. {git_nested-1.2.0 → git_nested-1.2.2}/doc/cli/commit.md +4 -0
  16. {git_nested-1.2.0 → git_nested-1.2.2}/doc/cli/config.md +6 -2
  17. {git_nested-1.2.0 → git_nested-1.2.2}/doc/cli/index.md +5 -1
  18. {git_nested-1.2.0 → git_nested-1.2.2}/doc/cli/init.md +1 -0
  19. git_nested-1.2.2/doc/cli/patches.md +113 -0
  20. {git_nested-1.2.0 → git_nested-1.2.2}/doc/cli/pull.md +33 -4
  21. {git_nested-1.2.0 → git_nested-1.2.2}/doc/cli/push.md +12 -0
  22. git_nested-1.2.2/doc/cli/submodules.md +242 -0
  23. git_nested-1.2.2/doc/cli/verify.md +86 -0
  24. {git_nested-1.2.0 → git_nested-1.2.2}/doc/concepts/comparison.md +2 -1
  25. {git_nested-1.2.0 → git_nested-1.2.2}/doc/concepts/glossary.md +1 -1
  26. {git_nested-1.2.0 → git_nested-1.2.2}/doc/conf.py +4 -0
  27. git_nested-1.2.2/doc/configuration/examples.md +259 -0
  28. {git_nested-1.2.0 → git_nested-1.2.2}/doc/configuration/git-config.md +11 -0
  29. {git_nested-1.2.0 → git_nested-1.2.2}/doc/configuration/gitnested-file.md +85 -1
  30. {git_nested-1.2.0 → git_nested-1.2.2}/doc/contributing/documentation.md +3 -0
  31. {git_nested-1.2.0 → git_nested-1.2.2}/doc/guides/conflicts.md +5 -0
  32. git_nested-1.2.2/doc/guides/patches.md +261 -0
  33. {git_nested-1.2.0 → git_nested-1.2.2}/doc/guides/pin.md +9 -0
  34. git_nested-1.2.2/doc/guides/submodules.md +91 -0
  35. {git_nested-1.2.0 → git_nested-1.2.2}/doc/index.md +12 -0
  36. {git_nested-1.2.0 → git_nested-1.2.2}/doc/introduction/index.md +2 -0
  37. {git_nested-1.2.0 → git_nested-1.2.2}/doc/introduction/install.md +17 -0
  38. {git_nested-1.2.0 → git_nested-1.2.2}/man/man1/git-nested.1 +9 -0
  39. {git_nested-1.2.0 → git_nested-1.2.2}/pyproject.toml +34 -3
  40. {git_nested-1.2.0 → git_nested-1.2.2}/src/git_nested/checks.py +21 -8
  41. {git_nested-1.2.0 → git_nested-1.2.2}/src/git_nested/cli/location.py +17 -1
  42. {git_nested-1.2.0 → git_nested-1.2.2}/src/git_nested/cli/parser.py +69 -2
  43. {git_nested-1.2.0 → git_nested-1.2.2}/src/git_nested/cli/setup.py +8 -3
  44. {git_nested-1.2.0 → git_nested-1.2.2}/src/git_nested/cli/spec.py +190 -4
  45. {git_nested-1.2.0 → git_nested-1.2.2}/src/git_nested/commands/__init__.py +6 -0
  46. {git_nested-1.2.0 → git_nested-1.2.2}/src/git_nested/commands/branch.py +34 -2
  47. {git_nested-1.2.0 → git_nested-1.2.2}/src/git_nested/commands/clean.py +1 -1
  48. {git_nested-1.2.0 → git_nested-1.2.2}/src/git_nested/commands/clone.py +53 -15
  49. {git_nested-1.2.0 → git_nested-1.2.2}/src/git_nested/commands/commit.py +8 -4
  50. {git_nested-1.2.0 → git_nested-1.2.2}/src/git_nested/commands/config.py +5 -4
  51. {git_nested-1.2.0 → git_nested-1.2.2}/src/git_nested/commands/diff.py +3 -1
  52. {git_nested-1.2.0 → git_nested-1.2.2}/src/git_nested/commands/init.py +7 -4
  53. git_nested-1.2.2/src/git_nested/commands/patchset.py +222 -0
  54. {git_nested-1.2.0 → git_nested-1.2.2}/src/git_nested/commands/pull.py +132 -9
  55. {git_nested-1.2.0 → git_nested-1.2.2}/src/git_nested/commands/push.py +55 -5
  56. {git_nested-1.2.0 → git_nested-1.2.2}/src/git_nested/commands/status.py +4 -2
  57. git_nested-1.2.2/src/git_nested/commands/submodules.py +885 -0
  58. git_nested-1.2.2/src/git_nested/commands/verify.py +153 -0
  59. git_nested-1.2.2/src/git_nested/configio.py +91 -0
  60. git_nested-1.2.2/src/git_nested/content.py +304 -0
  61. {git_nested-1.2.0 → git_nested-1.2.2}/src/git_nested/discovery.py +1 -1
  62. {git_nested-1.2.0 → git_nested-1.2.2}/src/git_nested/filters.py +48 -0
  63. {git_nested-1.2.0 → git_nested-1.2.2}/src/git_nested/git.py +19 -2
  64. {git_nested-1.2.0 → git_nested-1.2.2}/src/git_nested/gitfile.py +23 -8
  65. {git_nested-1.2.0 → git_nested-1.2.2}/src/git_nested/history.py +83 -12
  66. {git_nested-1.2.0 → git_nested-1.2.2}/src/git_nested/messages.py +9 -7
  67. {git_nested-1.2.0 → git_nested-1.2.2}/src/git_nested/models.py +63 -4
  68. git_nested-1.2.2/src/git_nested/patchbuild.py +128 -0
  69. git_nested-1.2.2/src/git_nested/patches.py +300 -0
  70. git_nested-1.2.2/src/git_nested/patchpick.py +55 -0
  71. {git_nested-1.2.0 → git_nested-1.2.2}/src/git_nested/refs.py +11 -6
  72. {git_nested-1.2.0 → git_nested-1.2.2}/src/git_nested/submodules.py +29 -7
  73. {git_nested-1.2.0 → git_nested-1.2.2}/src/git_nested/worktree.py +15 -0
  74. {git_nested-1.2.0 → git_nested-1.2.2/src/git_nested.egg-info}/PKG-INFO +13 -2
  75. {git_nested-1.2.0 → git_nested-1.2.2}/src/git_nested.egg-info/SOURCES.txt +23 -1
  76. {git_nested-1.2.0 → git_nested-1.2.2}/src/git_nested.egg-info/scm_file_list.json +23 -1
  77. git_nested-1.2.2/src/git_nested.egg-info/scm_version.json +8 -0
  78. {git_nested-1.2.0 → git_nested-1.2.2}/tests/conftest.py +78 -36
  79. {git_nested-1.2.0 → git_nested-1.2.2}/tests/e2e/scenarios/test_extraction.py +3 -3
  80. git_nested-1.2.2/tests/e2e/test_attributes.py +68 -0
  81. {git_nested-1.2.0 → git_nested-1.2.2}/tests/e2e/test_diff.py +2 -2
  82. {git_nested-1.2.0 → git_nested-1.2.2}/tests/e2e/test_error.py +2 -2
  83. git_nested-1.2.2/tests/e2e/test_ignore.py +149 -0
  84. git_nested-1.2.2/tests/e2e/test_issue_184.py +364 -0
  85. git_nested-1.2.2/tests/e2e/test_patches.py +1113 -0
  86. git_nested-1.2.2/tests/e2e/test_pin.py +142 -0
  87. {git_nested-1.2.0 → git_nested-1.2.2}/tests/e2e/test_pull.py +48 -7
  88. {git_nested-1.2.0 → git_nested-1.2.2}/tests/e2e/test_push.py +2 -2
  89. {git_nested-1.2.0 → git_nested-1.2.2}/tests/e2e/test_rebase.py +1 -1
  90. {git_nested-1.2.0 → git_nested-1.2.2}/tests/e2e/test_signing.py +4 -1
  91. git_nested-1.2.2/tests/e2e/test_submodules.py +264 -0
  92. git_nested-1.2.2/tests/e2e/test_submodules_command.py +1483 -0
  93. git_nested-1.2.2/tests/e2e/test_submodules_contribute.py +196 -0
  94. git_nested-1.2.2/tests/e2e/test_toml.py +55 -0
  95. git_nested-1.2.2/tests/e2e/test_verify.py +276 -0
  96. {git_nested-1.2.0 → git_nested-1.2.2}/tests/e2e/test_version.py +7 -1
  97. {git_nested-1.2.0 → git_nested-1.2.2}/tests/unit/test_command.py +32 -0
  98. {git_nested-1.2.0 → git_nested-1.2.2}/tests/unit/test_completion_engine.py +2 -2
  99. git_nested-1.2.2/tests/unit/test_configio.py +108 -0
  100. {git_nested-1.2.0 → git_nested-1.2.2}/tests/unit/test_helpers.py +54 -6
  101. {git_nested-1.2.0 → git_nested-1.2.2}/tests/unit/test_repo_business.py +4 -12
  102. {git_nested-1.2.0 → git_nested-1.2.2}/uv.lock +261 -259
  103. git_nested-1.2.0/doc/guides/submodules.md +0 -49
  104. git_nested-1.2.0/src/git_nested/content.py +0 -162
  105. git_nested-1.2.0/src/git_nested/yamlio.py +0 -25
  106. git_nested-1.2.0/src/git_nested.egg-info/scm_version.json +0 -8
  107. git_nested-1.2.0/tests/e2e/test_pin.py +0 -51
  108. git_nested-1.2.0/tests/e2e/test_submodules.py +0 -123
  109. {git_nested-1.2.0 → git_nested-1.2.2}/.codecov.yml +0 -0
  110. {git_nested-1.2.0 → git_nested-1.2.2}/.fish.rc +0 -0
  111. {git_nested-1.2.0 → git_nested-1.2.2}/.gitattributes +0 -0
  112. {git_nested-1.2.0 → git_nested-1.2.2}/.github/CODEOWNERS +0 -0
  113. {git_nested-1.2.0 → git_nested-1.2.2}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  114. {git_nested-1.2.0 → git_nested-1.2.2}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  115. {git_nested-1.2.0 → git_nested-1.2.2}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  116. {git_nested-1.2.0 → git_nested-1.2.2}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  117. {git_nested-1.2.0 → git_nested-1.2.2}/.github/dependabot.yml +0 -0
  118. {git_nested-1.2.0 → git_nested-1.2.2}/.github/release.yml +0 -0
  119. {git_nested-1.2.0 → git_nested-1.2.2}/.github/workflows/build-binary.yml +0 -0
  120. {git_nested-1.2.0 → git_nested-1.2.2}/.github/workflows/prune-artifacts.yml +0 -0
  121. {git_nested-1.2.0 → git_nested-1.2.2}/.github/workflows/release-binary.yml +0 -0
  122. {git_nested-1.2.0 → git_nested-1.2.2}/.gitignore +0 -0
  123. {git_nested-1.2.0 → git_nested-1.2.2}/.pre-commit-config.yaml +0 -0
  124. {git_nested-1.2.0 → git_nested-1.2.2}/.rc +0 -0
  125. {git_nested-1.2.0 → git_nested-1.2.2}/CONTRIBUTING.md +0 -0
  126. {git_nested-1.2.0 → git_nested-1.2.2}/LICENSE +0 -0
  127. {git_nested-1.2.0 → git_nested-1.2.2}/SECURITY.md +0 -0
  128. {git_nested-1.2.0 → git_nested-1.2.2}/bin/git-nested +0 -0
  129. {git_nested-1.2.0 → git_nested-1.2.2}/doc/_static/custom.js +0 -0
  130. {git_nested-1.2.0 → git_nested-1.2.2}/doc/_templates/layout.html +0 -0
  131. {git_nested-1.2.0 → git_nested-1.2.2}/doc/cli/clean.md +0 -0
  132. {git_nested-1.2.0 → git_nested-1.2.2}/doc/cli/completion.md +0 -0
  133. {git_nested-1.2.0 → git_nested-1.2.2}/doc/cli/diff.md +0 -0
  134. {git_nested-1.2.0 → git_nested-1.2.2}/doc/cli/environment-variables.md +0 -0
  135. {git_nested-1.2.0 → git_nested-1.2.2}/doc/cli/fetch.md +0 -0
  136. {git_nested-1.2.0 → git_nested-1.2.2}/doc/cli/repair.md +0 -0
  137. {git_nested-1.2.0 → git_nested-1.2.2}/doc/cli/run.md +0 -0
  138. {git_nested-1.2.0 → git_nested-1.2.2}/doc/cli/status.md +0 -0
  139. {git_nested-1.2.0 → git_nested-1.2.2}/doc/cli/version.md +0 -0
  140. {git_nested-1.2.0 → git_nested-1.2.2}/doc/concepts/how-it-works.md +0 -0
  141. {git_nested-1.2.0 → git_nested-1.2.2}/doc/contributing/development.md +0 -0
  142. {git_nested-1.2.0 → git_nested-1.2.2}/doc/guides/adopt.md +0 -0
  143. {git_nested-1.2.0 → git_nested-1.2.2}/doc/guides/hooks-and-signing.md +0 -0
  144. {git_nested-1.2.0 → git_nested-1.2.2}/doc/guides/many.md +0 -0
  145. {git_nested-1.2.0 → git_nested-1.2.2}/doc/guides/nested-in-nested.md +0 -0
  146. {git_nested-1.2.0 → git_nested-1.2.2}/doc/guides/partial.md +0 -0
  147. {git_nested-1.2.0 → git_nested-1.2.2}/doc/guides/squash-merges.md +0 -0
  148. {git_nested-1.2.0 → git_nested-1.2.2}/doc/quickstart/05-minutes.md +0 -0
  149. {git_nested-1.2.0 → git_nested-1.2.2}/doc/quickstart/everyday.md +0 -0
  150. {git_nested-1.2.0 → git_nested-1.2.2}/scripts/create-python-exe.sh +0 -0
  151. {git_nested-1.2.0 → git_nested-1.2.2}/setup.cfg +0 -0
  152. {git_nested-1.2.0 → git_nested-1.2.2}/sonar-project.properties +0 -0
  153. {git_nested-1.2.0 → git_nested-1.2.2}/src/git_nested/__init__.py +0 -0
  154. {git_nested-1.2.0 → git_nested-1.2.2}/src/git_nested/__main__.py +0 -0
  155. {git_nested-1.2.0 → git_nested-1.2.2}/src/git_nested/_compat.py +0 -0
  156. {git_nested-1.2.0 → git_nested-1.2.2}/src/git_nested/_version.py +0 -0
  157. {git_nested-1.2.0 → git_nested-1.2.2}/src/git_nested/cli/__init__.py +0 -0
  158. {git_nested-1.2.0 → git_nested-1.2.2}/src/git_nested/cli/app.py +0 -0
  159. {git_nested-1.2.0 → git_nested-1.2.2}/src/git_nested/cli/main.py +0 -0
  160. {git_nested-1.2.0 → git_nested-1.2.2}/src/git_nested/commands/completion.py +0 -0
  161. {git_nested-1.2.0 → git_nested-1.2.2}/src/git_nested/commands/fetch.py +0 -0
  162. {git_nested-1.2.0 → git_nested-1.2.2}/src/git_nested/commands/repair.py +0 -0
  163. {git_nested-1.2.0 → git_nested-1.2.2}/src/git_nested/commands/run.py +0 -0
  164. {git_nested-1.2.0 → git_nested-1.2.2}/src/git_nested/commands/version.py +0 -0
  165. {git_nested-1.2.0 → git_nested-1.2.2}/src/git_nested/completion/__init__.py +0 -0
  166. {git_nested-1.2.0 → git_nested-1.2.2}/src/git_nested/completion/scripts.py +0 -0
  167. {git_nested-1.2.0 → git_nested-1.2.2}/src/git_nested/constants.py +0 -0
  168. {git_nested-1.2.0 → git_nested-1.2.2}/src/git_nested/errors.py +0 -0
  169. {git_nested-1.2.0 → git_nested-1.2.2}/src/git_nested/output.py +0 -0
  170. {git_nested-1.2.0 → git_nested-1.2.2}/src/git_nested/py.typed +0 -0
  171. {git_nested-1.2.0 → git_nested-1.2.2}/src/git_nested.egg-info/dependency_links.txt +0 -0
  172. {git_nested-1.2.0 → git_nested-1.2.2}/src/git_nested.egg-info/entry_points.txt +0 -0
  173. {git_nested-1.2.0 → git_nested-1.2.2}/src/git_nested.egg-info/requires.txt +0 -0
  174. {git_nested-1.2.0 → git_nested-1.2.2}/src/git_nested.egg-info/top_level.txt +0 -0
  175. {git_nested-1.2.0 → git_nested-1.2.2}/tests/e2e/scenarios/test_filemode.py +0 -0
  176. {git_nested-1.2.0 → git_nested-1.2.2}/tests/e2e/scenarios/test_filter.py +0 -0
  177. {git_nested-1.2.0 → git_nested-1.2.2}/tests/e2e/test_branch.py +0 -0
  178. {git_nested-1.2.0 → git_nested-1.2.2}/tests/e2e/test_clean.py +0 -0
  179. {git_nested-1.2.0 → git_nested-1.2.2}/tests/e2e/test_clone.py +0 -0
  180. {git_nested-1.2.0 → git_nested-1.2.2}/tests/e2e/test_commit.py +0 -0
  181. {git_nested-1.2.0 → git_nested-1.2.2}/tests/e2e/test_completion.py +0 -0
  182. {git_nested-1.2.0 → git_nested-1.2.2}/tests/e2e/test_config.py +0 -0
  183. {git_nested-1.2.0 → git_nested-1.2.2}/tests/e2e/test_detached.py +0 -0
  184. {git_nested-1.2.0 → git_nested-1.2.2}/tests/e2e/test_encode.py +0 -0
  185. {git_nested-1.2.0 → git_nested-1.2.2}/tests/e2e/test_exclude.py +0 -0
  186. {git_nested-1.2.0 → git_nested-1.2.2}/tests/e2e/test_fetch.py +0 -0
  187. {git_nested-1.2.0 → git_nested-1.2.2}/tests/e2e/test_gitignore.py +0 -0
  188. {git_nested-1.2.0 → git_nested-1.2.2}/tests/e2e/test_init.py +0 -0
  189. {git_nested-1.2.0 → git_nested-1.2.2}/tests/e2e/test_nested_in_nested.py +0 -0
  190. {git_nested-1.2.0 → git_nested-1.2.2}/tests/e2e/test_non_ascii.py +0 -0
  191. {git_nested-1.2.0 → git_nested-1.2.2}/tests/e2e/test_reclone.py +0 -0
  192. {git_nested-1.2.0 → git_nested-1.2.2}/tests/e2e/test_repair.py +0 -0
  193. {git_nested-1.2.0 → git_nested-1.2.2}/tests/e2e/test_run.py +0 -0
  194. {git_nested-1.2.0 → git_nested-1.2.2}/tests/e2e/test_status.py +0 -0
  195. {git_nested-1.2.0 → git_nested-1.2.2}/tests/e2e/test_subdirectory.py +0 -0
  196. {git_nested-1.2.0 → git_nested-1.2.2}/tests/e2e/test_submodule.py +0 -0
  197. {git_nested-1.2.0 → git_nested-1.2.2}/tests/e2e/test_upstream_path.py +0 -0
  198. {git_nested-1.2.0 → git_nested-1.2.2}/tests/unit/conftest.py +0 -0
  199. {git_nested-1.2.0 → git_nested-1.2.2}/tests/unit/fakes.py +0 -0
  200. {git_nested-1.2.0 → git_nested-1.2.2}/tests/unit/test_adopt.py +0 -0
  201. {git_nested-1.2.0 → git_nested-1.2.2}/tests/unit/test_docs.py +0 -0
  202. {git_nested-1.2.0 → git_nested-1.2.2}/tests/unit/test_logging.py +0 -0
@@ -1,11 +1,13 @@
1
1
  name: Docs
2
2
 
3
3
  # Builds doc/ (see doc/conf.py) with Sphinx. On pull requests it only
4
- # builds, so a broken page fails the check. On main it also publishes the
5
- # site to the gh_pages branch, which GitHub Pages serves.
4
+ # builds, so a broken page fails the check. On main and on a release tag it
5
+ # also publishes the site to the gh_pages branch, which GitHub Pages serves.
6
+ # A tag build shows the release version.
6
7
  on:
7
8
  push:
8
9
  branches: [main]
10
+ tags: ['*.*.*']
9
11
  pull_request:
10
12
  branches: ['**']
11
13
  # by hand: 'Run workflow' in the Actions tab, or `gh workflow run docs.yml`
@@ -25,7 +27,7 @@ jobs:
25
27
  # doc/conf.py shows the version from `git describe`, which needs the tags.
26
28
  fetch-depth: 0
27
29
  - name: Install uv
28
- uses: astral-sh/setup-uv@v10.3.0
30
+ uses: astral-sh/setup-uv@v10.3.3
29
31
  with:
30
32
  python-version: '3.14'
31
33
  enable-cache: true
@@ -34,7 +36,7 @@ jobs:
34
36
  - name: Build docs
35
37
  run: uv run poe docs
36
38
  - name: Upload docs
37
- if: github.event_name != 'pull_request' && github.ref == 'refs/heads/main'
39
+ if: github.event_name != 'pull_request' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/'))
38
40
  uses: actions/upload-artifact@v7
39
41
  with:
40
42
  name: docs-html
@@ -42,10 +44,14 @@ jobs:
42
44
  include-hidden-files: true
43
45
 
44
46
  # A job of its own, so only this one can write to the repository.
45
- # Only main is published, also when the workflow is started by hand.
47
+ # Only main and tags are published, also when the workflow is started by hand.
46
48
  publish:
47
- if: github.event_name != 'pull_request' && github.ref == 'refs/heads/main'
49
+ if: github.event_name != 'pull_request' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/'))
48
50
  needs: build
51
+ # One publish at a time: a tag and main are often pushed together.
52
+ concurrency:
53
+ group: gh-pages
54
+ cancel-in-progress: false
49
55
  runs-on: ubuntu-26.04
50
56
  permissions:
51
57
  contents: write
@@ -13,7 +13,7 @@ jobs:
13
13
  with:
14
14
  fetch-depth: 0
15
15
  - name: Install uv
16
- uses: astral-sh/setup-uv@v10.3.0
16
+ uses: astral-sh/setup-uv@v10.3.3
17
17
  with:
18
18
  python-version: '3.13'
19
19
  enable-cache: true
@@ -38,7 +38,7 @@ jobs:
38
38
  # tags of this checkout.
39
39
 
40
40
  - name: Install uv
41
- uses: astral-sh/setup-uv@v10.3.0
41
+ uses: astral-sh/setup-uv@v10.3.3
42
42
  with:
43
43
  python-version: '3.13'
44
44
  enable-cache: true
@@ -5,6 +5,15 @@ on:
5
5
  branches: [main]
6
6
  pull_request:
7
7
  branches: ['**']
8
+ # daily on main (scheduled runs always use the default branch), so a
9
+ # breaking change in a dependency, runner image or upstream download shows
10
+ # up even on a day without any commit
11
+ schedule:
12
+ - cron: '0 18 * * *'
13
+ timezone: Europe/Berlin
14
+ # by hand for any branch: 'Run workflow' in the Actions tab, or
15
+ # `gh workflow run test.yml --ref <branch>`
16
+ workflow_dispatch:
8
17
 
9
18
  # One run per branch/PR at a time. On a PR a newer push cancels the run in
10
19
  # progress: only the newest commit's results matter there, and waiting for a
@@ -68,7 +77,8 @@ jobs:
68
77
  fail-fast: false
69
78
  matrix:
70
79
  os: [ubuntu-26.04, macos-latest, windows-latest]
71
- python-version: ['3.10', '3.11', '3.12', '3.13', '3.14']
80
+ # A PR runs only the oldest and newest Python. main runs all of them.
81
+ python-version: ${{ fromJSON(github.event_name == 'pull_request' && '["3.10", "3.14"]' || '["3.10", "3.11", "3.12", "3.13", "3.14"]') }}
72
82
 
73
83
  steps:
74
84
  - name: Checkout code
@@ -78,8 +88,29 @@ jobs:
78
88
  # authorship) needs real history, not the default shallow, tagless
79
89
  # checkout.
80
90
  fetch-depth: 0
91
+ # The tests start many git processes and write many small files.
92
+ # On Windows, Defender scans each one, which makes the tests slow.
93
+ - name: Turn off Defender scanning
94
+ if: runner.os == 'Windows'
95
+ shell: pwsh
96
+ run: Set-MpPreference -DisableRealtimeMonitoring $true
97
+ # A Dev Drive is a fast ReFS drive. TEMP points there, so the test
98
+ # repos in tmp_path live on it.
99
+ - name: Set up Dev Drive
100
+ if: runner.os == 'Windows'
101
+ uses: samypr100/setup-dev-drive@v4.1.0
102
+ with:
103
+ drive-size: 8GB
104
+ drive-path: ${{ runner.temp }}/dev_drive.vhdx
105
+ trusted-dev-drive: true
106
+ env-mapping: |
107
+ TEMP,{{ DEV_DRIVE }}/tmp
108
+ TMP,{{ DEV_DRIVE }}/tmp
109
+ - name: Create temp dir on Dev Drive
110
+ if: runner.os == 'Windows'
111
+ run: mkdir -p "$TEMP" && echo "TEMP=$TEMP"
81
112
  - name: Install uv
82
- uses: astral-sh/setup-uv@v10.3.0
113
+ uses: astral-sh/setup-uv@v10.3.3
83
114
  with:
84
115
  python-version: ${{ matrix.python-version }}
85
116
  enable-cache: true
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: git-nested
3
- Version: 1.2.0
3
+ Version: 1.2.2
4
4
  Summary: Git Submodule Alternative
5
5
  Author-email: Thorsten Klein <thorsten.klein.git@gmail.com>
6
6
  License: MIT
@@ -8,7 +8,7 @@ Project-URL: Homepage, https://github.com/thorsten-klein/git-nested
8
8
  Project-URL: Documentation, https://thorsten-klein.github.io/git-nested/
9
9
  Project-URL: Repository, https://github.com/thorsten-klein/git-nested
10
10
  Project-URL: Issues, https://github.com/thorsten-klein/git-nested/issues
11
- Keywords: git,nested,submodule,nested
11
+ Keywords: cli,dependency-management,developer-tools,git,git-extension,git-submodule,git-submodules,git-subrepo,git-subtree,git-tools,monorepo,multi-repo,nested-repositories,python,repository-management,submodules,subrepo,subtree,vendoring,version-control
12
12
  Classifier: Development Status :: 4 - Beta
13
13
  Classifier: Intended Audience :: Developers
14
14
  Classifier: Topic :: Software Development :: Version Control :: Git
@@ -26,6 +26,8 @@ Dynamic: license-file
26
26
 
27
27
  # git-nested
28
28
 
29
+ <img src="https://raw.githubusercontent.com/thorsten-klein/git-nested/main/doc/_static/logo.svg" alt="logo" width="500"/>
30
+
29
31
  > An alternative to git-submodule and git-subtree for managing nested repositories.
30
32
 
31
33
  [![Test](https://github.com/thorsten-klein/git-nested/actions/workflows/test.yml/badge.svg)](https://github.com/thorsten-klein/git-nested/actions/workflows/test.yml)
@@ -54,6 +56,15 @@ git nested status # see where everything st
54
56
  A small `.gitnested` file in the folder remembers the URL, the branch and
55
57
  the upstream commit. So the commands stay short.
56
58
 
59
+ Your repository has submodules already? Turn them all into nested
60
+ repositories, and keep following upstream:
61
+
62
+ ```bash
63
+ git nested submodules init --recursive
64
+ git fetch origin
65
+ git nested submodules update origin/main
66
+ ```
67
+
57
68
  ## Why git-nested?
58
69
 
59
70
  - **Self-contained.** Your repository has all files. A plain `git clone`
@@ -1,5 +1,7 @@
1
1
  # git-nested
2
2
 
3
+ <img src="https://raw.githubusercontent.com/thorsten-klein/git-nested/main/doc/_static/logo.svg" alt="logo" width="500"/>
4
+
3
5
  > An alternative to git-submodule and git-subtree for managing nested repositories.
4
6
 
5
7
  [![Test](https://github.com/thorsten-klein/git-nested/actions/workflows/test.yml/badge.svg)](https://github.com/thorsten-klein/git-nested/actions/workflows/test.yml)
@@ -28,6 +30,15 @@ git nested status # see where everything st
28
30
  A small `.gitnested` file in the folder remembers the URL, the branch and
29
31
  the upstream commit. So the commands stay short.
30
32
 
33
+ Your repository has submodules already? Turn them all into nested
34
+ repositories, and keep following upstream:
35
+
36
+ ```bash
37
+ git nested submodules init --recursive
38
+ git fetch origin
39
+ git nested submodules update origin/main
40
+ ```
41
+
31
42
  ## Why git-nested?
32
43
 
33
44
  - **Self-contained.** Your repository has all files. A plain `git clone`
@@ -37,6 +37,8 @@ on GitHub, or as a website at <https://thorsten-klein.github.io/git-nested/>.
37
37
 
38
38
  - **[`configuration/gitnested-file.md`](configuration/gitnested-file.md)**:
39
39
  every field of the `.gitnested` file.
40
+ - **[`configuration/examples.md`](configuration/examples.md)**: how
41
+ `.gitnested` looks in common cases, in YAML and TOML.
40
42
  - **[`configuration/git-config.md`](configuration/git-config.md)**: the
41
43
  `git config` settings git-nested reads and writes.
42
44
 
@@ -100,3 +100,12 @@
100
100
  color: #fcfcfc;
101
101
  text-decoration: underline;
102
102
  }
103
+
104
+ /* 6. The logo in the sidebar (html_logo in doc/conf.py). It has no
105
+ * background, so it needs a light one on the blue sidebar. */
106
+ .wy-side-nav-search .wy-dropdown > a img.logo,
107
+ .wy-side-nav-search > a img.logo {
108
+ background: #fcfcfc;
109
+ border-radius: 6px;
110
+ padding: 6px 10px;
111
+ }
@@ -0,0 +1,29 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="8 0 256 256" width="256" height="256" role="img" aria-label="git-nested">
2
+ <!-- outer commit tree -->
3
+ <g fill="none" stroke="#1B2330" stroke-width="10" stroke-linecap="round">
4
+ <path d="M64 40 V216"/>
5
+ <path d="M64 44 C 64 62, 160 48, 160 70"/>
6
+ <path d="M160 186 C 160 208, 64 194, 64 212"/>
7
+ </g>
8
+ <g fill="#1B2330">
9
+ <circle cx="64" cy="40" r="15"/>
10
+ <circle cx="64" cy="128" r="15"/>
11
+ <circle cx="64" cy="216" r="15"/>
12
+ </g>
13
+
14
+ <!-- the nested repo: a commit that is itself a commit tree -->
15
+ <circle cx="160" cy="128" r="58" fill="#E6F6F0" stroke="#12A67E" stroke-width="10"/>
16
+
17
+ <!-- inner commit tree -->
18
+ <g fill="none" stroke="#0E7C5F" stroke-width="6" stroke-linecap="round">
19
+ <path d="M138 100 V156"/>
20
+ <path d="M138 104 C 138 114, 180 106, 180 118"/>
21
+ <path d="M180 138 C 180 150, 138 142, 138 152"/>
22
+ </g>
23
+ <g fill="#0E7C5F">
24
+ <circle cx="138" cy="100" r="8"/>
25
+ <circle cx="138" cy="128" r="8"/>
26
+ <circle cx="138" cy="156" r="8"/>
27
+ </g>
28
+ <circle cx="180" cy="128" r="10" fill="#FFFFFF" stroke="#0E7C5F" stroke-width="5"/>
29
+ </svg>
@@ -0,0 +1,30 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 256" width="800" height="256" role="img" aria-label="git-nested">
2
+ <!-- outer commit tree -->
3
+ <g fill="none" stroke="#1B2330" stroke-width="10" stroke-linecap="round">
4
+ <path d="M64 40 V216"/>
5
+ <path d="M64 44 C 64 62, 160 48, 160 70"/>
6
+ <path d="M160 186 C 160 208, 64 194, 64 212"/>
7
+ </g>
8
+ <g fill="#1B2330">
9
+ <circle cx="64" cy="40" r="15"/>
10
+ <circle cx="64" cy="128" r="15"/>
11
+ <circle cx="64" cy="216" r="15"/>
12
+ </g>
13
+
14
+ <!-- the nested repo: a commit that is itself a commit tree -->
15
+ <circle cx="160" cy="128" r="58" fill="#E6F6F0" stroke="#12A67E" stroke-width="10"/>
16
+
17
+ <!-- inner commit tree -->
18
+ <g fill="none" stroke="#0E7C5F" stroke-width="6" stroke-linecap="round">
19
+ <path d="M138 100 V156"/>
20
+ <path d="M138 104 C 138 114, 180 106, 180 118"/>
21
+ <path d="M180 138 C 180 150, 138 142, 138 152"/>
22
+ </g>
23
+ <g fill="#0E7C5F">
24
+ <circle cx="138" cy="100" r="8"/>
25
+ <circle cx="138" cy="128" r="8"/>
26
+ <circle cx="138" cy="156" r="8"/>
27
+ </g>
28
+ <circle cx="180" cy="128" r="10" fill="#FFFFFF" stroke="#0E7C5F" stroke-width="5"/>
29
+ <text x="262" y="156" font-family="'JetBrains Mono', 'Fira Code', ui-monospace, Menlo, Consolas, monospace" font-size="84" letter-spacing="-2"><tspan fill="#5B6676" font-weight="400">git-</tspan><tspan fill="#1B2330" font-weight="800">nested</tspan></text>
30
+ </svg>
@@ -53,7 +53,7 @@ sequenceDiagram
53
53
  git-nested->>Git: ls-files -- <subdir>
54
54
  git-nested->>Git: log --format=%H %T <upstream_head>
55
55
  Note over git-nested: Find the newest upstream commit<br/>whose tree matches <subdir> at HEAD
56
- Note over git-nested: Write .gitnested YAML
56
+ Note over git-nested: Write .gitnested
57
57
  git-nested->>Git: rev-parse <matching_commit>
58
58
  git-nested->>Git: add -f -- <subdir>/.gitnested
59
59
  git-nested->>Git: commit --no-verify [--signoff] [-S] -m <message>
@@ -68,7 +68,13 @@ sequenceDiagram
68
68
  git-nested->>Git: merge-base --is-ancestor <upstream> <nested_ref>
69
69
  git-nested->>Git: ls-files -- <subdir>
70
70
  git-nested->>Git: read-tree --prefix=<subdir> -u <nested_commit_ref>
71
- Note over git-nested: Write .gitnested YAML
71
+ Note over git-nested: Write .gitnested
72
+ opt patches in use
73
+ git-nested->>Git: checkout HEAD -- <inner repos added here>
74
+ git-nested->>Git: rm -r -f / checkout HEAD -- <patches-ignore paths>
75
+ git-nested->>Git: format-patch --zero-commit --no-signature -o <folder> <upstream>..<nested_commit_ref> -- <without local paths>
76
+ git-nested->>Git: add -A -f -- <folder>
77
+ end
72
78
  git-nested->>Git: rev-parse <nested_commit_ref>
73
79
  git-nested->>Git: add -f -- <subdir>/.gitnested
74
80
  git-nested->>Git: diff --cached --quiet
@@ -132,7 +138,7 @@ sequenceDiagram
132
138
 
133
139
  rect rgb(230, 245, 255)
134
140
  Note over git-nested,Git: update_gitrepo_file
135
- Note over git-nested: Write .gitnested YAML
141
+ Note over git-nested: Write .gitnested
136
142
  git-nested->>Git: rev-parse <nested_commit_ref>
137
143
  git-nested->>Git: add -f -- <subdir>/.gitnested
138
144
  end
@@ -207,6 +213,13 @@ sequenceDiagram
207
213
  git-nested->>Git: diff-index --quiet --cached --ignore-submodules HEAD
208
214
  git-nested->>Git: rev-parse HEAD
209
215
 
216
+ opt patches in use (HEAD has a patch)
217
+ Note over git-nested: Stop if subdir has changes the patches do not hold
218
+ git-nested->>Git: worktree add --detach .git/tmp/patches/<subref> <recorded commit>
219
+ git-nested->>Git: am -3 --keep-cr <patch>... (in the worktree)
220
+ git-nested->>Git: diff --quiet HEAD <local tree> -- <without the patches folder, inner repos, patches-ignore>
221
+ end
222
+
210
223
  rect rgb(230, 245, 255)
211
224
  Note over git-nested,Git: do_fetch
212
225
  git-nested->>Git: fetch --no-tags --quiet <remote> <branch>
@@ -229,6 +242,12 @@ sequenceDiagram
229
242
  git-nested->>Git: branch -D nested/<subref>
230
243
  end
231
244
 
245
+ opt patches in use: instead of create_nested_branch and the merge or rebase
246
+ git-nested->>Git: worktree add --no-checkout -b nested/<subref> <worktree> refs/nested/<subref>/fetch
247
+ git-nested->>Git: am -3 --keep-cr <all patches> (in the worktree)
248
+ Note over git-nested: On a conflict: stop and name the patch. git am --continue goes on with the rest
249
+ end
250
+
232
251
  rect rgb(230, 245, 255)
233
252
  Note over git-nested,Git: create_nested_branch
234
253
  git-nested->>Git: rev-list refs/heads/nested/<subref> -1
@@ -265,6 +284,16 @@ sequenceDiagram
265
284
  git-nested->>Git: update-ref refs/nested/<subref>/branch nested/<subref>
266
285
  end
267
286
 
287
+ opt --ignore
288
+ Note over git-nested: Upstream, with the ignored paths from the recorded commit
289
+ git-nested->>Git: read-tree <upstream> (temporary index)
290
+ git-nested->>Git: rm --cached -r -q -f --ignore-unmatch -- <ignored>
291
+ git-nested->>Git: ls-tree -r -z --full-tree <recorded commit> -- <ignored>
292
+ git-nested->>Git: update-index -z --index-info
293
+ git-nested->>Git: commit-tree -p <upstream> <tree>
294
+ Note over git-nested: The merge and rebase below use this commit
295
+ end
296
+
268
297
  alt method = merge
269
298
  git-nested->>Git: merge --ff --no-edit refs/nested/<subref>/fetch
270
299
  Note over git-nested: (in worktree)
@@ -282,7 +311,13 @@ sequenceDiagram
282
311
  git-nested->>Git: ls-files -- <subdir>
283
312
  git-nested->>Git: rm -r -- <subdir>
284
313
  git-nested->>Git: read-tree --prefix=<subdir> -u <nested_commit_ref>
285
- Note over git-nested: Write .gitnested YAML
314
+ Note over git-nested: Write .gitnested
315
+ opt patches in use
316
+ git-nested->>Git: checkout HEAD -- <inner repos added here>
317
+ git-nested->>Git: rm -r -f / checkout HEAD -- <patches-ignore paths>
318
+ git-nested->>Git: format-patch --zero-commit --no-signature -o <folder> <upstream>..<nested_commit_ref> -- <without local paths>
319
+ git-nested->>Git: add -A -f -- <folder>
320
+ end
286
321
  git-nested->>Git: add -f -- <subdir>/.gitnested
287
322
  git-nested->>Git: diff --cached --quiet
288
323
  git-nested->>Git: commit --no-verify [--signoff] [-S] -m <message>
@@ -304,7 +339,7 @@ sequenceDiagram
304
339
  git-nested->>Git: ls-files -- <subdir>
305
340
  git-nested->>Git: rm -r -- <subdir>
306
341
  git-nested->>Git: read-tree --prefix=<subdir> -u <nested_commit_ref>
307
- Note over git-nested: Write .gitnested YAML
342
+ Note over git-nested: Write .gitnested
308
343
  git-nested->>Git: add -f -- <subdir>/.gitnested
309
344
  git-nested->>Git: commit --no-verify [--signoff] [-S] -m <message>
310
345
  git-nested->>Git: worktree prune
@@ -314,8 +349,11 @@ sequenceDiagram
314
349
  end
315
350
  end
316
351
 
317
- opt Submodules of upstream that were nested, or --recurse-submodules
318
- Note over git-nested: Nest each at the commit upstream pins now (as in clone)
352
+ opt Submodules of upstream that are nested
353
+ Note over git-nested: Put them back from HEAD, with your changes.<br/>Then pull each to the commit upstream pins now
354
+ end
355
+ opt --recurse-submodules
356
+ Note over git-nested: Nest each new one at the commit upstream pins (as in clone)
319
357
  end
320
358
 
321
359
  Note over git-nested: The commit message lists the new upstream commits
@@ -379,6 +417,8 @@ sequenceDiagram
379
417
  Note over git-nested: (Same branch creation as in pull — see pull diagram)
380
418
  git-nested->>Git: ls-tree -r -z --name-only HEAD -- <subdir>
381
419
  Note over git-nested: Also drop .gitnested.levelN files and inner nested repos upstream does not have
420
+ Note over git-nested: With --ignore: the ignored paths come from upstream
421
+ Note over git-nested: The patches folder is dropped. patches-ignore paths come from upstream
382
422
  git-nested->>Git: branch nested/<subref> <tip>
383
423
  git-nested->>Git: worktree add --no-checkout <worktree_path> nested/<subref>
384
424
  git-nested->>Git: reset -q --hard (in the worktree)
@@ -416,8 +456,10 @@ sequenceDiagram
416
456
  end
417
457
 
418
458
  opt --commit flag
419
- Note over git-nested: Update .gitnested YAML
459
+ Note over git-nested: Update .gitnested
420
460
  git-nested->>Git: add -f -- <subdir>/.gitnested
461
+ Note over git-nested: Empty the patches folder: upstream has the changes now
462
+ git-nested->>Git: add -A -f -- <folder>
421
463
  git-nested->>Git: commit --no-verify [--signoff] [-S] -m <message>
422
464
  Note over git-nested: If it fails: reset -q --hard HEAD
423
465
  end
@@ -652,7 +694,14 @@ sequenceDiagram
652
694
  git-nested->>Git: ls-files -- <subdir>
653
695
  git-nested->>Git: rm -r -- <subdir>
654
696
  git-nested->>Git: read-tree --prefix=<subdir> -u <nested_commit_ref>
655
- Note over git-nested: Write .gitnested YAML
697
+ Note over git-nested: Inner nested repos: checkout HEAD -- <path>, not the gitlink
698
+ Note over git-nested: Write .gitnested
699
+ opt patches in use
700
+ git-nested->>Git: checkout HEAD -- <inner repos added here>
701
+ git-nested->>Git: rm -r -f / checkout HEAD -- <patches-ignore paths>
702
+ git-nested->>Git: format-patch --zero-commit --no-signature -o <folder> <upstream>..<nested_commit_ref> -- <without local paths>
703
+ git-nested->>Git: add -A -f -- <folder>
704
+ end
656
705
  git-nested->>Git: rev-parse <nested_commit_ref>
657
706
  git-nested->>Git: add -f -- <subdir>/.gitnested
658
707
  git-nested->>Git: diff --cached --quiet
@@ -663,6 +712,10 @@ sequenceDiagram
663
712
  Note over git-nested: Remove empty parent dirs up to .git/tmp
664
713
  git-nested->>Git: update-ref refs/nested/<subref>/commit <nested_commit_ref>
665
714
  end
715
+
716
+ opt Inner nested repos
717
+ Note over git-nested: Pull each to the commit upstream pins now (as in pull)
718
+ end
666
719
  ```
667
720
 
668
721
  ---
@@ -728,6 +781,53 @@ sequenceDiagram
728
781
 
729
782
  ---
730
783
 
784
+ ## submodules
785
+
786
+ `init` runs `init --from-submodule` for each submodule. `update` looks
787
+ like this:
788
+
789
+ ```mermaid
790
+ sequenceDiagram
791
+ participant User
792
+ participant git-nested
793
+ participant Git
794
+
795
+ User->>git-nested: git nested submodules update <commit>
796
+ git-nested->>Git: merge-base --is-ancestor <commit> HEAD
797
+ Note over git-nested: Merged already: only update the nested repos that lag behind
798
+ opt --dry-run
799
+ Note over git-nested: Print the plan, also deeper down, then stop
800
+ end
801
+ git-nested->>Git: merge --no-commit --no-ff <commit>
802
+ Note over git-nested: Write .git/nested-submodules-update.json for --continue and --abort
803
+ git-nested->>Git: update-index --force-remove <gitlink>
804
+ Note over git-nested: Drop each gitlink and its part of .gitmodules
805
+ Note over git-nested: Merge .gitattributes without git-nested's block, then add the block again
806
+ git-nested->>Git: commit --no-edit
807
+ Note over git-nested: Stop on other conflicts. --continue goes on here
808
+ opt A submodule pull stopped before
809
+ Note over git-nested: --continue finishes it there, then runs commit
810
+ end
811
+
812
+ loop For each submodule upstream changed
813
+ alt moved
814
+ git-nested->>Git: mv <old> <new>
815
+ else removed
816
+ git-nested->>Git: rm -r <path>
817
+ else added
818
+ Note over git-nested: Same as clone. Not for update = none
819
+ else new pin
820
+ Note over git-nested: Same as pull -b <pin> -u. Skipped if it has a pin
821
+ end
822
+ git-nested->>Git: commit
823
+ end
824
+
825
+ opt --single-commit
826
+ git-nested->>Git: reset --soft <merge commit>
827
+ git-nested->>Git: commit --amend
828
+ end
829
+ ```
830
+
731
831
  ## diff
732
832
 
733
833
  ```mermaid
@@ -770,6 +870,131 @@ sequenceDiagram
770
870
 
771
871
  ---
772
872
 
873
+ ## verify
874
+
875
+ ```mermaid
876
+ sequenceDiagram
877
+ participant User
878
+ participant git-nested
879
+ participant Git
880
+
881
+ User->>git-nested: git nested verify <subdir> [--patches <patch>...]
882
+ git-nested->>Git: rev-parse --show-prefix
883
+ Note over git-nested: Below the top level: rev-parse --show-toplevel,<br/>paths rebased, then run from there
884
+ git-nested->>Git: rev-parse --git-dir
885
+ git-nested->>Git: rev-parse --git-dir
886
+ git-nested->>Git: symbolic-ref --short --quiet HEAD
887
+ git-nested->>Git: rev-parse --is-inside-work-tree
888
+ git-nested->>Git: rev-parse HEAD
889
+ Note over git-nested: Read .gitnested config
890
+
891
+ git-nested->>Git: rev-parse HEAD:<subdir>
892
+ git-nested->>Git: rev-list <commit>^{commit} -1
893
+ opt upstream commit not here
894
+ git-nested->>Git: fetch --no-tags --quiet <remote> <branch>
895
+ git-nested->>Git: rev-parse FETCH_HEAD^0
896
+ git-nested->>Git: update-ref refs/nested/<subref>/fetch FETCH_HEAD^0
897
+ end
898
+ opt path, filter or exclude configured
899
+ Note over git-nested: Build a commit with only the nested part of upstream
900
+ git-nested->>Git: commit-tree -p <commit> <tree>
901
+ end
902
+
903
+ git-nested->>Git: worktree add --detach --no-checkout .git/tmp/verify/<subref> <base>
904
+ git-nested->>Git: reset -q --hard (in the worktree)
905
+ Note over git-nested: A file a checkout made CRLF is applied as an LF copy
906
+ alt patches
907
+ git-nested->>Git: -c core.hooksPath=<empty> am -3 --quiet --no-gpg-sign --keep-cr <patch>... (in the worktree)
908
+ else diffs
909
+ loop For each diff
910
+ git-nested->>Git: apply --index <file> (in the worktree)
911
+ end
912
+ end
913
+ git-nested->>Git: commit --allow-empty --no-verify (in the worktree)
914
+ git-nested->>Git: diff --quiet HEAD <local tree> -- . ':(exclude,glob)**/.gitnested*' [':(exclude,literal)<path>']
915
+ Note over git-nested: Left out: the patches folder, inner nested repos, patches-ignore and --ignore paths
916
+ Note over git-nested: The diffs below use the same paths
917
+
918
+ opt it differs
919
+ git-nested->>Git: diff --stat HEAD <local tree>
920
+ alt patches
921
+ git-nested->>Git: diff --binary --full-index --output=<file> HEAD <local tree>
922
+ git-nested->>Git: apply --index <file>
923
+ git-nested->>Git: commit -m 'TODO: title' -m 'TODO: description'
924
+ git-nested->>Git: format-patch --zero-commit --no-signature -1 --start-number=<n> -o <dir> HEAD
925
+ else diff with --output
926
+ git-nested->>Git: diff --binary --output=<file> <base> <local tree>
927
+ end
928
+ end
929
+
930
+ git-nested->>Git: worktree prune
931
+ Note over git-nested: The worktree is removed, unless --keep
932
+ ```
933
+
934
+ ---
935
+
936
+ ## patches
937
+
938
+ ```mermaid
939
+ sequenceDiagram
940
+ participant User
941
+ participant git-nested
942
+ participant Git
943
+
944
+ User->>git-nested: git nested patches create|verify|drop <subdir>
945
+ git-nested->>Git: rev-parse --show-prefix
946
+ Note over git-nested: Below the top level: rev-parse --show-toplevel,<br/>paths rebased, then run from there
947
+ git-nested->>Git: rev-parse --git-dir
948
+ git-nested->>Git: rev-parse --git-dir
949
+ git-nested->>Git: symbolic-ref --short --quiet HEAD
950
+ git-nested->>Git: rev-parse --is-inside-work-tree
951
+ git-nested->>Git: rev-parse HEAD
952
+ Note over git-nested: Read .gitnested config. Refuse if the patches are off or do not work with the setup
953
+
954
+ git-nested->>Git: rev-parse HEAD:<subdir>
955
+ git-nested->>Git: rev-list <commit>^{commit} -1
956
+ opt upstream commit not here
957
+ git-nested->>Git: fetch --no-tags --quiet <remote> <branch>
958
+ git-nested->>Git: rev-parse FETCH_HEAD^0
959
+ git-nested->>Git: update-ref refs/nested/<subref>/fetch FETCH_HEAD^0
960
+ end
961
+
962
+ git-nested->>Git: worktree add --detach --no-checkout .git/tmp/patches/<subref> <commit>
963
+ git-nested->>Git: reset -q --hard (in the worktree)
964
+ opt the folder has patches (not with create --force)
965
+ Note over git-nested: A patch file a checkout made CRLF is applied as an LF copy
966
+ git-nested->>Git: -c core.hooksPath=<empty> am -3 --quiet --no-gpg-sign --keep-cr <patch>... (in the worktree)
967
+ end
968
+ git-nested->>Git: diff --stat HEAD <local tree> -- . ':(exclude,glob)**/.gitnested*' [':(exclude,literal)<path>']
969
+ Note over git-nested: Left out: the patches folder, inner nested repos and patches-ignore paths
970
+
971
+ opt create, and HEAD has more
972
+ git-nested->>Git: diff --binary --full-index --output=<file> HEAD <local tree>
973
+ git-nested->>Git: apply --index <file>
974
+ git-nested->>Git: commit -m 'TODO: title' -m 'TODO: description'
975
+ end
976
+ git-nested->>Git: format-patch --zero-commit --no-signature --no-numbered --no-cover-letter -o <scratch> <commit>..HEAD
977
+ Note over git-nested: Compare with the folder, byte for byte
978
+ alt create
979
+ Note over git-nested: Replace the patches in the folder if they differ
980
+ else verify
981
+ Note over git-nested: Fail if a change is not in a patch, or a patch differs
982
+ end
983
+
984
+ git-nested->>Git: worktree prune
985
+
986
+ opt drop <patch>...
987
+ Note over git-nested: Refuse a dirty working tree, and changes the patches do not hold
988
+ git-nested->>Git: worktree add --detach --no-checkout <tmp> <commit>
989
+ git-nested->>Git: am -3 --keep-cr <the other patches> (in the worktree)
990
+ git-nested->>Git: read-tree --prefix=<subdir> -u <result>
991
+ git-nested->>Git: format-patch --zero-commit --no-signature -o <folder> <commit>..<result>
992
+ git-nested->>Git: commit --no-verify -m '<subdir>: drop the patch <name>'
993
+ end
994
+ ```
995
+
996
+ ---
997
+
773
998
  ## clean
774
999
 
775
1000
  ```mermaid
@@ -64,6 +64,8 @@ One module per command, for example `commands/pull.py`. Each has one
64
64
  | `history.py` | rebuilds the nested history: the core algorithm |
65
65
  | `content.py` | creates the nested branch, places its content, commits |
66
66
  | `filters.py` | applies `filter` and `exclude` |
67
+ | `patches.py` | keeps local changes as patch files: reads, applies and writes them |
68
+ | `patchbuild.py` | builds and checks patches in a temporary worktree |
67
69
  | `gitfile.py` | reads and writes `.gitnested`, and the level files |
68
70
  | `refs.py` | names of the nested branches and refs |
69
71
  | `worktree.py` | temporary worktrees and their branches |
@@ -79,7 +81,7 @@ One module per command, for example `commands/pull.py`. Each has one
79
81
  | `output.py` | everything git-nested prints; hides credentials |
80
82
  | `messages.py` | the long help texts, for example after a conflict |
81
83
  | `models.py` | `Flags`, `NestedConfig`, `CommandContext` |
82
- | `yamlio.py` | reads and writes the YAML of `.gitnested` |
84
+ | `configio.py` | reads and writes `.gitnested`, as YAML or TOML |
83
85
  | `errors.py` | `GitNestedError`, the one exception type |
84
86
  | `constants.py` | shared names |
85
87
  | `_version.py` | the version |