git-nested 1.0.3__tar.gz → 1.0.5__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 (55) hide show
  1. git_nested-1.0.5/.github/CODEOWNERS +10 -0
  2. git_nested-1.0.5/.github/workflows/build-binary.yml +62 -0
  3. git_nested-1.0.5/.github/workflows/release-binary.yml +157 -0
  4. git_nested-1.0.5/.github/workflows/test-binary.yml +78 -0
  5. {git_nested-1.0.3 → git_nested-1.0.5}/.github/workflows/test.yml +18 -0
  6. {git_nested-1.0.3 → git_nested-1.0.5}/.gitignore +2 -0
  7. {git_nested-1.0.3 → git_nested-1.0.5}/CONTRIBUTING.md +25 -0
  8. {git_nested-1.0.3 → git_nested-1.0.5}/PKG-INFO +37 -3
  9. {git_nested-1.0.3 → git_nested-1.0.5}/README.md +36 -2
  10. {git_nested-1.0.3 → git_nested-1.0.5}/lib/git_nested.egg-info/PKG-INFO +37 -3
  11. {git_nested-1.0.3 → git_nested-1.0.5}/lib/git_nested.egg-info/SOURCES.txt +6 -0
  12. {git_nested-1.0.3 → git_nested-1.0.5}/lib/git_nested.py +111 -4
  13. {git_nested-1.0.3 → git_nested-1.0.5}/pyproject.toml +6 -0
  14. git_nested-1.0.5/scripts/create-python-exe.sh +176 -0
  15. {git_nested-1.0.3 → git_nested-1.0.5}/share/completion.bash +2 -2
  16. {git_nested-1.0.3 → git_nested-1.0.5}/share/git-nested.fish +2 -1
  17. {git_nested-1.0.3 → git_nested-1.0.5}/share/zsh-completion/_git-nested +2 -2
  18. {git_nested-1.0.3 → git_nested-1.0.5}/test/conftest.py +76 -10
  19. {git_nested-1.0.3 → git_nested-1.0.5}/test/scenarios/test_filter.py +33 -0
  20. {git_nested-1.0.3 → git_nested-1.0.5}/test/test_clone.py +2 -3
  21. git_nested-1.0.5/test/test_diff.py +158 -0
  22. {git_nested-1.0.3 → git_nested-1.0.5}/test/test_error.py +5 -2
  23. {git_nested-1.0.3 → git_nested-1.0.5}/test/test_pull.py +4 -4
  24. {git_nested-1.0.3 → git_nested-1.0.5}/test/test_version.py +2 -3
  25. {git_nested-1.0.3 → git_nested-1.0.5}/.codecov.yml +0 -0
  26. {git_nested-1.0.3 → git_nested-1.0.5}/.fish.rc +0 -0
  27. {git_nested-1.0.3 → git_nested-1.0.5}/.gitattributes +0 -0
  28. {git_nested-1.0.3 → git_nested-1.0.5}/.github/workflows/publish.yml +0 -0
  29. {git_nested-1.0.3 → git_nested-1.0.5}/.rc +0 -0
  30. {git_nested-1.0.3 → git_nested-1.0.5}/LICENSE +0 -0
  31. {git_nested-1.0.3 → git_nested-1.0.5}/docs/diagrams.md +0 -0
  32. {git_nested-1.0.3 → git_nested-1.0.5}/lib/git-nested +0 -0
  33. {git_nested-1.0.3 → git_nested-1.0.5}/lib/git_nested.egg-info/dependency_links.txt +0 -0
  34. {git_nested-1.0.3 → git_nested-1.0.5}/lib/git_nested.egg-info/entry_points.txt +0 -0
  35. {git_nested-1.0.3 → git_nested-1.0.5}/lib/git_nested.egg-info/requires.txt +0 -0
  36. {git_nested-1.0.3 → git_nested-1.0.5}/lib/git_nested.egg-info/top_level.txt +0 -0
  37. {git_nested-1.0.3 → git_nested-1.0.5}/setup.cfg +0 -0
  38. {git_nested-1.0.3 → git_nested-1.0.5}/share/enable-completion.sh +0 -0
  39. {git_nested-1.0.3 → git_nested-1.0.5}/test/scenarios/test_extraction.py +0 -0
  40. {git_nested-1.0.3 → git_nested-1.0.5}/test/scenarios/test_filemode.py +0 -0
  41. {git_nested-1.0.3 → git_nested-1.0.5}/test/test_branch.py +0 -0
  42. {git_nested-1.0.3 → git_nested-1.0.5}/test/test_clean.py +0 -0
  43. {git_nested-1.0.3 → git_nested-1.0.5}/test/test_completion.py +0 -0
  44. {git_nested-1.0.3 → git_nested-1.0.5}/test/test_encode.py +0 -0
  45. {git_nested-1.0.3 → git_nested-1.0.5}/test/test_fetch.py +0 -0
  46. {git_nested-1.0.3 → git_nested-1.0.5}/test/test_gitignore.py +0 -0
  47. {git_nested-1.0.3 → git_nested-1.0.5}/test/test_init.py +0 -0
  48. {git_nested-1.0.3 → git_nested-1.0.5}/test/test_nested_in_nested.py +0 -0
  49. {git_nested-1.0.3 → git_nested-1.0.5}/test/test_push.py +0 -0
  50. {git_nested-1.0.3 → git_nested-1.0.5}/test/test_rebase.py +0 -0
  51. {git_nested-1.0.3 → git_nested-1.0.5}/test/test_reclone.py +0 -0
  52. {git_nested-1.0.3 → git_nested-1.0.5}/test/test_status.py +0 -0
  53. {git_nested-1.0.3 → git_nested-1.0.5}/test/test_submodule.py +0 -0
  54. {git_nested-1.0.3 → git_nested-1.0.5}/test/unittest/test_logging.py +0 -0
  55. {git_nested-1.0.3 → git_nested-1.0.5}/uv.lock +0 -0
