-
Notifications
You must be signed in to change notification settings - Fork 939
Shell Prompt
Tip
Fish shell users or Starship prompt users should review those pages instead as they have more specific advice. Note that Starship is a tool that supports multiple shell engines, including Bash and ZSH.
ZSH users can also use rkh/zsh-jj for vcs_info integration. Additional approaches for zsh with powerlevel10k have been documented by André Arko and Nathan Witmer.
Some users like to have information about the current repository status printed out with every shell prompt. The following is example code that defines a shell function to check for the presence of a jj or Git repository, prints useful information about the repository, and adds the function to the PS1 prompt in bash or zsh.
# Dedicated to the Public Domain under the Unlicense: https://unlicense.org/UNLICENSE
# Print Git or jj repository information
jjgit_prompt()
{
local jjgit gitprompt
# echo "jj" or "git" if either is found in $PWD or its parent directories
pwd_in_jjgit() {
# using the shell is much faster than `git rev-parse --git-dir` or `jj root`
local D="$PWD"
while test -n "$D"
do
test -e "$D/.jj" && { echo jj ; return ; }
test -e "$D/.git" && { echo git ; return ; }
D="${D%/*}"
done
}
jjgit="$(pwd_in_jjgit)" # results in "jj", "git" or ""
if test "$jjgit" = jj
then
# --ignore-working-copy: avoid inspecting $PWD and concurrent snapshotting which could create divergent commits
printf '%s' "$(
jj --ignore-working-copy --no-pager log --no-graph --color=always -r @ -T \
' "jj:[@ " ++ concat( separate(" ", format_short_change_id_with_change_offset(self),format_short_commit_id(commit_id),
bookmarks,if(conflict,label("conflict","conflict"))))++"]" ' 2>/dev/null
)"
elif test "$jjgit" = git
then
# --no-pager: never use a pager for the prompt, regardless of user config
gitprompt=$(git --no-pager log -1 --color=always --pretty='%C(auto)%h ꜓%C(auto)%(decorate:prefix=,suffix=,tag=,pointer=→,separator=))' 2> /dev/null)
printf '%s' "git:[${gitprompt/HEAD/}]"
fi
}
# Add jjgit_prompt to PS1
if test -n "$precmd_functions"
then
# zsh (This part is correct, as Zsh uses precmd_functions)
ps1_jjgit_prompt() { PS1="$(jjgit_prompt)""$PS1" ; }
precmd_functions=("${precmd_functions[@]/jjgit_prompt}") # remove old version
precmd_functions+=(ps1_jjgit_prompt) # add new prompt function
else
# bash
if [[ $PROMPT_COMMAND != *update_ps1_jjgit* ]]; then
update_ps1_jjgit() {
PS1="\[$(jjgit_prompt)\]📦[\u@\h \W]$ "
}
PROMPT_COMMAND="update_ps1_jjgit${PROMPT_COMMAND:+; $PROMPT_COMMAND}"
fi
fiTo convert a Git repository into a jj repository, use jj git init --colocate.