Tooling gotcha — do NOT trust RTK-filtered
git log/--graphfor history rewritingWhen RTK (the token-optimizing CLI proxy that auto-rewrites
git …→rtk git …via a Claude Code hook) filtersgit logoutput — especiallygit log --oneline --graph— it drops merge commits from the displayed list. The result is a deceptively linear-looking graph: a merge commit gets collapsed out of view, so a child commit appears to descend from the merge’s first parent’s parent. Trusting this for a squash / rebase / reset operates on the wrong commit range and can lose work.
This gotcha surfaced during git history surgery on esign_css (update/customization/instacash-2026-05-27 branch). See esign-css-instacash-orphan-history for the broader esign_css instacash history shape.
The symptom (concrete case)
RTK-filtered git log --oneline --graph rendered an apparently linear chain and collapsed merge commit 27e6cc7 (a real two-parent merge) out of the displayed list. This made it look like:
9cce25f’s parent was5d5b407
…when its actual parent was the merge 27e6cc7. Operating on the visible “parent” would have squashed/reset across the merge boundary and dropped a parent’s worth of history.
Why it happens
RTK’s output filter elides commit lines it treats as noise; merge commits’ own list lines get filtered, so a merge silently disappears from --oneline/--graph even though it is structurally present in the DAG.
Reliable patterns for git surgery under RTK
Use parent-aware / plumbing commands that survive filtering
These expose the real DAG even when a merge’s own log line is filtered out.
Expose parents in the log itself (the %p field shows actual parent SHAs, so merges are visible by their 2+ parents even if their own list line is filtered):
git log --pretty='%h | %p | %s'Filter-proof plumbing (porcelain-free, RTK leaves these intact):
git rev-list --parents -n 1 <sha> # one commit's parents (2+ SHAs = a merge)
git rev-list --count A..B # exact commit count in a range
git rev-parse <sha> # resolve a ref to a full SHA
git rev-parse '<sha>^{tree}' # the tree (content) hash at a commitrtk proxy <cmd> runs a raw, unfiltered command — but the user may prefer you avoid it; reach for the parent-aware / plumbing commands above first.
Verify a squash/rebase preserved content — compare TREE hashes
For Agents
A squash or rebase must change history only, never content. Prove zero content change by comparing the tree hash before and after — an identical tree hash is cryptographic proof the working content is byte-identical.
git rev-parse 'HEAD^{tree}' # capture BEFORE the operation
# … perform the squash / rebase …
git rev-parse 'HEAD^{tree}' # must equal the captured valueIf the two tree hashes match, only the history was restructured. If they differ, content changed — stop and investigate.
Reusable technique — non-interactive squash of the latest N commits
git rebase -i is unavailable in this harness, so squash the latest N commits with a soft reset instead:
git branch backup/<name> HEAD # 1. backup ref first — trivial rollback
git diff --cached --quiet # 2. guard: nothing staged (must exit 0)
ORIG=$(git rev-parse 'HEAD^{tree}') # capture original tree hash
git reset --soft <base> # 3. move HEAD back, keep all changes staged
git commit -m "<msg>" # 4. one new commit on top of <base>
test "$(git rev-parse 'HEAD^{tree}')" = "$ORIG" && echo OK # 5. tree-hash equality<base>is the commit you want the single squashed commit to sit on top of — derive it fromgit log --pretty='%h | %p | %s'orgit rev-list --parents, not from a filtered--graph.- Step 1 (backup ref) makes rollback
git reset --hard backup/<name>. - Step 2 ensures the squash doesn’t silently absorb unrelated staged changes.
- Step 5 is the proof gate — identical tree hash means zero content change, history-only restructure.
Related
- esign-css-instacash-orphan-history — esign_css
customization/instacashis a single squashed orphan; same family of “the usual git tooling misleads you here” hazards (no merge base, meaninglessrev-list --count A..B). - RTK — the token-optimizing proxy whose output filtering causes this gotcha.
- instacash-update-2026-05-27-status — the 2026-05-27 InstaCash devel-update wave during which this surgery happened.
- esign — esign_css / eSign service overview.