@@ -0,0 +1,10 @@
1
+ # Code owners for git-nested
2
+ #
3
+ # Owners listed here are automatically requested for review on pull requests
4
+ # that touch matching files. The last matching pattern wins.
5
+ #
6
+ # Note: GitHub never requests a review from the author of the pull request,
7
+ # so PRs opened by an owner get no automatic reviewer.
8
+
9
+ # Default owner for everything in the repository
10
+ * @thorsten-klein
@@ -0,0 +1,62 @@
1
+ name: Build binary
2
+
3
+ # Builds the standalone 'git-nested' executable and uploads it as an artifact.
4
+ # Called by test.yml (so every push/PR proves the recipe still builds) and by
5
+ # release-binary.yml (which attaches it to the release) -- so what CI exercises
6
+ # is built by exactly the recipe that ships, rather than a lookalike that can
7
+ # drift away from it.
8
+ on:
9
+ workflow_call:
10
+ inputs:
11
+ ref:
12
+ description: 'Commit/tag/branch to build. Empty: whatever triggered the caller.'
13
+ type: string
14
+ required: false
15
+ default: ''
16
+ artifact:
17
+ description: 'Name of the uploaded artifact'
18
+ type: string
19
+ required: false
20
+ default: git-nested-binary
21
+
22
+ jobs:
23
+ build:
24
+ runs-on: ubuntu-latest
25
+ # A PyInstaller binary links the glibc of the machine that built it, and
26
+ # glibc is only backward compatible -- built on ubuntu-latest it would
27
+ # refuse to start on anything older than that runner. AlmaLinux 8 has
28
+ # glibc 2.28, the oldest that still runs the node20 the actions below
29
+ # need, which covers every distro from Ubuntu 20.04 / Debian 10 /
30
+ # Fedora 29 / RHEL 8 onwards. glibc-based distros only -- musl ones
31
+ # (Alpine) can never run this binary.
32
+ container: almalinux:8
33
+ steps:
34
+ # Before the checkout -- without git, actions/checkout silently falls
35
+ # back to downloading a tarball, and a checkout with no .git has no
36
+ # tags for setuptools-scm to derive the version from.
37
+ - name: Install build prerequisites
38
+ run: dnf -y install python3.12 python3.12-pip git tar xz
39
+
40
+ - uses: actions/checkout@v4
41
+ with:
42
+ ref: ${{ inputs.ref }}
43
+ # the version frozen into the binary comes from the tags, and the
44
+ # default shallow checkout fetches none of them.
45
+ fetch-depth: 0
46
+
47
+ # the checkout is owned by a different user than this container's root,
48
+ # which git refuses to read from until told it is not a security issue.
49
+ - name: Trust the checkout
50
+ run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
51
+
52
+ - name: Build the executable
53
+ run: scripts/create-python-exe.sh --output dist --python python3.12
54
+
55
+ # the .tar.xz rather than the bare executable. It is what a release
56
+ # actually ships, and unlike a zipped artifact it keeps the exec bit,
57
+ # so consumers just untar and run it.
58
+ - uses: actions/upload-artifact@v4
59
+ with:
60
+ name: ${{ inputs.artifact }}
61
+ path: dist/git-nested_x64_Linux.tar.xz
62
+ if-no-files-found: error
@@ -0,0 +1,157 @@
1
+ name: Release binary
2
+
3
+ # Builds the single-file 'git-nested' executable (see
4
+ # scripts/create-python-exe.sh) and attaches git-nested_x64_Linux.tar.xz to the
5
+ # release, so git-nested can be used on a machine that has no python -- and no
6
+ # pip, no uv -- at all.
7
+ #
8
+ # Separate from publish.yml on purpose. That one is triggered by the tag push
9
+ # and uploads to PyPI, while attaching an asset needs the GitHub *release* to
10
+ # already exist, which is only guaranteed once it is published.
11
+ on:
12
+ release:
13
+ types: [published]
14
+ # on-demand -- builds and verifies without touching any release. Give 'tag'
15
+ # to also (re-)attach the asset to an existing release, e.g. after fixing
16
+ # the build for one already published.
17
+ workflow_dispatch:
18
+ inputs:
19
+ tag:
20
+ description: 'Existing release tag to build from and attach the asset to (empty: build + verify only)'
21
+ required: false
22
+ default: ''
23
+
24
+ permissions:
25
+ contents: read
26
+
27
+ concurrency:
28
+ group: ${{ github.workflow }}-${{ github.event.release.tag_name || inputs.tag || github.ref }}
29
+ cancel-in-progress: true
30
+
31
+ env:
32
+ # The release this builds. Its tag is what setuptools-scm turns into the
33
+ # version frozen into the binary, so checking out anything else would
34
+ # produce an executable that misreports itself. Empty on a plain
35
+ # workflow_dispatch -- then the triggering ref is built as-is.
36
+ REF: ${{ github.event.release.tag_name || inputs.tag || github.ref }}
37
+ ARCHIVE: git-nested_x64_Linux.tar.xz
38
+
39
+ jobs:
40
+ # the glibc floor and every other build decision live there, shared with
41
+ # test.yml so both exercise the same executable. 'env.REF' is not available
42
+ # to a reusable workflow's inputs, so the ref is spelled out again.
43
+ build:
44
+ uses: ./.github/workflows/build-binary.yml
45
+ with:
46
+ ref: ${{ github.event.release.tag_name || inputs.tag || github.ref }}
47
+ artifact: git-nested-binary
48
+
49
+ # The whole pytest suite, driven through the binary that is about to be
50
+ # attached -- the check that it is functionally complete, not just startable.
51
+ test:
52
+ needs: build
53
+ uses: ./.github/workflows/test-binary.yml
54
+ with:
55
+ ref: ${{ github.event.release.tag_name || inputs.tag || github.ref }}
56
+ artifact: git-nested-binary
57
+
58
+ # Proves the "runs on any x86_64 Linux" claim rather than assuming it. The
59
+ # binary is dropped into stock distro images that have no python installed,
60
+ # and has to drive a real nested repo end to end there.
61
+ verify:
62
+ needs: build
63
+ runs-on: ubuntu-latest
64
+ strategy:
65
+ fail-fast: false
66
+ matrix:
67
+ include:
68
+ # the glibc floor it was built against, and the oldest still-
69
+ # supported LTS releases -- the ones a modern-runner build breaks
70
+ - image: almalinux:8
71
+ install: dnf -y install git
72
+ - image: ubuntu:22.04
73
+ install: apt-get update -qq && DEBIAN_FRONTEND=noninteractive apt-get install -y -qq git
74
+ - image: debian:12
75
+ install: apt-get update -qq && DEBIAN_FRONTEND=noninteractive apt-get install -y -qq git
76
+ # ... plus the current end of the range, where a binary built too
77
+ # old would fail instead
78
+ - image: ubuntu:24.04
79
+ install: apt-get update -qq && DEBIAN_FRONTEND=noninteractive apt-get install -y -qq git
80
+ - image: fedora:latest
81
+ install: dnf -y install git
82
+ - image: archlinux:latest
83
+ install: pacman -Sy --noconfirm git
84
+ steps:
85
+ - uses: actions/download-artifact@v4
86
+ with:
87
+ name: git-nested-binary
88
+
89
+ - name: Unpack
90
+ run: tar -xf "$ARCHIVE"
91
+
92
+ # git is the one thing that does have to be installed -- git-nested
93
+ # drives it and refuses to start without it. Python deliberately is not:
94
+ # if any of these images had to install it, the binary would not be
95
+ # doing its job.
96
+ - name: Write the verification script
97
+ run: |
98
+ cat > verify.sh <<'EOF'
99
+ set -eu
100
+ if command -v python3 >/dev/null; then
101
+ echo "note: this image happens to ship python3; the binary does not use it"
102
+ else
103
+ echo "note: no python3 in this image at all"
104
+ fi
105
+
106
+ git-nested --version
107
+
108
+ # invoked as `git nested`, the way users run it: git finds the
109
+ # subcommand by looking for a 'git-nested' on PATH.
110
+ git config --global user.email ci@example.com
111
+ git config --global user.name CI
112
+ git config --global init.defaultBranch master
113
+ git config --global --add safe.directory '*'
114
+
115
+ mkdir -p /tmp/repo/doc
116
+ cd /tmp/repo
117
+ git init -q
118
+ touch doc/README.md
119
+ git add -A
120
+ git commit -qm "initial"
121
+
122
+ git nested init doc
123
+ test -f doc/.gitnested
124
+ cat doc/.gitnested
125
+ git nested status
126
+ EOF
127
+
128
+ # The binary and the script are mounted in, so the distro images need
129
+ # neither tar/xz nor anything else to take part beyond git -- the point
130
+ # is that nothing else is required.
131
+ - name: Run on ${{ matrix.image }}
132
+ run: |
133
+ docker run --rm \
134
+ -v "$PWD/git-nested:/usr/local/bin/git-nested:ro" \
135
+ -v "$PWD/verify.sh:/verify.sh:ro" \
136
+ ${{ matrix.image }} \
137
+ sh -c '${{ matrix.install }} >/dev/null && sh /verify.sh'
138
+
139
+ upload:
140
+ needs: [test, verify]
141
+ # nothing to attach when workflow_dispatch ran without a tag
142
+ if: github.event_name == 'release' || inputs.tag != ''
143
+ runs-on: ubuntu-latest
144
+ permissions:
145
+ contents: write
146
+ steps:
147
+ - uses: actions/download-artifact@v4
148
+ with:
149
+ name: git-nested-binary
150
+
151
+ # --clobber so re-running against an already-attached release replaces
152
+ # the asset instead of failing halfway.
153
+ - name: Attach ${{ env.ARCHIVE }} to ${{ env.REF }}
154
+ env:
155
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
156
+ GH_REPO: ${{ github.repository }}
157
+ run: gh release upload "$REF" "$ARCHIVE" --clobber
@@ -0,0 +1,78 @@
1
+ name: Test binary
2
+
3
+ # Runs the *whole* pytest suite against the standalone executable instead of
4
+ # against the git_nested module in the checkout: conftest's GIT_NESTED_EXE
5
+ # routes every cmd_git_nested() call through `git nested ...` on PATH, so the
6
+ # ~130 tests drive the frozen binary as a user would. That is what catches the
7
+ # failures unique to freezing -- a module PyInstaller did not collect, package
8
+ # metadata missing so the version is wrong, a data file left out of the archive
9
+ # -- none of which the module tests can see.
10
+ #
11
+ # Called by test.yml (every push/PR) and by release-binary.yml (before the
12
+ # asset is attached). release-binary.yml additionally runs the binary across
13
+ # distro images, which is the other half: this job proves the binary is
14
+ # complete, that one proves it is portable.
15
+ on:
16
+ workflow_call:
17
+ inputs:
18
+ ref:
19
+ description: 'Commit/tag/branch whose tests to run. Empty: whatever triggered the caller.'
20
+ type: string
21
+ required: false
22
+ default: ''
23
+ artifact:
24
+ description: 'Name of the artifact holding the built binary'
25
+ type: string
26
+ required: false
27
+ default: git-nested-binary
28
+
29
+ jobs:
30
+ test:
31
+ runs-on: ubuntu-latest
32
+ steps:
33
+ - uses: actions/checkout@v4
34
+ with:
35
+ ref: ${{ inputs.ref }}
36
+ # no fetch-depth: 0 needed -- the version under test is read out of
37
+ # the binary (conftest's _version_under_test), not derived from the
38
+ # tags of this checkout.
39
+
40
+ - name: Install uv
41
+ uses: astral-sh/setup-uv@v7
42
+ with:
43
+ python-version: '3.13'
44
+ enable-cache: true
45
+
46
+ # for pytest, pytest-xdist and the git_nested import conftest still needs
47
+ # for its helpers -- the code under test comes from the binary.
48
+ - name: Setup project
49
+ run: uv sync --frozen
50
+
51
+ - name: git config
52
+ run: |
53
+ git config --global user.email "you@example.com";
54
+ git config --global user.name "Your Name";
55
+ git config --global init.defaultBranch "master";
56
+ git config --global --add safe.directory "$PWD";
57
+ git config --global --add safe.directory "$PWD.git";
58
+
59
+ - uses: actions/download-artifact@v4
60
+ with:
61
+ name: ${{ inputs.artifact }}
62
+
63
+ # into its own directory: the env fixture puts the binary's directory on
64
+ # PATH, and the repo root is not a good thing to put there.
65
+ - name: Unpack the binary
66
+ run: |
67
+ mkdir -p bin
68
+ tar -C bin -xf git-nested_x64_Linux.tar.xz
69
+ bin/git-nested --version
70
+
71
+ # no coverage flags: the code being executed lives in another process
72
+ # inside the frozen archive, so there is nothing here for coverage to
73
+ # measure. test.yml's module run is what the coverage numbers come from.
74
+ - name: Run the suite against the binary
75
+ env:
76
+ GIT_NESTED_EXE: ${{ github.workspace }}/bin/git-nested
77
+ PYTHONIOENCODING: utf-8
78
+ run: uv run pytest -v -n=auto -W error
@@ -7,6 +7,24 @@ on:
7
7
  branches: ['*']
