< Back to all hacks

#03 Git Wrapper Bridge

Infrastructure
Problem
npm needs git for some dependencies but git can't install in proot (dpkg broken on ARM32).
Solution
Wrapper script at /usr/local/bin/git that calls Termux's native git binary via the proot bind mount.
Lesson
proot bind-mounts give access to Termux binaries inside the chroot — use wrapper scripts to bridge the gap.

Context

Several npm packages specify git repositories as dependencies (e.g., "package": "git+https://github.com/..."). When npm encounters these, it shells out to git to clone the repository. Inside the proot Ubuntu environment, git isn't available — apt install git fails because dpkg's ARM32 support in proot is broken for packages with complex post-install scripts.

However, proot works by bind-mounting the host filesystem. Termux's native binaries at /data/data/com.termux/files/usr/bin/ are accessible from inside proot at the same path. We can create a wrapper script that redirects git calls to Termux's native git binary.

This hack is LEGACY — superseded by native gateway migration (Hack #12) which doesn't use proot.

Implementation

Create a wrapper script inside the proot environment that calls through to Termux's native git:

# Inside proot (proot-distro login ubuntu):

# Create the wrapper directory
mkdir -p /usr/local/bin

# Create the git wrapper
cat > /usr/local/bin/git << 'EOF'
#!/bin/bash
# Git bridge — calls Termux's native git through proot bind mount
exec /data/data/com.termux/files/usr/bin/git "$@"
EOF

# Make it executable
chmod +x /usr/local/bin/git

Verify that /usr/local/bin is in the PATH (it should be by default on Ubuntu):

# Check PATH includes /usr/local/bin
echo $PATH | tr ':' '\n' | grep local
# Expected: /usr/local/bin

# If not, add to .bashrc:
echo 'export PATH="/usr/local/bin:$PATH"' >> ~/.bashrc

Verification

# Inside proot — test the wrapper:
git --version
# Expected: git version 2.x.x (Termux's version)

# Test that npm can use git:
npm ls 2>&1 | head -5
# Expected: no "git not found" errors

# Test a git clone operation:
git clone --depth 1 https://github.com/test/repo.git /tmp/test-repo
# Expected: successful clone

Gotchas

  • The wrapper only works if proot bind-mounts include the Termux prefix. Default proot-distro configuration does this automatically
  • Git operations that create files (clone, checkout) work correctly because proot translates paths transparently
  • Some git operations may have issues with path lengths due to proot's path translation overhead
  • Later replaced by a more sophisticated git wrapper (Hack #4) that handles argument parsing for edge cases, and then by sed-based path rewriting (Hack #11)

Result

MetricBeforeAfter
git inside prootNot availableWorking via bridge
npm git dependenciesFailInstall correctly
Extra disk space00 (just a script)