Scenario: tracing Git commands
Use Git's tracing to inspect the repository operations git-splice runs,
including the commits a push sends. The
design principle explains why
using the user's installed Git matters.
setup.bash builds a splice at lib/ with one commit to push:
$ build_scenario scenario_git_trace
Set GIT_TRACE to an absolute path so Git records each command in that file:
$ GIT_TRACE="$PWD/../trace" git splice status
On branch main
ahead 1 lib
The trace includes discovery and config queries as well as writes.
Filter it to inspect the rebuild: status creates an upstream-shaped
commit to compare, but publishes no ref.
$ sed -n 's/.*trace: built-in: //p' ../trace | grep '^git commit-tree '
git commit-tree --no-gpg-sign 5f5ab219661c5dba1f8904855aaa5867a97f2dc9 -p bde416459fbcc09c9b585f3b65a94cab3f68bfcd
Use a file, not GIT_TRACE=1
GIT_TRACE=1 traces to stderr, and git-splice silences stderr where a failure
is an expected answer, such as asking for a key that isn't set. Those commands
are missing from what you see, such as this one, which every command runs:
$ GIT_TRACE=1 git splice status 2>&1 |
> grep -c -- --show-toplevel
0
[1]
In the file, it's there:
$ grep -c -- --show-toplevel ../trace
1
What a push sends
A file also keeps the commands apart from the output. To see what a push writes,
start with an empty file and look for the commands that write. commit-tree
makes the rebuilt commit, push sends it, and update-ref records that the
upstream has it now:
$ : >../trace &&
> GIT_TRACE="$PWD/../trace" git splice push lib
ok lib: pushed 0fd98a6 to main
$ sed -n 's/.*trace: built-in: //p' ../trace |
> grep -E '^git (commit-tree|push|update-ref) '
git commit-tree --no-gpg-sign 5f5ab219661c5dba1f8904855aaa5867a97f2dc9 -p bde416459fbcc09c9b585f3b65a94cab3f68bfcd
git push --quiet -- https://git.example.com/lib.git 0fd98a6c01e5ee8559e8c043c4593ed9d8dd6271:refs/heads/main
git update-ref --create-reflog refs/splices/lib/heads/main 0fd98a6c01e5ee8559e8c043c4593ed9d8dd6271
The list has more than git-splice's own commands: Git adds the ones it runs
itself, here pack-objects for the push.
What the trace doesn't show
Three things git-splice does without a git command:
initandclone --from-submodulewrite<path>/.spliceto the folder, thengit addandgit commitit, as you would.clone --from-submodulealso removes the submodule's.gitfile and writes the edited.gitmodulesthe same way.- While it records an upstream's key, a folder
.git/splice-keys.lockkeeps othergit-splicecommands from picking the same one. - It writes temporary files outside the repository, for
git config --fileand a temporaryGIT_INDEX_FILE.