8
8
 
9
9
  jobs:
10
+ # Builds the standalone executable with the very script the release uses
11
+ # (scripts/create-python-exe.sh), so a change that breaks the freeze -- a new
12
+ # import, a moved data file -- fails here rather than on release day. The
13
+ # script smoke-tests the binary it produces; release-binary.yml additionally
14
+ # runs it across distros before attaching it to a release.
15
+ binary:
16
+ uses: ./.github/workflows/build-binary.yml
17
+ with:
18
+ artifact: git-nested-binary-ci
19
+
20
+ # ... and then runs the full pytest suite through that executable, so a
21
+ # binary that builds but does not work still fails the PR.
22
+ binary-test:
23
+ needs: binary
24
+ uses: ./.github/workflows/test-binary.yml
25
+ with:
26
+ artifact: git-nested-binary-ci
27
+
10
28
  test:
11
29
  runs-on: ${{ matrix.os }}
12
30
  strategy:
@@ -9,5 +9,7 @@ build/
9
9
  .pytest_cache/
10
10
  .coverage
11
11
  htmlcov/
12
+ coverage.xml
13
+ junit.xml
12
14
  *.whl
13
15
  *.tar.gz
@@ -65,6 +65,31 @@ uv run poe test -vv
65
65
  uv run pytest
