Skip to content

Commit e4453e0

Browse files
vegerotTrae
authored andcommitted
fix(contrib): fix scm-prompt triggering chpwd hooks during directory traversal (#1325)
Summary: Currently, trying to open a new tab in Ghostty within a repository causes the tab to open in the repository root instead of the current working directory. This commit fixes the issue. When scm-prompt.sh walks up the directory tree to find the root of the repository (.sl, .git, or .hg), it uses `builtin cd -P`. In Zsh, executing `cd` (even inside a subshell) triggers all functions registered in `chpwd_functions`. This causes unexpected side effects if a `chpwd` hook performs operations that bypass standard output capture. For example, Ghostty's shell integration registers a `chpwd` hook that writes an OSC 7 escape sequence directly to a persistent TTY file descriptor (/dev/tty) to report the current working directory. Because this writes to the TTY directly, the traversal performed by `scm-prompt.sh` leaks temporary working directories to the terminal emulator, causing Ghostty to open new tabs in the repository root rather than the actual current working directory. By localizing and clearing `chpwd_functions` within the subshell before executing `cd`, we prevent these hooks from firing during the directory traversal, resolving the side effects while keeping the traversal logic intact. Pull Request resolved: #1325 Test Plan: Run this script. Before this commit, it will print the path to the repository root. After this commit, it will print the current working directory. ```sh #!/usr/bin/env zsh # Clear previous output rm -f /tmp/ghostty_bug_repro.txt rm -f /tmp/ghostty_log.txt # Create a self-contained temporary home/zdotdir for this test REPRO_ZDOTDIR=$(mktemp -d) # Write out the minimal reproducible .zshrc cat << 'ZSHRC_EOF' > "$REPRO_ZDOTDIR/.zshrc" # We need prompt_subst to allow function execution in prompt setopt prompt_subst # Load the buggy sapling prompt (assuming it's installed at this path) source ~/workspace/github.com/facebook/sapling/eden/scm/contrib/scm-prompt.sh # Set the prompt to trigger the bug export PS1='$(_scm_prompt) %~ %# ' # To test Ghostty OSC 7 tracking, we need Ghostty shell integration source "$GHOSTTY_RESOURCES_DIR/shell-integration/zsh/ghostty-integration" ZSHRC_EOF # Launch Ghostty with logging and our minimal zshrc # We use ZDOTDIR to point zsh to our custom zshrc GHOSTTY_LOG=stderr ZDOTDIR="$REPRO_ZDOTDIR" /Users/bytedance/workspace/github.com/ghostty-org/ghostty/zig-out/Ghostty.app/Contents/MacOS/ghostty > /tmp/ghostty_log.txt 2>&1 & GHOSTTY_PID=$! # Give it a moment to start sleep 1 # Run the AppleScript to drive the UI osascript << 'APPLESCRIPT' tell application "System Events" tell application "/Users/bytedance/workspace/github.com/ghostty-org/ghostty/zig-out/Ghostty.app" to activate delay 1 -- cd to a deeply nested directory in the sapling repo keystroke "cd ~/workspace/github.com/facebook/sapling/eden/scm/" keystroke return delay 1 -- open a new tab keystroke "t" using command down delay 1 -- get the pwd in the new tab and write it to a file keystroke "pwd > /tmp/ghostty_bug_repro.txt" keystroke return delay 1 -- quit Ghostty keystroke "q" using command down end tell APPLESCRIPT # Read the output echo "The new tab's working directory was:" cat /tmp/ghostty_bug_repro.txt echo "Ghostty PID was $GHOSTTY_PID" echo "Ghostty logs are in: /tmp/ghostty_log.txt" # Clean up rm -rf "$REPRO_ZDOTDIR" ``` Reviewed By: quark-zju Differential Revision: D106557429 fbshipit-source-id: 4b2965dcf49c03deb543af993c1273f3f18057a3 Co-authored-by: Trae <trae@bytedance.com>
1 parent f61baf2 commit e4453e0

1 file changed

Lines changed: 1 addition & 1 deletion

File tree

eden/scm/contrib/scm-prompt.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ _scm_prompt() {
257257
fi
258258
[[ "$dir" = "/" ]] && break
259259
# portable "realpath" equivalent
260-
dir="$(builtin cd -P "$dir/.." >/dev/null && builtin echo "$PWD")"
260+
dir="$(chpwd_functions=(); chpwd() { :; }; builtin cd -P "$dir/.." >/dev/null && builtin echo "$PWD")"
261261
done
262262

263263
if [[ -n "$br" ]]; then

0 commit comments

Comments
 (0)