summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClaudio Bandera <claudio.bandera@kit.edu>2015-10-16 16:49:10 +0200
committerClaudio Bandera <claudio.bandera@kit.edu>2015-10-16 16:49:10 +0200
commit5fd8e9dbdb540e8418bae51b882c7fd90458c13b (patch)
tree2b8ce9697b269eef1fb3490f95b67947facc27f5
parenta7f6b47969e9c734ff28f5b49fdbbee6a6095b93 (diff)
parentf043242a00cc9a178ffa8205462c9cd61ffe36b2 (diff)
downloadgit-sonar-5fd8e9dbdb540e8418bae51b882c7fd90458c13b.tar.gz
git-sonar-5fd8e9dbdb540e8418bae51b882c7fd90458c13b.zip
Merge remote-tracking branch 'upstream/master' into hotfix/unittests
-rw-r--r--README.md69
-rwxr-xr-xprompt.bash9
-rwxr-xr-xprompt.zsh9
-rwxr-xr-xradar-base.sh83
-rwxr-xr-xtest1
-rwxr-xr-xtest-colors.sh28
-rwxr-xr-xtest-commits.sh18
-rwxr-xr-xtest-format-config.sh234
-rwxr-xr-xtest-performance.sh231
9 files changed, 620 insertions, 62 deletions
diff --git a/README.md b/README.md
index 1538681..7686edb 100644
--- a/README.md
+++ b/README.md
@@ -17,6 +17,7 @@ last few years. Maybe it can help you too.
- [Local commits status](#local-commits-status)
- [Remote commits status](#remote-commits-status)
- [(Optional) Auto-fetch repos](#optional-auto-fetch-repos)
+- [Customise your prompt](#customise-your-prompt)
- [Support](#support)
- [Ensuring prompt execution](#ensuring-prompt-execution)
- [Configuring colours](#configuring-colours)
@@ -76,7 +77,7 @@ Add to your `config.fish`
function fish_prompt
set_color $fish_color_cwd
echo -n (prompt_pwd)
- git-radar --fish -fetch
+ git-radar --fish --fetch
set_color normal
echo -n ' > '
end
@@ -120,6 +121,9 @@ Red | Unstaged, you'll need to `git add` them before you can commit
Grey | Untracked, these are new files git is unaware of
Yellow | Conflicted, these need resolved before they can be committed
+The use of feature is controlled by the `GIT_RADAR_FORMAT` environment variable.
+See [Customise your prompt](#customise-your-prompt) for how to personalise this.
+
### Local commits status
The prompt will show you the difference in commits between your branch and the
@@ -132,6 +136,9 @@ Prompt | Meaning
![git:(master 3↓)] | We have 3 commits to pull down
![git:(master 3⇵5)] | Our version and origins version of `master` have diverged
+The use of feature is controlled by the `GIT_RADAR_FORMAT` environment variable.
+See [Customise your prompt](#customise-your-prompt) for how to personalise this.
+
### Remote commits status
The prompt will also show the difference between your branch on origin and what
@@ -146,19 +153,11 @@ Prompt | Meaning
![git:(m 4 → my-branch)] | There are 4 commits on `origin/master` that aren't on `origin/my-branch`
![git:(m 1 ⇄ 2 my-branch)] | `origin/master` and `origin/my-branch` have diverged, we'll need to rebase or merge
-If you don't rely on this status, you can always hide this part of the prompt by calling git-radar with `--no-remote-status`.
-
-**Bash**
-```bash
-export PS1="$PS1\$(git-radar --bash --fetch --no-remote-status) "
-```
-[(note: the `\` escaping the `$` is important)](#ensuring-prompt-execution)
+The use of feature is controlled by the `GIT_RADAR_FORMAT` environment variable.
+See [Customise your prompt](#customise-your-prompt) for how to personalise this.
-**Zsh**
-```zsh
-export PROMPT="$PROMPT\$(git-radar --zsh --fetch --no-remote-status) "
-```
-[(note: the `\` escaping the `$` is important)](#ensuring-prompt-execution)
+If you don't rely on this status, you can always hide this part of the prompt by
+[customising your prompt](#customise-your-prompt)
### (Optional) Auto-fetch repos
@@ -183,6 +182,50 @@ export PROMPT="$PROMPT\$(git-radar --zsh --fetch) "
```
[(note: the `\` escaping the `$` is important)](#ensuring-prompt-execution)
+## Customise your prompt
+
+Git Radar is highly customisable using a prompt format string. The 4 features
+above: remote commits, local commits, branch and file changes; are controlled
+by the prompt format string.
+
+Feature | Control string
+---------------|---------------
+Remote commits | `%{remote}`
+Local commits | `%{local}`
+Branch | `%{branch}`
+File changes | `%{changes}`
+
+You can create any prompt shape you prefer by exporting `GIT_RADAR_FORMAT` with
+your preferred shape. The control strings above will be replaced with the output
+of the corresponding feature.
+
+**Examples**
+
+GIT_RADAR_FORMAT | Result
+--------------------------------------|---------------------
+`%{branch}%{local}%{changes}` | `master1↑1M`
+`[%{branch}] - %{local} - %{changes}` | `[master] - 1↑ - 1M`
+
+### Prefixing and Suffixing the features
+
+Often you will want certain parts of the prompt to only appear when there is
+content to render. For example, when in a repo you want `[branch]` but when out
+of a repo you don't want the `[]` appearing.
+
+To do this the control strings support prefixes and suffixes. Prefixes and
+Suffixes are separated from the feature name by `:` and will only render if the
+feature would render:
+
+Format: `prompt > %{prefix - :changes: - suffix}`
+
+In a repo: `prompt > prefix - 1M - suffix`
+
+Outside a repo: `prompt > `
+
+The default prompt format uses this to add spaces only if the feature would
+render. In that way the prompt always looks well spaced out no matter how many
+features are rendering.
+
## Support
### Ensuring prompt execution
diff --git a/prompt.bash b/prompt.bash
index 51c4db7..444ad7a 100755
--- a/prompt.bash
+++ b/prompt.bash
@@ -6,12 +6,5 @@ source "$dot/radar-base.sh"
if is_repo; then
prepare_bash_colors
- printf " \x01\033[1;30m\x02git:(\x01\033[0m\x02"
- if show_remote_status $args; then
- color_remote_commits
- fi
- readable_branch_name
- color_local_commits
- printf "\x01\033[1;30m\x02)\x01\033[0m\x02"
- color_changes_status
+ render_prompt
fi
diff --git a/prompt.zsh b/prompt.zsh
index 2d31820..c2b175a 100755
--- a/prompt.zsh
+++ b/prompt.zsh
@@ -8,12 +8,5 @@ if is_repo; then
autoload colors && colors
prepare_zsh_colors
- printf '%s' "%{$fg_bold[black]%} git:(%{$reset_color%}"
- if show_remote_status $args; then
- color_remote_commits
- fi
- readable_branch_name
- color_local_commits
- printf '%s' "%{$fg_bold[black]%})%{$reset_color%}"
- color_changes_status
+ render_prompt
fi
diff --git a/radar-base.sh b/radar-base.sh
index f346b26..3ffc800 100755
--- a/radar-base.sh
+++ b/radar-base.sh
@@ -5,6 +5,14 @@ cwd=""
remote=""
rcfile_path="$HOME"
+timethis() {
+ cmd="$@"
+ start=$(gdate +%s.%N)
+ eval $cmd
+ dur=$(echo "$(gdate +%s.%N) - $start" | bc)
+ echo "$1 - $dur" >> $HOME/duration.dat
+}
+
prepare_bash_colors() {
if [ -f "$rcfile_path/.gitradarrc.bash" ]; then
source "$rcfile_path/.gitradarrc.bash"
@@ -31,6 +39,8 @@ prepare_bash_colors() {
COLOR_BRANCH="\x01${GIT_RADAR_COLOR_BRANCH:-"\\033[0m"}\x02"
MASTER_SYMBOL="${GIT_RADAR_MASTER_SYMBOL:-"\\x01\\033[0m\\x02\\xF0\\x9D\\x98\\xAE\\x01\\033[0m\\x02"}"
+ PROMPT_FORMAT="${GIT_RADAR_FORMAT:-" \\x01\\033[1;30m\\x02git:(\\x01\\033[0m\\x02%{remote: }%{branch}%{ :local}\\x01\\033[1;30m\\x02)\\x01\\033[0m\\x02%{ :changes}"}"
+
RESET_COLOR_LOCAL="\x01${GIT_RADAR_COLOR_LOCAL_RESET:-"\\033[0m"}\x02"
RESET_COLOR_REMOTE="\x01${GIT_RADAR_COLOR_REMOTE_RESET:-"\\033[0m"}\x02"
RESET_COLOR_CHANGES="\x01${GIT_RADAR_COLOR_CHANGES_RESET:-"\\033[0m"}\x02"
@@ -65,6 +75,8 @@ prepare_zsh_colors() {
COLOR_BRANCH="%{${GIT_RADAR_COLOR_BRANCH:-$reset_color}%}"
MASTER_SYMBOL="${GIT_RADAR_MASTER_SYMBOL:-"%{$reset_color%}$italic_m%{$reset_color%}"}"
+ PROMPT_FORMAT="${GIT_RADAR_FORMAT:-" %{$fg_bold[grey]%}git:(%{$reset_color%}%{remote: }%{branch}%{ :local}%{$fg_bold[grey]%})%{$reset_color%}%{ :changes}"}"
+
RESET_COLOR_LOCAL="%{${GIT_RADAR_COLOR_LOCAL_RESET:-$reset_color}%}"
RESET_COLOR_REMOTE="%{${GIT_RADAR_COLOR_REMOTE_RESET:-$reset_color}%}"
RESET_COLOR_CHANGES="%{${GIT_RADAR_COLOR_CHANGES_RESET:-$reset_color}%}"
@@ -395,7 +407,7 @@ color_changes_status() {
changes="$staged_changes$conflicted_changes$unstaged_changes$untracked_changes"
fi
- printf $PRINT_F_OPTION "$changes"
+ printf $PRINT_F_OPTION "${changes:1}"
}
bash_color_changes_status() {
@@ -407,8 +419,6 @@ zsh_color_changes_status() {
}
color_local_commits() {
- local separator="${1:- }"
-
local green_ahead_arrow="${COLOR_LOCAL_AHEAD}↑$RESET_COLOR_LOCAL"
local red_behind_arrow="${COLOR_LOCAL_BEHIND}↓$RESET_COLOR_LOCAL"
local yellow_diverged_arrow="${COLOR_LOCAL_DIVERGED}⇵$RESET_COLOR_LOCAL"
@@ -419,11 +429,11 @@ color_local_commits() {
local_behind="$(commits_behind_of_remote "$remote_branch")"
if [[ "$local_behind" -gt "0" && "$local_ahead" -gt "0" ]]; then
- local_commits="$separator$local_behind$yellow_diverged_arrow$local_ahead"
+ local_commits="$local_behind$yellow_diverged_arrow$local_ahead"
elif [[ "$local_behind" -gt "0" ]]; then
- local_commits="$separator$local_behind$red_behind_arrow"
+ local_commits="$local_behind$red_behind_arrow"
elif [[ "$local_ahead" -gt "0" ]]; then
- local_commits="$separator$local_ahead$green_ahead_arrow"
+ local_commits="$local_ahead$green_ahead_arrow"
fi
fi
printf $PRINT_F_OPTION "$local_commits"
@@ -448,14 +458,14 @@ color_remote_commits() {
remote_behind="$(remote_behind_of_master "$remote_branch")"
if [[ "$remote_behind" -gt "0" && "$remote_ahead" -gt "0" ]]; then
- remote="$MASTER_SYMBOL $remote_behind $yellow_diverged_arrow $remote_ahead "
+ remote="$MASTER_SYMBOL $remote_behind $yellow_diverged_arrow $remote_ahead"
elif [[ "$remote_ahead" -gt "0" ]]; then
- remote="$MASTER_SYMBOL $green_ahead_arrow $remote_ahead "
+ remote="$MASTER_SYMBOL $green_ahead_arrow $remote_ahead"
elif [[ "$remote_behind" -gt "0" ]]; then
- remote="$MASTER_SYMBOL $remote_behind $red_behind_arrow "
+ remote="$MASTER_SYMBOL $remote_behind $red_behind_arrow"
fi
else
- remote="upstream $not_upstream "
+ remote="upstream $not_upstream"
fi
printf $PRINT_F_OPTION "$remote"
@@ -489,3 +499,56 @@ show_remote_status() {
fi
return 0
}
+
+render_prompt() {
+ output="$PROMPT_FORMAT"
+ branch_sed=""
+ remote_sed=""
+ local_sed=""
+ changes_sed=""
+
+
+ if_pre="%\{([^%{}]{1,}:){0,1}"
+ if_post="(:[^%{}]{1,}){0,1}\}"
+ sed_pre="%{\(\([^%^{^}]*\)\:\)\{0,1\}"
+ sed_post="\(\:\([^%^{^}]*\)\)\{0,1\}}"
+
+ if [[ $output =~ ${if_pre}remote${if_post} ]]; then
+ remote_result="$(color_remote_commits)"
+ if [[ -n "$remote_result" ]]; then
+ remote_sed="s/${sed_pre}remote${sed_post}/\2${remote_result}\4/"
+ else
+ remote_sed="s/${sed_pre}remote${sed_post}//"
+ fi
+ fi
+ if [[ $PROMPT_FORMAT =~ ${if_pre}branch${if_post} ]]; then
+ branch_result="$(readable_branch_name | sed -e 's/\//\\\//')"
+ if [[ -n "$branch_result" ]]; then
+ branch_sed="s/${sed_pre}branch${sed_post}/\2${branch_result}\4/"
+ else
+ branch_sed="s/${sed_pre}branch${sed_post}//"
+ fi
+ fi
+ if [[ $PROMPT_FORMAT =~ ${if_pre}local${if_post} ]]; then
+ local_result="$(color_local_commits)"
+ if [[ -n "$local_result" ]]; then
+ local_sed="s/${sed_pre}local${sed_post}/\2$local_result\4/"
+ else
+ local_sed="s/${sed_pre}local${sed_post}//"
+ fi
+ fi
+ if [[ $PROMPT_FORMAT =~ ${if_pre}changes${if_post} ]]; then
+ changes_result="$(color_changes_status)"
+ if [[ -n "$changes_result" ]]; then
+ changes_sed="s/${sed_pre}changes${sed_post}/\2${changes_result}\4/"
+ else
+ changes_sed="s/${sed_pre}changes${sed_post}//"
+ fi
+ fi
+
+ printf '%b' "$output" | sed \
+ -e "$remote_sed" \
+ -e "$branch_sed" \
+ -e "$changes_sed" \
+ -e "$local_sed"
+}
diff --git a/test b/test
index 4efeafd..87cba9b 100755
--- a/test
+++ b/test
@@ -7,3 +7,4 @@
./test-files.sh
./test-status.sh
./test-colors.sh
+./test-format-config.sh
diff --git a/test-colors.sh b/test-colors.sh
index 116e09d..f234ca9 100755
--- a/test-colors.sh
+++ b/test-colors.sh
@@ -292,14 +292,14 @@ test_bash_colors_local() {
git add .
git commit -m "test commit" --quiet
- printf -v expected " 1\x01local-ahead\x02↑\x01local-reset\x02"
+ printf -v expected "1\x01local-ahead\x02↑\x01local-reset\x02"
assertEquals "$expected" "$(bash_color_local_commits)"
assertEquals "$expected" "$(color_local_commits)"
git push --quiet >/dev/null
git reset --hard HEAD^ --quiet >/dev/null
- printf -v expected " 1\x01local-behind\x02↓\x01local-reset\x02"
+ printf -v expected "1\x01local-behind\x02↓\x01local-reset\x02"
assertEquals "$expected" "$(bash_color_local_commits)"
assertEquals "$expected" "$(color_local_commits)"
@@ -307,7 +307,7 @@ test_bash_colors_local() {
git add .
git commit -m "new commit" --quiet
- printf -v expected " 1\x01local-diverged\x02⇵\x01local-reset\x021"
+ printf -v expected "1\x01local-diverged\x02⇵\x01local-reset\x021"
assertEquals "$expected" "$(bash_color_local_commits)"
assertEquals "$expected" "$(color_local_commits)"
@@ -338,18 +338,18 @@ test_zsh_colors_local() {
git add .
git commit -m "test commit" --quiet
- assertEquals " 1%{local-ahead%}↑%{local-reset%}" "$(zsh_color_local_commits)"
+ assertEquals "1%{local-ahead%}↑%{local-reset%}" "$(zsh_color_local_commits)"
git push --quiet >/dev/null
git reset --hard HEAD^ --quiet >/dev/null
- assertEquals " 1%{local-behind%}↓%{local-reset%}" "$(zsh_color_local_commits)"
+ assertEquals "1%{local-behind%}↓%{local-reset%}" "$(zsh_color_local_commits)"
echo "foo" > foo
git add .
git commit -m "new commit" --quiet
- assertEquals " 1%{local-diverged%}⇵%{local-reset%}1" "$(zsh_color_local_commits)"
+ assertEquals "1%{local-diverged%}⇵%{local-reset%}1" "$(zsh_color_local_commits)"
rm_tmp
}
@@ -381,7 +381,7 @@ test_bash_colors_remote() {
git checkout -b mybranch --quiet
git push --quiet -u origin mybranch >/dev/null
- printf -v expected "m 1 \x01remote-behind\x02→\x01remote-reset\x02 "
+ printf -v expected "m 1 \x01remote-behind\x02→\x01remote-reset\x02"
assertEquals "$expected" "$(bash_color_remote_commits)"
assertEquals "$expected" "$(color_remote_commits)"
@@ -390,14 +390,14 @@ test_bash_colors_remote() {
git commit -m "new commit" --quiet
git push --quiet origin mybranch >/dev/null
- printf -v expected "m 1 \x01remote-diverged\x02⇄\x01remote-reset\x02 1 "
+ printf -v expected "m 1 \x01remote-diverged\x02⇄\x01remote-reset\x02 1"
assertEquals "$expected" "$(bash_color_remote_commits)"
assertEquals "$expected" "$(color_remote_commits)"
git pull origin master --quiet >/dev/null
git push --quiet >/dev/null
- printf -v expected "m \x01remote-ahead\x02←\x01remote-reset\x02 2 "
+ printf -v expected "m \x01remote-ahead\x02←\x01remote-reset\x02 2"
assertEquals "$expected" "$(bash_color_remote_commits)"
assertEquals "$expected" "$(color_remote_commits)"
@@ -431,19 +431,19 @@ test_zsh_colors_remote() {
git checkout -b mybranch --quiet
git push --quiet -u origin mybranch >/dev/null
- assertEquals "m 1 %{remote-behind%}→%{remote-reset%} " "$(zsh_color_remote_commits)"
+ assertEquals "m 1 %{remote-behind%}→%{remote-reset%}" "$(zsh_color_remote_commits)"
echo "bar" > bar
git add .
git commit -m "new commit" --quiet
git push --quiet >/dev/null
- assertEquals "m 1 %{remote-diverged%}⇄%{remote-reset%} 1 " "$(zsh_color_remote_commits)"
+ assertEquals "m 1 %{remote-diverged%}⇄%{remote-reset%} 1" "$(zsh_color_remote_commits)"
git pull origin master --quiet >/dev/null
git push --quiet >/dev/null
- assertEquals "m %{remote-ahead%}←%{remote-reset%} 2 " "$(zsh_color_remote_commits)"
+ assertEquals "m %{remote-ahead%}←%{remote-reset%} 2" "$(zsh_color_remote_commits)"
rm_tmp
}
@@ -464,7 +464,7 @@ test_bash_colors_changes() {
unstaged="1\x01changes-unstaged\x02M\x01change-reset\x02"
staged="1\x01changes-staged\x02A\x01change-reset\x02"
- printf -v expected " $staged $unstaged $untracked"
+ printf -v expected "$staged $unstaged $untracked"
assertEquals "$expected" "$(bash_color_changes_status)"
assertEquals "$expected" "$(color_changes_status)"
rm_tmp
@@ -486,7 +486,7 @@ test_zsh_colors_changes() {
unstaged="1%{changes-unstaged%}M%{change-reset%}"
staged="1%{changes-staged%}A%{change-reset%}"
- assertEquals " $staged $unstaged $untracked" "$(zsh_color_changes_status)"
+ assertEquals "$staged $unstaged $untracked" "$(zsh_color_changes_status)"
rm_tmp
}
diff --git a/test-commits.sh b/test-commits.sh
index c97c56a..7634103 100755
--- a/test-commits.sh
+++ b/test-commits.sh
@@ -410,9 +410,9 @@ test_local_commits() {
git add .
git commit -m "test commit" --quiet
- assertEquals " 1$up" "$(zsh_color_local_commits)"
- assertEquals " 1$up" "$(bash_color_local_commits)"
- assertEquals " 1$up" "$(color_local_commits)"
+ assertEquals "1$up" "$(zsh_color_local_commits)"
+ assertEquals "1$up" "$(bash_color_local_commits)"
+ assertEquals "1$up" "$(color_local_commits)"
cd "$remote"
echo "foo" > foo
@@ -422,15 +422,15 @@ test_local_commits() {
cd "$repo"
git fetch origin --quiet
- assertEquals " 1${both}1" "$(zsh_color_local_commits)"
- assertEquals " 1${both}1" "$(bash_color_local_commits)"
- assertEquals " 1${both}1" "$(color_local_commits)"
+ assertEquals "1${both}1" "$(zsh_color_local_commits)"
+ assertEquals "1${both}1" "$(bash_color_local_commits)"
+ assertEquals "1${both}1" "$(color_local_commits)"
git reset --hard HEAD^ --quiet
- assertEquals " 1$down" "$(zsh_color_local_commits)"
- assertEquals " 1$down" "$(bash_color_local_commits)"
- assertEquals " 1$down" "$(color_local_commits)"
+ assertEquals "1$down" "$(zsh_color_local_commits)"
+ assertEquals "1$down" "$(bash_color_local_commits)"
+ assertEquals "1$down" "$(color_local_commits)"
}
. ./shunit/shunit2
diff --git a/test-format-config.sh b/test-format-config.sh
new file mode 100755
index 0000000..5504ebc
--- /dev/null
+++ b/test-format-config.sh
@@ -0,0 +1,234 @@
+scriptDir="$(cd "$(dirname "$0")"; pwd)"
+
+source "$scriptDir/radar-base.sh"
+
+cd_to_tmp() {
+ tmpfile="/tmp/git-prompt-tests-$(time_now)$1"
+ mkdir -p "$tmpfile"
+ cd "$tmpfile"
+}
+
+rm_tmp() {
+ cd $scriptDir
+ rm -rf /tmp/git-prompt-tests*
+}
+
+unset_colours() {
+ export COLOR_REMOTE_AHEAD=""
+ export COLOR_REMOTE_BEHIND=""
+ export COLOR_REMOTE_DIVERGED=""
+ export COLOR_REMOTE_NOT_UPSTREAM=""
+
+ export COLOR_LOCAL_AHEAD=""
+ export COLOR_LOCAL_BEHIND=""
+ export COLOR_LOCAL_DIVERGED=""
+
+ export COLOR_CHANGES_STAGED=""
+ export COLOR_CHANGES_UNSTAGED=""
+ export COLOR_CHANGES_CONFLICTED=""
+ export COLOR_CHANGES_UNTRACKED=""
+
+ export COLOR_BRANCH=""
+ export MASTER_SYMBOL="m"
+
+ export RESET_COLOR_LOCAL=""
+ export RESET_COLOR_REMOTE=""
+ export RESET_COLOR_CHANGES=""
+ export RESET_COLOR_BRANCH=""
+}
+
+prepare_test_repo() {
+ cd_to_tmp "remote"
+
+ git init --quiet
+ touch README
+ git add .
+ git commit -m "initial commit" --quiet
+ origin="$(pwd)"
+
+ cd_to_tmp "new"
+ git init --quiet
+ git remote add origin $origin
+ git fetch origin --quiet
+ git checkout master --quiet
+ git checkout -b foo --quiet
+ git push --quiet -u origin foo >/dev/null
+ repo="$(pwd)"
+
+ cd "$origin"
+ echo "foo" > foo
+ git add .
+ git commit -m "remote commit" --quiet
+ cd "$repo"
+ echo "foo" > foo
+ git add .
+ git commit -m "local commit" --quiet
+ echo "foo" > bar
+ git fetch origin --quiet
+}
+
+test_all_options_set_config() {
+ cd_to_tmp "empty"
+ export GIT_RADAR_FORMAT="%{branch}%{local}%{changes}"
+ # Don't test remote as in no repo you will get upstream error message
+ prepare_zsh_colors
+ unset_colours
+
+ prompt="$(render_prompt)"
+ assertEquals "$prompt" ""
+
+ export GIT_RADAR_FORMAT="%{remote}"
+ # Don't test remote as in no repo you will get upstream error message
+ prepare_zsh_colors
+ unset_colours
+
+ prompt="$(render_prompt)"
+ assertEquals "$prompt" "upstream ⚡"
+ prepare_test_repo
+
+ export GIT_RADAR_FORMAT="%{remote}%{branch}%{local}%{changes}"
+ prepare_zsh_colors
+ unset_colours
+
+ prompt="$(render_prompt)"
+ assertEquals "$prompt" "m 1 →foo1↑1A"
+
+ export GIT_RADAR_FORMAT="%{remote}%{branch}%{changes}"
+ prepare_zsh_colors
+ unset_colours
+
+ prompt="$(render_prompt)"
+ assertEquals "$prompt" "m 1 →foo1A"
+
+ export GIT_RADAR_FORMAT="%{branch}%{local}%{changes}"
+ prepare_zsh_colors
+ unset_colours
+
+ prompt="$(render_prompt)"
+ assertEquals "$prompt" "foo1↑1A"
+
+ export GIT_RADAR_FORMAT="%{branch}%{changes}"
+ prepare_zsh_colors
+ unset_colours
+
+ prompt="$(render_prompt)"
+ assertEquals "$prompt" "foo1A"
+
+ export GIT_RADAR_FORMAT="%{branch}"
+ prepare_zsh_colors
+ unset_colours
+
+ prompt="$(render_prompt)"
+ assertEquals "$prompt" "foo"
+
+ rm_tmp
+}
+
+test_reorder_parts() {
+ prepare_test_repo
+
+ export GIT_RADAR_FORMAT="%{branch}%{local}%{changes}%{remote}"
+ prepare_zsh_colors
+ unset_colours
+
+ prompt="$(render_prompt)"
+ assertEquals "foo1↑1Am 1 →" "$prompt"
+
+ export GIT_RADAR_FORMAT="%{local}%{changes}%{remote}%{branch}"
+ prepare_zsh_colors
+ unset_colours
+
+ prompt="$(render_prompt)"
+ assertEquals "1↑1Am 1 →foo" "$prompt"
+
+ export GIT_RADAR_FORMAT="%{changes}%{remote}%{branch}%{local}"
+ prepare_zsh_colors
+ unset_colours
+
+ prompt="$(render_prompt)"
+ assertEquals "1Am 1 →foo1↑" "$prompt"
+
+ rm_tmp
+}
+
+test_prefix_and_suffix_changes() {
+ prepare_test_repo
+
+ export GIT_RADAR_FORMAT="%{changes}"
+ prepare_zsh_colors
+ unset_colours
+
+ prompt="$(render_prompt)"
+ assertEquals "1A" "$prompt"
+
+ export GIT_RADAR_FORMAT="%{[:changes:]}"
+ prepare_zsh_colors
+ unset_colours
+
+ prompt="$(render_prompt)"
+ assertEquals "[1A]" "$prompt"
+
+ rm_tmp
+}
+
+test_prefix_and_suffix_local() {
+ prepare_test_repo
+
+ export GIT_RADAR_FORMAT="%{local}"
+ prepare_zsh_colors
+ unset_colours
+
+ prompt="$(render_prompt)"
+ assertEquals "1↑" "$prompt"
+
+ export GIT_RADAR_FORMAT="%{[:local:]}"
+ prepare_zsh_colors
+ unset_colours
+
+ prompt="$(render_prompt)"
+ assertEquals "[1↑]" "$prompt"
+
+ rm_tmp
+}
+
+test_prefix_and_suffix_branch() {
+ prepare_test_repo
+
+ export GIT_RADAR_FORMAT="%{branch}"
+ prepare_zsh_colors
+ unset_colours
+
+ prompt="$(render_prompt)"
+ assertEquals "foo" "$prompt"
+
+ export GIT_RADAR_FORMAT="%{[:branch:]}"
+ prepare_zsh_colors
+ unset_colours
+
+ prompt="$(render_prompt)"
+ assertEquals "[foo]" "$prompt"
+
+ rm_tmp
+}
+
+test_prefix_and_suffix_remote() {
+ prepare_test_repo
+
+ export GIT_RADAR_FORMAT="%{remote}"
+ prepare_zsh_colors
+ unset_colours
+
+ prompt="$(render_prompt)"
+ assertEquals "m 1 →" "$prompt"
+
+ export GIT_RADAR_FORMAT="%{[:remote:]}"
+ prepare_zsh_colors
+ unset_colours
+
+ prompt="$(render_prompt)"
+ assertEquals "[m 1 →]" "$prompt"
+
+ rm_tmp
+}
+
+. ./shunit/shunit2
diff --git a/test-performance.sh b/test-performance.sh
new file mode 100755
index 0000000..365c4a5
--- /dev/null
+++ b/test-performance.sh
@@ -0,0 +1,231 @@
+scriptDir="$(cd "$(dirname "$0")"; pwd)"
+
+source "$scriptDir/radar-base.sh"
+
+cd_to_tmp() {
+ tmpfile="/tmp/git-prompt-tests-$(time_now)$1"
+ mkdir -p "$tmpfile"
+ cd "$tmpfile"
+}
+
+rm_tmp() {
+ cd $scriptDir
+ rm -rf /tmp/git-prompt-tests*
+}
+
+report() {
+ arr=( "$@" )
+ printf '%s\n' "${arr[@]}" | sort -n | awk '
+ function colored(s) {
+ OFMT="%2.3fs";
+ OFS="";
+ ORS="";
+ if( s > 0.2 ) {
+ print "\033[1;31m", s, "\033[0m"
+ } else if( s > 0.1 ) {
+ print "\033[1;33m", s, "\033[0m"
+ } else {
+ print "\033[1;32m", s, "\033[0m"
+ }
+ OFS="\t";
+ ORS="\n";
+ }
+ BEGIN {
+ c = 0;
+ sum = 0;
+ }
+ $1 ~ /^[0-9]*(\.[0-9]*)?$/ {
+ a[c++] = $1;
+ sum += $1;
+ }
+ END {
+ min = a[0] + 0;
+ max = a[c-1] + 0;
+ ave = sum / c;
+ if( (c % 2) == 1 ) {
+ median = a[ int(c/2) ];
+ } else {
+ median = ( a[c/2] + a[c/2-1] ) / 2;
+ }
+ OFS="\t";
+ OFMT="%2.3fs";
+ print c, colored(ave), colored(median), colored(min), colored(max);
+ }
+'
+}
+
+table_headers() {
+ printf " Count\tMean\tMedian\tMin\tMax\n"
+}
+
+profile () {
+ cmd="$2"
+ for (( i = 0; i < 100; i++ )); do
+ start=$(gdate +%s.%N)
+ eval $cmd > /dev/null
+ duration=$(echo "$(gdate +%s.%N) - $start" | bc)
+ timings[$i]=$duration
+ done
+ printf '%-25s' "$1"
+ report "${timings[@]}"
+}
+
+test_empty_repo() {
+ cd_to_tmp
+ git init --quiet
+
+ table_headers
+ profile "prompt.zsh" "/.$scriptDir/prompt.zsh"
+ profile "prompt.bash" "/.$scriptDir/prompt.bash"
+
+ rm_tmp
+}
+
+test_lots_of_file_changes() {
+ cd_to_tmp
+ git init --quiet
+
+ table_headers
+
+ profile "no changes zsh" "/.$scriptDir/prompt.zsh"
+ profile "no changes bash" "/.$scriptDir/prompt.bash"
+
+ for (( i = 0; i < 100; i++ )); do
+ touch foo$i
+ done
+
+ profile "100 untracked zsh" "/.$scriptDir/prompt.zsh"
+ profile "100 untracked bash" "/.$scriptDir/prompt.bash"
+
+ for (( i = 0; i < 100; i++ )); do
+ touch bar$i
+ git add bar$i
+ done
+
+ profile "100 added zsh" "/.$scriptDir/prompt.zsh"
+ profile "100 added bash" "/.$scriptDir/prompt.bash"
+
+ for (( i = 0; i < 100; i++ )); do
+ echo "bar$i" > bar$i
+ done
+
+ profile "100 modify zsh" "/.$scriptDir/prompt.zsh"
+ profile "100 modify bash" "/.$scriptDir/prompt.bash"
+
+ rm_tmp
+}
+
+test_commits_local_and_remote_ahead() {
+ cd_to_tmp "remote"
+ git init --quiet
+ touch README
+ git add .
+ git commit -m "initial commit" --quiet
+ remoteLocation="$(pwd)"
+
+ cd_to_tmp "new"
+ git init --quiet
+ git remote add origin $remoteLocation
+ git fetch origin --quiet
+ git checkout master --quiet
+
+ git checkout -b foo --quiet
+ git push --quiet -u origin foo >/dev/null
+
+ table_headers
+
+ profile "0 commits zsh" "/.$scriptDir/prompt.zsh"
+ profile "0 commits bash" "/.$scriptDir/prompt.bash"
+
+ for (( i = 0; i < 100; i++ )); do
+ echo "foo$i" >> foo
+ git add .
+ git commit -m "foo $i" --quiet
+ done
+
+ profile "100 local zsh" "/.$scriptDir/prompt.zsh"
+ profile "100 local bash" "/.$scriptDir/prompt.bash"
+
+ git push --quiet
+
+ profile "100 remote zsh" "/.$scriptDir/prompt.zsh"
+ profile "100 remote bash" "/.$scriptDir/prompt.bash"
+
+ rm_tmp
+}
+
+test_commits_local_and_remote_behind() {
+ cd_to_tmp "remote"
+ git init --bare --quiet
+ remoteLocation="$(pwd)"
+
+ cd_to_tmp "new"
+ git init --quiet
+ git remote add origin $remoteLocation
+ git fetch origin --quiet
+ git checkout -b master --quiet
+ touch README
+ git add README
+ git commit -m "initial commit" --quiet
+
+ git push --quiet -u origin master >/dev/null
+ git reset --quiet --hard HEAD
+
+ git checkout -b foo --quiet
+ git push --quiet -u origin foo >/dev/null
+
+ git checkout master --quiet
+
+ table_headers
+
+ profile "0 commits zsh" "/.$scriptDir/prompt.zsh"
+ profile "0 commits bash" "/.$scriptDir/prompt.bash"
+
+ for (( i = 0; i < 100; i++ )); do
+ echo "foo$i" >> foo
+ git add .
+ git commit -m "foo $i" --quiet
+ done
+
+ git push --quiet
+ git checkout foo --quiet
+
+ profile "100 behind remote zsh" "/.$scriptDir/prompt.zsh"
+ profile "100 behind remote bash" "/.$scriptDir/prompt.bash"
+
+ git checkout master --quiet
+ git checkout -b bar --quiet
+ git push --quiet -u origin bar >/dev/null
+ git reset --hard origin/foo --quiet
+
+ profile "100 behind mine zsh" "/.$scriptDir/prompt.zsh"
+ profile "100 behind mine bash" "/.$scriptDir/prompt.bash"
+
+}
+
+test_large_repo() {
+ cd_to_tmp
+ git clone https://github.com/Homebrew/homebrew --quiet
+ cd homebrew
+
+ table_headers
+ profile "prompt.zsh" "/.$scriptDir/prompt.zsh"
+ profile "prompt.bash" "/.$scriptDir/prompt.bash"
+
+ rm_tmp
+}
+
+test_lots_of_submodules() {
+ cd_to_tmp
+ git clone https://github.com/michaeldfallen/dotfiles --quiet
+ cd dotfiles
+ git submodule update --init --quiet
+
+ table_headers
+ profile "prompt.zsh" "/.$scriptDir/prompt.zsh"
+ profile "prompt.bash" "/.$scriptDir/prompt.bash"
+
+ rm_tmp
+}
+
+. ./shunit/shunit2