66
66
  ```
67
67
 
68
+ ### Testing the Standalone Executable
69
+
70
+ Releases ship a single-file executable built with PyInstaller
71
+ (`scripts/create-python-exe.sh`). Freezing can break things the module tests
72
+ never see — an import PyInstaller did not collect, missing package metadata —
73
+ so the whole suite can be run *through* the binary instead:
74
+
75
+ ```bash
76
+ # Build dist/git-nested and run every test against it
77
+ uv run poe test-exe
78
+
79
+ # Just build it
80
+ uv run poe exe
81
+
82
+ # Or point the tests at any executable you already have
83
+ GIT_NESTED_EXE=dist/git-nested uv run pytest
84
+ ```
85
+
86
+ With `GIT_NESTED_EXE` set, `cmd_git_nested()` in `test/conftest.py` runs
87
+ `git nested ...` as a subprocess against that binary rather than calling the
88
+ module in-process; without it, nothing changes. CI does both: `test.yml` builds
89
+ the binary and runs the suite against it on every PR, and `release-binary.yml`
90
+ repeats that plus a run across six distro images before attaching the asset to
91
+ a release.
92
+
68
93
  ### Code Quality
69
94
 
70
95
  We use [Ruff](https://github.com/astral-sh/ruff) for both linting and formatting:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: git-nested
3
- Version: 1.0.3
3
+ Version: 1.0.5
4
4
  Summary: Git Submodule Alternative
5
5
  Author-email: Thorsten Klein <thorsten.klein.git@gmail.com>
6
6
  License: MIT
@@ -80,7 +80,25 @@ git-nested now supports nested repositories within nested repositories (recursiv
80
80
  pip install git+https://github.com/thorsten-klein/git-nested
81
81
  ```
