1# based off of the git-prompt script that ships with git
2# hence licensed under GPL version 2 (like the rest of fish).
3#
4# Written by Lily Ballard and updated by Brian Gernhardt and fish contributors
5#
6# This is based on git's git-prompt.bash script, Copyright (C) 2006,2007 Shawn O. Pearce <spearce@spearce.org>.
7# The act of porting the code, along with any new code, are Copyright (C) 2012 Lily Ballard.
8
9function __fish_git_prompt_show_upstream --description "Helper function for fish_git_prompt"
10    set -l show_upstream $__fish_git_prompt_showupstream
11    set -l svn_prefix # For better SVN upstream information
12    set -l informative
13
14    set -l svn_url_pattern
15    set -l count
16    set -l upstream git
17    set -l verbose
18    set -l name
19
20    # Default to informative if __fish_git_prompt_show_informative_status is set
21    if set -q __fish_git_prompt_show_informative_status
22        set informative 1
23    end
24
25    set -l svn_remote
26    # get some config options from git-config
27    command git config -z --get-regexp '^(svn-remote\..*\.url|bash\.showupstream)$' 2>/dev/null | while read -lz key value
28        switch $key
29            case bash.showupstream
30                set show_upstream $value
31                test -n "$show_upstream"
32                or return
33            case svn-remote.'*'.url
34                set svn_remote $svn_remote $value
35                # Avoid adding \| to the beginning to avoid needing #?? later
36                if test -n "$svn_url_pattern"
37                    set svn_url_pattern $svn_url_pattern"|$value"
38                else
39                    set svn_url_pattern $value
40                end
41                set upstream svn+git # default upstream is SVN if available, else git
42
43                # Save the config key (without .url) for later use
44                set -l remote_prefix (string replace -r '\.url$' '' -- $key)
45                set svn_prefix $svn_prefix $remote_prefix
46        end
47    end
48
49    # parse configuration variables
50    # and clear informative default when needed
51    for option in $show_upstream
52        switch $option
53            case git svn
54                set upstream $option
55                set -e informative
56            case verbose
57                set verbose 1
58                set -e informative
59            case informative
60                set informative 1
61            case name
62                set name 1
63            case none
64                return
65        end
66    end
67
68    # Find our upstream
69    switch $upstream
70        case git
71            set upstream '@{upstream}'
72        case svn\*
73            # get the upstream from the 'git-svn-id: …' in a commit message
74            # (git-svn uses essentially the same procedure internally)
75            set -l svn_upstream (git log --first-parent -1 --grep="^git-svn-id: \($svn_url_pattern\)" 2>/dev/null)
76            if test (count $svn_upstream) -ne 0
77                echo $svn_upstream[-1] | read -l __ svn_upstream __
78                set svn_upstream (string replace -r '@.*' '' -- $svn_upstream)
79                set -l cur_prefix
80                for i in (seq (count $svn_remote))
81                    set -l remote $svn_remote[$i]
82                    set -l mod_upstream (string replace "$remote" "" -- $svn_upstream)
83                    if test "$svn_upstream" != "$mod_upstream"
84                        # we found a valid remote
85                        set svn_upstream $mod_upstream
86                        set cur_prefix $svn_prefix[$i]
87                        break
88                    end
89                end
90
91                if test -z "$svn_upstream"
92                    # default branch name for checkouts with no layout:
93                    if test -n "$GIT_SVN_ID"
94                        set upstream $GIT_SVN_ID
95                    else
96                        set upstream git-svn
97                    end
98                else
99                    set upstream (string replace '/branches' '' -- $svn_upstream | string replace -a '/' '')
100
101                    # Use fetch config to fix upstream
102                    set -l fetch_val (command git config "$cur_prefix".fetch)
103                    if test -n "$fetch_val"
104                        string split -m1 : -- "$fetch_val" | read -l trunk pattern
105                        set upstream (string replace -r -- "/$trunk\$" '' $pattern) /$upstream
106                    end
107                end
108            else if test $upstream = svn+git
109                set upstream '@{upstream}'
110            end
111    end
112
113    # Find how many commits we are ahead/behind our upstream
114    set count (command git rev-list --count --left-right $upstream...HEAD 2>/dev/null | string replace \t " ")
115
116    # calculate the result
117    if test -n "$verbose"
118        # Verbose has a space by default
119        set -l prefix "$___fish_git_prompt_char_upstream_prefix"
120        # Using two underscore version to check if user explicitly set to nothing
121        if not set -q __fish_git_prompt_char_upstream_prefix
122            set prefix " "
123        end
124
125        echo $count | read -l behind ahead
126        switch "$count"
127            case '' # no upstream
128            case "0 0" # equal to upstream
129                echo "$prefix$___fish_git_prompt_char_upstream_equal"
130            case "0 *" # ahead of upstream
131                echo "$prefix$___fish_git_prompt_char_upstream_ahead$ahead"
132            case "* 0" # behind upstream
133                echo "$prefix$___fish_git_prompt_char_upstream_behind$behind"
134            case '*' # diverged from upstream
135                echo "$prefix$___fish_git_prompt_char_upstream_diverged$ahead-$behind"
136        end
137        if test -n "$count" -a -n "$name"
138            echo " "(command git rev-parse --abbrev-ref "$upstream" 2>/dev/null)
139        end
140    else if test -n "$informative"
141        echo $count | read -l behind ahead
142        switch "$count"
143            case '' # no upstream
144            case "0 0" # equal to upstream
145            case "0 *" # ahead of upstream
146                echo "$___fish_git_prompt_char_upstream_prefix$___fish_git_prompt_char_upstream_ahead$ahead"
147            case "* 0" # behind upstream
148                echo "$___fish_git_prompt_char_upstream_prefix$___fish_git_prompt_char_upstream_behind$behind"
149            case '*' # diverged from upstream
150                echo "$___fish_git_prompt_char_upstream_prefix$___fish_git_prompt_char_upstream_ahead$ahead$___fish_git_prompt_char_upstream_behind$behind"
151        end
152    else
153        switch "$count"
154            case '' # no upstream
155            case "0 0" # equal to upstream
156                echo "$___fish_git_prompt_char_upstream_prefix$___fish_git_prompt_char_upstream_equal"
157            case "0 *" # ahead of upstream
158                echo "$___fish_git_prompt_char_upstream_prefix$___fish_git_prompt_char_upstream_ahead"
159            case "* 0" # behind upstream
160                echo "$___fish_git_prompt_char_upstream_prefix$___fish_git_prompt_char_upstream_behind"
161            case '*' # diverged from upstream
162                echo "$___fish_git_prompt_char_upstream_prefix$___fish_git_prompt_char_upstream_diverged"
163        end
164    end
165
166    # For the return status
167    test "$count" = "0 0"
168end
169
170function fish_git_prompt --description "Prompt function for Git"
171    # If git isn't installed, there's nothing we can do
172    # Return 1 so the calling prompt can deal with it
173    if not command -sq git
174        return 1
175    end
176    set -l repo_info (command git rev-parse --git-dir --is-inside-git-dir --is-bare-repository --is-inside-work-tree HEAD 2>/dev/null)
177    test -n "$repo_info"
178    or return
179
180    set -l git_dir $repo_info[1]
181    set -l inside_gitdir $repo_info[2]
182    set -l bare_repo $repo_info[3]
183    set -l inside_worktree $repo_info[4]
184    set -q repo_info[5]
185    and set -l sha $repo_info[5]
186
187    set -l rbc (__fish_git_prompt_operation_branch_bare $repo_info)
188    set -l r $rbc[1] # current operation
189    set -l b $rbc[2] # current branch
190    set -l detached $rbc[3]
191    set -l dirtystate #dirty working directory
192    set -l stagedstate #staged changes
193    set -l invalidstate #staged changes
194    set -l stashstate #stashes
195    set -l untrackedfiles #untracked
196    set -l c $rbc[4] # bare repository
197    set -l p #upstream
198    set -l informative_status
199
200    set -q __fish_git_prompt_status_order
201    or set -g __fish_git_prompt_status_order stagedstate invalidstate dirtystate untrackedfiles stashstate
202
203    if not set -q ___fish_git_prompt_init
204        # This takes a while, so it only needs to be done once,
205        # and then whenever the configuration changes.
206        __fish_git_prompt_validate_chars
207        __fish_git_prompt_validate_colors
208        set -g ___fish_git_prompt_init
209    end
210
211    set -l space "$___fish_git_prompt_color$___fish_git_prompt_char_stateseparator$___fish_git_prompt_color_done"
212
213    # Use our variables as defaults, but allow overrides via the local git config.
214    # That means if neither is set, this stays empty.
215    #
216    # So "!= true" or "!= false" are useful tests if you want to do something by default.
217    set -l informative (command git config --bool bash.showInformativeStatus)
218
219    set -l dirty (command git config --bool bash.showDirtyState)
220    if not set -q dirty[1]
221        set -q __fish_git_prompt_showdirtystate
222        and set dirty true
223    end
224    # If we don't print these, there is no need to compute them.
225    # Note: For now, staged and dirty are coupled.
226    contains dirtystate $__fish_git_prompt_status_order
227    or contains stagedstate $__fish_git_prompt_status_order
228    or set dirty false
229
230    set -l untracked (command git config --bool bash.showUntrackedFiles)
231    if not set -q untracked[1]
232        set -q __fish_git_prompt_showuntrackedfiles
233        and set untracked true
234    end
235    contains untrackedfiles $__fish_git_prompt_status_order
236    or set untracked false
237
238    if test true = $inside_worktree
239        # Use informative status if it has been enabled locally, or it has been
240        # enabled globally (via the fish variable) and dirty or untracked are not false.
241        #
242        # This is to allow overrides for the repository.
243        if test "$informative" = true
244            or begin
245                set -q __fish_git_prompt_show_informative_status
246                and test "$dirty" != false
247                and test "$untracked" != false
248            end
249            set informative_status (__fish_git_prompt_informative_status $git_dir)
250            if test -n "$informative_status"
251                set informative_status "$space$informative_status"
252            end
253        else
254            # This has to be set explicitly.
255            if test "$dirty" = true
256                set dirtystate (__fish_git_prompt_dirty)
257                if test -n "$sha"
258                    set stagedstate (__fish_git_prompt_staged)
259                else
260                    set invalidstate 1
261                end
262            end
263
264            if set -q __fish_git_prompt_showstashstate
265                and test -r $git_dir/logs/refs/stash
266                set stashstate 1
267            end
268
269            if test "$untracked" = true
270                set untrackedfiles (__fish_git_prompt_untracked)
271            end
272        end
273
274        if set -q __fish_git_prompt_showupstream
275            or set -q __fish_git_prompt_show_informative_status
276            set p (__fish_git_prompt_show_upstream)
277        end
278    end
279
280    set -l branch_color $___fish_git_prompt_color_branch
281    set -l branch_done $___fish_git_prompt_color_branch_done
282    if set -q __fish_git_prompt_showcolorhints
283        if test $detached = yes
284            set branch_color $___fish_git_prompt_color_branch_detached
285            set branch_done $___fish_git_prompt_color_branch_detached_done
286        end
287    end
288
289    set -l f ""
290    for i in $__fish_git_prompt_status_order
291        if test -n "$$i"
292            set -l color_var ___fish_git_prompt_color_$i
293            set -l color_done_var ___fish_git_prompt_color_{$i}_done
294            set -l symbol_var ___fish_git_prompt_char_$i
295
296            set -l color $$color_var
297            set -l color_done $$color_done_var
298            set -l symbol $$symbol_var
299
300            set f "$f$color$symbol$color_done"
301        end
302    end
303
304    set b (string replace refs/heads/ '' -- $b)
305    set -q __fish_git_prompt_shorten_branch_char_suffix
306    or set -l __fish_git_prompt_shorten_branch_char_suffix "…"
307    if string match -qr '^\d+$' "$__fish_git_prompt_shorten_branch_len"; and test (string length "$b") -gt $__fish_git_prompt_shorten_branch_len
308        set b (string sub -l "$__fish_git_prompt_shorten_branch_len" "$b")"$__fish_git_prompt_shorten_branch_char_suffix"
309    end
310    if test -n "$b"
311        set b "$branch_color$b$branch_done"
312    end
313
314    if test -n "$c"
315        set c "$___fish_git_prompt_color_bare$c$___fish_git_prompt_color_bare_done"
316    end
317    if test -n "$r"
318        set r "$___fish_git_prompt_color_merging$r$___fish_git_prompt_color_merging_done"
319    end
320    if test -n "$p"
321        set p "$___fish_git_prompt_color_upstream$p$___fish_git_prompt_color_upstream_done"
322    end
323
324    # Formatting
325    if test -n "$f"
326        set f "$space$f"
327    end
328    set -l format $argv[1]
329    if test -z "$format"
330        set format " (%s)"
331    end
332
333    printf "%s$format%s" "$___fish_git_prompt_color_prefix" "$___fish_git_prompt_color_prefix_done$c$b$f$r$p$informative_status$___fish_git_prompt_color_suffix" "$___fish_git_prompt_color_suffix_done"
334end
335
336### helper functions
337
338function __fish_git_prompt_staged --description "fish_git_prompt helper, tells whether or not the current branch has staged files"
339    # The "diff" functions all return > 0 if there _is_ a diff,
340    # but we want to return 0 if there are staged changes.
341    # So we invert the status.
342    not command git diff-index --cached --quiet HEAD -- 2>/dev/null
343    and echo 1
344end
345
346function __fish_git_prompt_untracked --description "fish_git_prompt helper, tells whether or not the current repository has untracked files"
347    command git ls-files --others --exclude-standard --directory --no-empty-directory --error-unmatch -- :/ >/dev/null 2>&1
348    and echo 1
349end
350
351function __fish_git_prompt_dirty --description "fish_git_prompt helper, tells whether or not the current branch has tracked, modified files"
352    # Like staged, invert the status because we want 0 to mean there are dirty files.
353    not command git diff --no-ext-diff --quiet --exit-code 2>/dev/null
354    and echo 1
355end
356
357function __fish_git_prompt_informative_status
358    set -l stashstate 0
359    set -l stashfile "$argv[1]/logs/refs/stash"
360    if set -q __fish_git_prompt_showstashstate; and test -e "$stashfile"
361        set stashstate (count < $stashfile)
362    end
363
364    # Use git status --porcelain.
365    # This uses the "normal" untracked mode so untracked directories are considered as 1 entry.
366    # It's quite a bit faster and unlikely anyone cares about the number of files if it's *all* of the files
367    # in that directory.
368    # The v2 format is better, but we don't actually care in this case.
369    set -l stats (string sub -l 2 (git status --porcelain -z -unormal | string split0))
370    set -l invalidstate (string match -r '^UU' $stats | count)
371    set -l stagedstate (string match -r '^[ACDMR].' $stats | count)
372    set -l dirtystate (string match -r '^.[ACDMR]' $stats | count)
373    set -l untrackedfiles (string match -r '^\?\?' $stats | count)
374
375    set -l info
376
377    # If `math` fails for some reason, assume the state is clean - it's the simpler path
378    set -l state (math $dirtystate + $invalidstate + $stagedstate + $untrackedfiles + $stashstate 2>/dev/null)
379    if test -z "$state"
380        or test "$state" = 0
381        if test -n "$___fish_git_prompt_char_cleanstate"
382            set info $___fish_git_prompt_color_cleanstate$___fish_git_prompt_char_cleanstate$___fish_git_prompt_color_cleanstate_done
383        end
384    else
385        for i in $__fish_git_prompt_status_order
386            if [ $$i != 0 ]
387                set -l color_var ___fish_git_prompt_color_$i
388                set -l color_done_var ___fish_git_prompt_color_{$i}_done
389                set -l symbol_var ___fish_git_prompt_char_$i
390
391                set -l color $$color_var
392                set -l color_done $$color_done_var
393                set -l symbol $$symbol_var
394
395                set -l count
396
397                if not set -q __fish_git_prompt_hide_$i
398                    set count $$i
399                end
400
401                set info "$info$color$symbol$count$color_done"
402            end
403        end
404    end
405
406    echo $info
407
408end
409
410# Keeping these together avoids many duplicated checks
411function __fish_git_prompt_operation_branch_bare --description "fish_git_prompt helper, returns the current Git operation and branch"
412    # This function is passed the full repo_info array
413    set -l git_dir $argv[1]
414    set -l inside_gitdir $argv[2]
415    set -l bare_repo $argv[3]
416    set -q argv[5]
417    and set -l sha $argv[5]
418
419    set -l branch
420    set -l operation
421    set -l detached no
422    set -l bare
423    set -l step
424    set -l total
425
426    if test -d $git_dir/rebase-merge
427        set branch (cat $git_dir/rebase-merge/head-name 2>/dev/null)
428        set step (cat $git_dir/rebase-merge/msgnum 2>/dev/null)
429        set total (cat $git_dir/rebase-merge/end 2>/dev/null)
430        if test -f $git_dir/rebase-merge/interactive
431            set operation "|REBASE-i"
432        else
433            set operation "|REBASE-m"
434        end
435    else
436        if test -d $git_dir/rebase-apply
437            set step (cat $git_dir/rebase-apply/next 2>/dev/null)
438            set total (cat $git_dir/rebase-apply/last 2>/dev/null)
439            if test -f $git_dir/rebase-apply/rebasing
440                set branch (cat $git_dir/rebase-apply/head-name 2>/dev/null)
441                set operation "|REBASE"
442            else if test -f $git_dir/rebase-apply/applying
443                set operation "|AM"
444            else
445                set operation "|AM/REBASE"
446            end
447        else if test -f $git_dir/MERGE_HEAD
448            set operation "|MERGING"
449        else if test -f $git_dir/CHERRY_PICK_HEAD
450            set operation "|CHERRY-PICKING"
451        else if test -f $git_dir/REVERT_HEAD
452            set operation "|REVERTING"
453        else if test -f $git_dir/BISECT_LOG
454            set operation "|BISECTING"
455        end
456    end
457
458    if test -n "$step" -a -n "$total"
459        set operation "$operation $step/$total"
460    end
461
462    if test -z "$branch"
463        if not set branch (command git symbolic-ref HEAD 2>/dev/null)
464            set detached yes
465            set branch (switch "$__fish_git_prompt_describe_style"
466						case contains
467							command git describe --contains HEAD
468						case branch
469							command git describe --contains --all HEAD
470						case describe
471							command git describe HEAD
472						case default '*'
473							command git describe --tags --exact-match HEAD
474						end 2>/dev/null)
475            if test $status -ne 0
476                # Shorten the sha ourselves to 8 characters - this should be good for most repositories,
477                # and even for large ones it should be good for most commits
478                if set -q sha
479                    set branch (string match -r '^.{8}' -- $sha)…
480                else
481                    set branch unknown
482                end
483            end
484            set branch "($branch)"
485        end
486    end
487
488    if test true = $inside_gitdir
489        if test true = $bare_repo
490            set bare "BARE:"
491        else
492            # Let user know they're inside the git dir of a non-bare repo
493            set branch "GIT_DIR!"
494        end
495    end
496
497    echo $operation
498    echo $branch
499    echo $detached
500    echo $bare
501end
502
503function __fish_git_prompt_set_char
504    set -l user_variable_name "$argv[1]"
505    set -l char $argv[2]
506
507    if set -q argv[3]
508        and begin
509            set -q __fish_git_prompt_show_informative_status
510            or set -q __fish_git_prompt_use_informative_chars
511        end
512        set char $argv[3]
513    end
514
515    set -l variable _$user_variable_name
516    set -l variable_done "$variable"_done
517
518    if not set -q $variable
519        set -g $variable (set -q $user_variable_name; and echo $$user_variable_name; or echo $char)
520    end
521end
522
523function __fish_git_prompt_validate_chars --description "fish_git_prompt helper, checks char variables"
524
525    __fish_git_prompt_set_char __fish_git_prompt_char_cleanstate '✔'
526    __fish_git_prompt_set_char __fish_git_prompt_char_dirtystate '*' '✚'
527    __fish_git_prompt_set_char __fish_git_prompt_char_invalidstate '#' '✖'
528    __fish_git_prompt_set_char __fish_git_prompt_char_stagedstate '+' '●'
529    __fish_git_prompt_set_char __fish_git_prompt_char_stashstate '$' '⚑'
530    __fish_git_prompt_set_char __fish_git_prompt_char_stateseparator ' ' '|'
531    __fish_git_prompt_set_char __fish_git_prompt_char_untrackedfiles '%' '…'
532    __fish_git_prompt_set_char __fish_git_prompt_char_upstream_ahead '>' '↑'
533    __fish_git_prompt_set_char __fish_git_prompt_char_upstream_behind '<' '↓'
534    __fish_git_prompt_set_char __fish_git_prompt_char_upstream_diverged '<>'
535    __fish_git_prompt_set_char __fish_git_prompt_char_upstream_equal '='
536    __fish_git_prompt_set_char __fish_git_prompt_char_upstream_prefix ''
537
538end
539
540function __fish_git_prompt_set_color
541    set -l user_variable_name "$argv[1]"
542
543    set -l default default_done
544    switch (count $argv)
545        case 1 # No defaults given, use prompt color
546            set default $___fish_git_prompt_color
547            set default_done $___fish_git_prompt_color_done
548        case 2 # One default given, use normal for done
549            set default "$argv[2]"
550            set default_done (set_color normal)
551        case 3 # Both defaults given
552            set default "$argv[2]"
553            set default_done "$argv[3]"
554    end
555
556    set -l variable _$user_variable_name
557    set -l variable_done "$variable"_done
558
559    if not set -q $variable
560        if test -n "$$user_variable_name"
561            set -g $variable (set_color $$user_variable_name)
562            set -g $variable_done (set_color normal)
563        else
564            set -g $variable $default
565            set -g $variable_done $default_done
566        end
567    end
568end
569
570
571function __fish_git_prompt_validate_colors --description "fish_git_prompt helper, checks color variables"
572
573    # Base color defaults to nothing (must be done first)
574    __fish_git_prompt_set_color __fish_git_prompt_color '' ''
575
576    # Normal colors
577    __fish_git_prompt_set_color __fish_git_prompt_color_prefix
578    __fish_git_prompt_set_color __fish_git_prompt_color_suffix
579    __fish_git_prompt_set_color __fish_git_prompt_color_bare
580    __fish_git_prompt_set_color __fish_git_prompt_color_merging
581    __fish_git_prompt_set_color __fish_git_prompt_color_cleanstate
582    __fish_git_prompt_set_color __fish_git_prompt_color_invalidstate
583    __fish_git_prompt_set_color __fish_git_prompt_color_upstream
584
585    # Colors with defaults with showcolorhints
586    if set -q __fish_git_prompt_showcolorhints
587        __fish_git_prompt_set_color __fish_git_prompt_color_flags (set_color --bold blue)
588        __fish_git_prompt_set_color __fish_git_prompt_color_branch (set_color green)
589        __fish_git_prompt_set_color __fish_git_prompt_color_dirtystate (set_color red)
590        __fish_git_prompt_set_color __fish_git_prompt_color_stagedstate (set_color green)
591    else
592        __fish_git_prompt_set_color __fish_git_prompt_color_flags
593        __fish_git_prompt_set_color __fish_git_prompt_color_branch
594        __fish_git_prompt_set_color __fish_git_prompt_color_dirtystate $___fish_git_prompt_color_flags $___fish_git_prompt_color_flags_done
595        __fish_git_prompt_set_color __fish_git_prompt_color_stagedstate $___fish_git_prompt_color_flags $___fish_git_prompt_color_flags_done
596    end
597
598    # Branch_detached has a default, but is only used with showcolorhints
599    __fish_git_prompt_set_color __fish_git_prompt_color_branch_detached (set_color red)
600
601    # Colors that depend on flags color
602    __fish_git_prompt_set_color __fish_git_prompt_color_stashstate $___fish_git_prompt_color_flags $___fish_git_prompt_color_flags_done
603    __fish_git_prompt_set_color __fish_git_prompt_color_untrackedfiles $___fish_git_prompt_color_flags $___fish_git_prompt_color_flags_done
604
605end
606
607set -l varargs
608for var in repaint describe_style show_informative_status use_informative_chars showdirtystate showstashstate showuntrackedfiles showupstream
609    set -a varargs --on-variable __fish_git_prompt_$var
610end
611function __fish_git_prompt_reset $varargs --description "Event handler, resets prompt when functionality changes"
612    if status --is-interactive
613        if contains -- $argv[3] __fish_git_prompt_show_informative_status __fish_git_prompt_use_informative_chars
614            # Clear characters that have different defaults with/without informative status
615            for name in cleanstate dirtystate invalidstate stagedstate stashstate stateseparator untrackedfiles upstream_ahead upstream_behind
616                set -e ___fish_git_prompt_char_$name
617            end
618            # Clear init so we reset the chars next time.
619            set -e ___fish_git_prompt_init
620        end
621    end
622end
623
624set -l varargs
625for var in '' _prefix _suffix _bare _merging _cleanstate _invalidstate _upstream _flags _branch _dirtystate _stagedstate _branch_detached _stashstate _untrackedfiles
626    set -a varargs --on-variable __fish_git_prompt_color$var
627end
628set -a varargs --on-variable __fish_git_prompt_showcolorhints
629function __fish_git_prompt_reset_color $varargs --description "Event handler, resets prompt when any color changes"
630    if status --is-interactive
631        set -e ___fish_git_prompt_init
632        set -l var $argv[3]
633        set -e _$var
634        set -e _{$var}_done
635        if test $var = __fish_git_prompt_color -o $var = __fish_git_prompt_color_flags -o $var = __fish_git_prompt_showcolorhints
636            # reset all the other colors too
637            for name in prefix suffix bare merging branch dirtystate stagedstate invalidstate stashstate untrackedfiles upstream flags
638                set -e ___fish_git_prompt_color_$name
639                set -e ___fish_git_prompt_color_{$name}_done
640            end
641        end
642    end
643end
644
645set -l varargs
646for var in cleanstate dirtystate invalidstate stagedstate stashstate stateseparator untrackedfiles upstream_ahead upstream_behind upstream_diverged upstream_equal upstream_prefix
647    set -a varargs --on-variable __fish_git_prompt_char_$var
648end
649function __fish_git_prompt_reset_char $varargs --description "Event handler, resets prompt when any char changes"
650    if status --is-interactive
651        set -e ___fish_git_prompt_init
652        set -e _$argv[3]
653    end
654end
655