82
82
 
83
- #### Method 2: From Source with Shell Integration
83
+ #### Method 2: Standalone Executable (no Python needed)
84
+
85
+ Every [release](https://github.com/thorsten-klein/git-nested/releases) ships
86
+ `git-nested_x64_Linux.tar.xz`: a single file with git-nested, its dependencies
87
+ and a Python interpreter inside. Only git itself has to be installed.
88
+
89
+ ```bash
90
+ curl -L https://github.com/thorsten-klein/git-nested/releases/latest/download/git-nested_x64_Linux.tar.xz | tar -xJ
91
+ sudo install git-nested /usr/local/bin/ # any directory on PATH works
92
+ ```
93
+
94
+ The file has to keep the name `git-nested` — that is how `git nested ...`
95
+ finds it. The archive also contains the completion scripts from `share/`.
96
+
97
+ Built on x86_64 with glibc 2.28, so it runs on any x86_64 Linux from that
98
+ version onwards (Ubuntu 20.04, Debian 10, RHEL/AlmaLinux 8 and newer). Not on
99
+ musl distros such as Alpine.
100
+
101
+ #### Method 3: From Source with Shell Integration
84
102
 
85
103
  Adds git-nested to PATH and enables tab completion:
86
104
 
@@ -90,7 +108,7 @@ echo 'source /path/to/git-nested/.rc' >> ~/.bashrc
90
108
  source ~/.bashrc
91
109
  ```
92
110
 
93
- #### Method 3: From Source (Manual)
111
+ #### Method 4: From Source (Manual)
94
112
 
95
113
  ```bash
96
114
  git clone https://github.com/thorsten-klein/git-nested /path/to/git-nested
@@ -195,6 +213,22 @@ Fetch remote content for a nested repository.
195
213
  git nested fetch --help
196
214
  ```
197
215
 
216
+ #### `git nested diff`
217
+
218
+ Show the local diff of a nested repo compared to upstream. Fetches the latest upstream
219
+ content first, so it always compares against the freshest available state. Requires that
220
+ there are no uncommitted changes in the outer repository.
221
+
222
+ ```bash
223
+ git nested diff --help
224
+ ```
225
+
226
+ **Example:**
227
+ ```bash
228
+ git nested diff ext/lib
229
+ git nested diff --all # Diff all nested repos
230
+ ```
231
+
198
232
  #### `git nested branch`
199
233
 
200
234
  Create a branch with local nested commits for manual conflict resolution.
@@ -54,7 +54,25 @@ git-nested now supports nested repositories within nested repositories (recursiv
54
54
  pip install git+https://github.com/thorsten-klein/git-nested
55
55
  ```
56
56
 
57
- #### Method 2: From Source with Shell Integration
57
+ #### Method 2: Standalone Executable (no Python needed)
58
+
59
+ Every [release](https://github.com/thorsten-klein/git-nested/releases) ships
60
+ `git-nested_x64_Linux.tar.xz`: a single file with git-nested, its dependencies
61
+ and a Python interpreter inside. Only git itself has to be installed.
62
+
63
+ ```bash
64
+ curl -L https://github.com/thorsten-klein/git-nested/releases/latest/download/git-nested_x64_Linux.tar.xz | tar -xJ
65
+ sudo install git-nested /usr/local/bin/ # any directory on PATH works
66
+ ```
67
+
68
+ The file has to keep the name `git-nested` — that is how `git nested ...`
69
+ finds it. The archive also contains the completion scripts from `share/`.
70
+
71
+ Built on x86_64 with glibc 2.28, so it runs on any x86_64 Linux from that
72
+ version onwards (Ubuntu 20.04, Debian 10, RHEL/AlmaLinux 8 and newer). Not on
73
+ musl distros such as Alpine.
74
+
75
+ #### Method 3: From Source with Shell Integration
58
76
 
59
77
  Adds git-nested to PATH and enables tab completion:
60
78
 
@@ -64,7 +82,7 @@ echo 'source /path/to/git-nested/.rc' >> ~/.bashrc
64
82
  source ~/.bashrc
65
83
  ```
66
84
 
67
- #### Method 3: From Source (Manual)
85
+ #### Method 4: From Source (Manual)
68
86
 
69
87
  ```bash
70
88
  git clone https://github.com/thorsten-klein/git-nested /path/to/git-nested
@@ -169,6 +187,22 @@ Fetch remote content for a nested repository.
169
187
  git nested fetch --help
170
188
  ```
171
189
 
190
+ #### `git nested diff`
191
+
192
+ Show the local diff of a nested repo compared to upstream. Fetches the latest upstream
193
+ content first, so it always compares against the freshest available state. Requires that
194
+ there are no uncommitted changes in the outer repository.
195
+
196
+ ```bash
197
+ git nested diff --help
198
+ ```
199
+
200
+ **Example:**
201
+ ```bash
202
+ git nested diff ext/lib
203
+ git nested diff --all # Diff all nested repos
204
+ ```
205
+
172
206
  #### `git nested branch`
173
207
 
174
208
  Create a branch with local nested commits for manual conflict resolution.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: git-nested
3
- Version: 1.0.3
3
+ Version: 1.0.5
4
4
  Summary: Git Submodule Alternative
5
5
  Author-email: Thorsten Klein <thorsten.klein.git@gmail.com>
6
6
  License: MIT
@@ -80,7 +80,25 @@ git-nested now supports nested repositories within nested repositories (recursiv
80
80
  pip install git+https://github.com/thorsten-klein/git-nested
81
81
  ```
82
82
 
83
- #### Method 2: From Source with Shell Integration
83
+ #### Method 2: Standalone Executable (no Python needed)
84
+
85
+ Every [release](https://github.com/thorsten-klein/git-nested/releases) ships
86
+ `git-nested_x64_Linux.tar.xz`: a single file with git-nested, its dependencies
87
+ and a Python interpreter inside. Only git itself has to be installed.
88
+
89
+ ```bash
90
+ curl -L https://github.com/thorsten-klein/git-nested/releases/latest/download/git-nested_x64_Linux.tar.xz | tar -xJ
91
+ sudo install git-nested /usr/local/bin/ # any directory on PATH works
92
+ ```
93
+
94
+ The file has to keep the name `git-nested` — that is how `git nested ...`
95
+ finds it. The archive also contains the completion scripts from `share/`.
96
+
97
+ Built on x86_64 with glibc 2.28, so it runs on any x86_64 Linux from that
98
+ version onwards (Ubuntu 20.04, Debian 10, RHEL/AlmaLinux 8 and newer). Not on
99
+ musl distros such as Alpine.
100
+
101
+ #### Method 3: From Source with Shell Integration
84
102
 
85
103
  Adds git-nested to PATH and enables tab completion:
86
104
 
@@ -90,7 +108,7 @@ echo 'source /path/to/git-nested/.rc' >> ~/.bashrc
90
108
  source ~/.bashrc
91
109
  ```
92
110
 
93
- #### Method 3: From Source (Manual)
111
+ #### Method 4: From Source (Manual)
94
112
 
95
113
  ```bash
96
114
  git clone https://github.com/thorsten-klein/git-nested /path/to/git-nested
@@ -195,6 +213,22 @@ Fetch remote content for a nested repository.
195
213
  git nested fetch --help
196
214
  ```
197
215
 
216
+ #### `git nested diff`
217
+
218
+ Show the local diff of a nested repo compared to upstream. Fetches the latest upstream
219
+ content first, so it always compares against the freshest available state. Requires that
220
+ there are no uncommitted changes in the outer repository.
221
+
222
+ ```bash
223
+ git nested diff --help
224
+ ```
225
+
226
+ **Example:**
227
+ ```bash
228
+ git nested diff ext/lib
229
+ git nested diff --all # Diff all nested repos
230
+ ```
231
+
198
232
  #### `git nested branch`
199
233
 
200
234
  Create a branch with local nested commits for manual conflict resolution.
@@ -8,7 +8,11 @@ LICENSE
8
8
  README.md
9
9
  pyproject.toml
10
10
  uv.lock
11
+ .github/CODEOWNERS
12
+ .github/workflows/build-binary.yml
11
13
  .github/workflows/publish.yml
14
+ .github/workflows/release-binary.yml
15
+ .github/workflows/test-binary.yml
12
16
  .github/workflows/test.yml
13
17
  docs/diagrams.md
14
18
  lib/git-nested
@@ -19,6 +23,7 @@ lib/git_nested.egg-info/dependency_links.txt
19
23
  lib/git_nested.egg-info/entry_points.txt
20
24
  lib/git_nested.egg-info/requires.txt
21
25
  lib/git_nested.egg-info/top_level.txt
26
+ scripts/create-python-exe.sh
22
27
  share/completion.bash
23
28
  share/enable-completion.sh
24
29
  share/git-nested.fish
@@ -28,6 +33,7 @@ test/test_branch.py
28
33
  test/test_clean.py
29
34
  test/test_clone.py
30
35
  test/test_completion.py
36
+ test/test_diff.py
31
37
  test/test_encode.py
32
38
  test/test_error.py
33
39
  test/test_fetch.py