1#
2# bash completion support for core Git.
3#
4# Copyright (C) 2006,2007 Shawn O. Pearce <spearce@spearce.org>
5# Conceptually based on gitcompletion (http://gitweb.hawaga.org.uk/).
6# Distributed under the GNU General Public License, version 2.0.
7#
8# The contained completion routines provide support for completing:
9#
10# *) local and remote branch names
11# *) local and remote tag names
12# *) .git/remotes file names
13# *) git 'subcommands'
14# *) tree paths within 'ref:path/to/file' expressions
15# *) common --long-options
16#
17# To use these routines:
18#
19# 1) Copy this file to somewhere (e.g. ~/.git-completion.sh).
20# 2) Added the following line to your .bashrc:
21# source ~/.git-completion.sh
22#
23# 3) You may want to make sure the git executable is available
24# in your PATH before this script is sourced, as some caching
25# is performed while the script loads. If git isn't found
26# at source time then all lookups will be done on demand,
27# which may be slightly slower.
28#
29# 4) Consider changing your PS1 to also show the current branch:
30# PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '
31#
32# The argument to __git_ps1 will be displayed only if you
33# are currently in a git repository. The %s token will be
34# the name of the current branch.
35#
36# To submit patches:
37#
38# *) Read Documentation/SubmittingPatches
39# *) Send all patches to the current maintainer:
40#
41# "Shawn O. Pearce" <spearce@spearce.org>
42#
43# *) Always CC the Git mailing list:
44#
45# git@vger.kernel.org
46#
47
48case "$COMP_WORDBREAKS" in
49*:*) : great ;;
50*) COMP_WORDBREAKS="$COMP_WORDBREAKS:"
51esac
52
53__gitdir ()
54{
55 if [ -z "$1" ]; then
56 if [ -n "$__git_dir" ]; then
57 echo "$__git_dir"
58 elif [ -d .git ]; then
59 echo .git
60 else
61 git rev-parse --git-dir 2>/dev/null
62 fi
63 elif [ -d "$1/.git" ]; then
64 echo "$1/.git"
65 else
66 echo "$1"
67 fi
68}
69
70__git_ps1 ()
71{
72 local g="$(git rev-parse --git-dir 2>/dev/null)"
73 if [ -n "$g" ]; then
74 local r
75 local b
76 if [ -d "$g/rebase-apply" ]
77 then
78 if test -f "$g/rebase-apply/rebasing"
79 then
80 r="|REBASE"
81 elif test -f "$g/rebase-apply/applying"
82 then
83 r="|AM"
84 else
85 r="|AM/REBASE"
86 fi
87 b="$(git symbolic-ref HEAD 2>/dev/null)"
88 elif [ -f "$g/rebase-merge/interactive" ]
89 then
90 r="|REBASE-i"
91 b="$(cat "$g/rebase-merge/head-name")"
92 elif [ -d "$g/rebase-merge" ]
93 then
94 r="|REBASE-m"
95 b="$(cat "$g/rebase-merge/head-name")"
96 elif [ -f "$g/MERGE_HEAD" ]
97 then
98 r="|MERGING"
99 b="$(git symbolic-ref HEAD 2>/dev/null)"
100 else
101 if [ -f "$g/BISECT_LOG" ]
102 then
103 r="|BISECTING"
104 fi
105 if ! b="$(git symbolic-ref HEAD 2>/dev/null)"
106 then
107 if ! b="$(git describe --exact-match HEAD 2>/dev/null)"
108 then
109 b="$(cut -c1-7 "$g/HEAD")..."
110 fi
111 fi
112 fi
113
114 if [ -n "$1" ]; then
115 printf "$1" "${b##refs/heads/}$r"
116 else
117 printf " (%s)" "${b##refs/heads/}$r"
118 fi
119 fi
120}
121
122__gitcomp_1 ()
123{
124 local c IFS=' '$'\t'$'\n'
125 for c in $1; do
126 case "$c$2" in
127 --*=*) printf %s$'\n' "$c$2" ;;
128 *.) printf %s$'\n' "$c$2" ;;
129 *) printf %s$'\n' "$c$2 " ;;
130 esac
131 done
132}
133
134__gitcomp ()
135{
136 local cur="${COMP_WORDS[COMP_CWORD]}"
137 if [ $# -gt 2 ]; then
138 cur="$3"
139 fi
140 case "$cur" in
141 --*=)
142 COMPREPLY=()
143 ;;
144 *)
145 local IFS=$'\n'
146 COMPREPLY=($(compgen -P "$2" \
147 -W "$(__gitcomp_1 "$1" "$4")" \
148 -- "$cur"))
149 ;;
150 esac
151}
152
153__git_heads ()
154{
155 local cmd i is_hash=y dir="$(__gitdir "$1")"
156 if [ -d "$dir" ]; then
157 for i in $(git --git-dir="$dir" \
158 for-each-ref --format='%(refname)' \
159 refs/heads ); do
160 echo "${i#refs/heads/}"
161 done
162 return
163 fi
164 for i in $(git ls-remote "$1" 2>/dev/null); do
165 case "$is_hash,$i" in
166 y,*) is_hash=n ;;
167 n,*^{}) is_hash=y ;;
168 n,refs/heads/*) is_hash=y; echo "${i#refs/heads/}" ;;
169 n,*) is_hash=y; echo "$i" ;;
170 esac
171 done
172}
173
174__git_tags ()
175{
176 local cmd i is_hash=y dir="$(__gitdir "$1")"
177 if [ -d "$dir" ]; then
178 for i in $(git --git-dir="$dir" \
179 for-each-ref --format='%(refname)' \
180 refs/tags ); do
181 echo "${i#refs/tags/}"
182 done
183 return
184 fi
185 for i in $(git ls-remote "$1" 2>/dev/null); do
186 case "$is_hash,$i" in
187 y,*) is_hash=n ;;
188 n,*^{}) is_hash=y ;;
189 n,refs/tags/*) is_hash=y; echo "${i#refs/tags/}" ;;
190 n,*) is_hash=y; echo "$i" ;;
191 esac
192 done
193}
194
195__git_refs ()
196{
197 local cmd i is_hash=y dir="$(__gitdir "$1")"
198 if [ -d "$dir" ]; then
199 if [ -e "$dir/HEAD" ]; then echo HEAD; fi
200 for i in $(git --git-dir="$dir" \
201 for-each-ref --format='%(refname)' \
202 refs/tags refs/heads refs/remotes); do
203 case "$i" in
204 refs/tags/*) echo "${i#refs/tags/}" ;;
205 refs/heads/*) echo "${i#refs/heads/}" ;;
206 refs/remotes/*) echo "${i#refs/remotes/}" ;;
207 *) echo "$i" ;;
208 esac
209 done
210 return
211 fi
212 for i in $(git ls-remote "$dir" 2>/dev/null); do
213 case "$is_hash,$i" in
214 y,*) is_hash=n ;;
215 n,*^{}) is_hash=y ;;
216 n,refs/tags/*) is_hash=y; echo "${i#refs/tags/}" ;;
217 n,refs/heads/*) is_hash=y; echo "${i#refs/heads/}" ;;
218 n,refs/remotes/*) is_hash=y; echo "${i#refs/remotes/}" ;;
219 n,*) is_hash=y; echo "$i" ;;
220 esac
221 done
222}
223
224__git_refs2 ()
225{
226 local i
227 for i in $(__git_refs "$1"); do
228 echo "$i:$i"
229 done
230}
231
232__git_refs_remotes ()
233{
234 local cmd i is_hash=y
235 for i in $(git ls-remote "$1" 2>/dev/null); do
236 case "$is_hash,$i" in
237 n,refs/heads/*)
238 is_hash=y
239 echo "$i:refs/remotes/$1/${i#refs/heads/}"
240 ;;
241 y,*) is_hash=n ;;
242 n,*^{}) is_hash=y ;;
243 n,refs/tags/*) is_hash=y;;
244 n,*) is_hash=y; ;;
245 esac
246 done
247}
248
249__git_remotes ()
250{
251 local i ngoff IFS=$'\n' d="$(__gitdir)"
252 shopt -q nullglob || ngoff=1
253 shopt -s nullglob
254 for i in "$d/remotes"/*; do
255 echo ${i#$d/remotes/}
256 done
257 [ "$ngoff" ] && shopt -u nullglob
258 for i in $(git --git-dir="$d" config --list); do
259 case "$i" in
260 remote.*.url=*)
261 i="${i#remote.}"
262 echo "${i/.url=*/}"
263 ;;
264 esac
265 done
266}
267
268__git_merge_strategies ()
269{
270 if [ -n "$__git_merge_strategylist" ]; then
271 echo "$__git_merge_strategylist"
272 return
273 fi
274 git merge -s help 2>&1 |
275 sed -n -e '/[Aa]vailable strategies are: /,/^$/{
276 s/\.$//
277 s/.*://
278 s/^[ ]*//
279 s/[ ]*$//
280 p
281 }'
282}
283__git_merge_strategylist=
284__git_merge_strategylist=$(__git_merge_strategies 2>/dev/null)
285
286__git_complete_file ()
287{
288 local pfx ls ref cur="${COMP_WORDS[COMP_CWORD]}"
289 case "$cur" in
290 ?*:*)
291 ref="${cur%%:*}"
292 cur="${cur#*:}"
293 case "$cur" in
294 ?*/*)
295 pfx="${cur%/*}"
296 cur="${cur##*/}"
297 ls="$ref:$pfx"
298 pfx="$pfx/"
299 ;;
300 *)
301 ls="$ref"
302 ;;
303 esac
304
305 case "$COMP_WORDBREAKS" in
306 *:*) : great ;;
307 *) pfx="$ref:$pfx" ;;
308 esac
309
310 local IFS=$'\n'
311 COMPREPLY=($(compgen -P "$pfx" \
312 -W "$(git --git-dir="$(__gitdir)" ls-tree "$ls" \
313 | sed '/^100... blob /{
314 s,^.* ,,
315 s,$, ,
316 }
317 /^120000 blob /{
318 s,^.* ,,
319 s,$, ,
320 }
321 /^040000 tree /{
322 s,^.* ,,
323 s,$,/,
324 }
325 s/^.* //')" \
326 -- "$cur"))
327 ;;
328 *)
329 __gitcomp "$(__git_refs)"
330 ;;
331 esac
332}
333
334__git_complete_revlist ()
335{
336 local pfx cur="${COMP_WORDS[COMP_CWORD]}"
337 case "$cur" in
338 *...*)
339 pfx="${cur%...*}..."
340 cur="${cur#*...}"
341 __gitcomp "$(__git_refs)" "$pfx" "$cur"
342 ;;
343 *..*)
344 pfx="${cur%..*}.."
345 cur="${cur#*..}"
346 __gitcomp "$(__git_refs)" "$pfx" "$cur"
347 ;;
348 *)
349 __gitcomp "$(__git_refs)"
350 ;;
351 esac
352}
353
354__git_all_commands ()
355{
356 if [ -n "$__git_all_commandlist" ]; then
357 echo "$__git_all_commandlist"
358 return
359 fi
360 local i IFS=" "$'\n'
361 for i in $(git help -a|egrep '^ ')
362 do
363 case $i in
364 *--*) : helper pattern;;
365 *) echo $i;;
366 esac
367 done
368}
369__git_all_commandlist=
370__git_all_commandlist="$(__git_all_commands 2>/dev/null)"
371
372__git_porcelain_commands ()
373{
374 if [ -n "$__git_porcelain_commandlist" ]; then
375 echo "$__git_porcelain_commandlist"
376 return
377 fi
378 local i IFS=" "$'\n'
379 for i in "help" $(__git_all_commands)
380 do
381 case $i in
382 *--*) : helper pattern;;
383 applymbox) : ask gittus;;
384 applypatch) : ask gittus;;
385 archimport) : import;;
386 cat-file) : plumbing;;
387 check-attr) : plumbing;;
388 check-ref-format) : plumbing;;
389 commit-tree) : plumbing;;
390 cvsexportcommit) : export;;
391 cvsimport) : import;;
392 cvsserver) : daemon;;
393 daemon) : daemon;;
394 diff-files) : plumbing;;
395 diff-index) : plumbing;;
396 diff-tree) : plumbing;;
397 fast-import) : import;;
398 fsck-objects) : plumbing;;
399 fetch-pack) : plumbing;;
400 fmt-merge-msg) : plumbing;;
401 for-each-ref) : plumbing;;
402 hash-object) : plumbing;;
403 http-*) : transport;;
404 index-pack) : plumbing;;
405 init-db) : deprecated;;
406 local-fetch) : plumbing;;
407 mailinfo) : plumbing;;
408 mailsplit) : plumbing;;
409 merge-*) : plumbing;;
410 mktree) : plumbing;;
411 mktag) : plumbing;;
412 pack-objects) : plumbing;;
413 pack-redundant) : plumbing;;
414 pack-refs) : plumbing;;
415 parse-remote) : plumbing;;
416 patch-id) : plumbing;;
417 peek-remote) : plumbing;;
418 prune) : plumbing;;
419 prune-packed) : plumbing;;
420 quiltimport) : import;;
421 read-tree) : plumbing;;
422 receive-pack) : plumbing;;
423 reflog) : plumbing;;
424 repo-config) : deprecated;;
425 rerere) : plumbing;;
426 rev-list) : plumbing;;
427 rev-parse) : plumbing;;
428 runstatus) : plumbing;;
429 sh-setup) : internal;;
430 shell) : daemon;;
431 send-pack) : plumbing;;
432 show-index) : plumbing;;
433 ssh-*) : transport;;
434 stripspace) : plumbing;;
435 symbolic-ref) : plumbing;;
436 tar-tree) : deprecated;;
437 unpack-file) : plumbing;;
438 unpack-objects) : plumbing;;
439 update-index) : plumbing;;
440 update-ref) : plumbing;;
441 update-server-info) : daemon;;
442 upload-archive) : plumbing;;
443 upload-pack) : plumbing;;
444 write-tree) : plumbing;;
445 verify-tag) : plumbing;;
446 *) echo $i;;
447 esac
448 done
449}
450__git_porcelain_commandlist=
451__git_porcelain_commandlist="$(__git_porcelain_commands 2>/dev/null)"
452
453__git_aliases ()
454{
455 local i IFS=$'\n'
456 for i in $(git --git-dir="$(__gitdir)" config --list); do
457 case "$i" in
458 alias.*)
459 i="${i#alias.}"
460 echo "${i/=*/}"
461 ;;
462 esac
463 done
464}
465
466__git_aliased_command ()
467{
468 local word cmdline=$(git --git-dir="$(__gitdir)" \
469 config --get "alias.$1")
470 for word in $cmdline; do
471 if [ "${word##-*}" ]; then
472 echo $word
473 return
474 fi
475 done
476}
477
478__git_find_subcommand ()
479{
480 local word subcommand c=1
481
482 while [ $c -lt $COMP_CWORD ]; do
483 word="${COMP_WORDS[c]}"
484 for subcommand in $1; do
485 if [ "$subcommand" = "$word" ]; then
486 echo "$subcommand"
487 return
488 fi
489 done
490 c=$((++c))
491 done
492}
493
494__git_has_doubledash ()
495{
496 local c=1
497 while [ $c -lt $COMP_CWORD ]; do
498 if [ "--" = "${COMP_WORDS[c]}" ]; then
499 return 0
500 fi
501 c=$((++c))
502 done
503 return 1
504}
505
506__git_whitespacelist="nowarn warn error error-all fix"
507
508_git_am ()
509{
510 local cur="${COMP_WORDS[COMP_CWORD]}" dir="$(__gitdir)"
511 if [ -d "$dir"/rebase-apply ]; then
512 __gitcomp "--skip --resolved --abort"
513 return
514 fi
515 case "$cur" in
516 --whitespace=*)
517 __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
518 return
519 ;;
520 --*)
521 __gitcomp "
522 --signoff --utf8 --binary --3way --interactive
523 --whitespace=
524 "
525 return
526 esac
527 COMPREPLY=()
528}
529
530_git_apply ()
531{
532 local cur="${COMP_WORDS[COMP_CWORD]}"
533 case "$cur" in
534 --whitespace=*)
535 __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
536 return
537 ;;
538 --*)
539 __gitcomp "
540 --stat --numstat --summary --check --index
541 --cached --index-info --reverse --reject --unidiff-zero
542 --apply --no-add --exclude=
543 --whitespace= --inaccurate-eof --verbose
544 "
545 return
546 esac
547 COMPREPLY=()
548}
549
550_git_add ()
551{
552 __git_has_doubledash && return
553
554 local cur="${COMP_WORDS[COMP_CWORD]}"
555 case "$cur" in
556 --*)
557 __gitcomp "
558 --interactive --refresh --patch --update --dry-run
559 --ignore-errors
560 "
561 return
562 esac
563 COMPREPLY=()
564}
565
566_git_archive ()
567{
568 local cur="${COMP_WORDS[COMP_CWORD]}"
569 case "$cur" in
570 --format=*)
571 __gitcomp "$(git archive --list)" "" "${cur##--format=}"
572 return
573 ;;
574 --remote=*)
575 __gitcomp "$(__git_remotes)" "" "${cur##--remote=}"
576 return
577 ;;
578 --*)
579 __gitcomp "
580 --format= --list --verbose
581 --prefix= --remote= --exec=
582 "
583 return
584 ;;
585 esac
586 __git_complete_file
587}
588
589_git_bisect ()
590{
591 __git_has_doubledash && return
592
593 local subcommands="start bad good skip reset visualize replay log run"
594 local subcommand="$(__git_find_subcommand "$subcommands")"
595 if [ -z "$subcommand" ]; then
596 __gitcomp "$subcommands"
597 return
598 fi
599
600 case "$subcommand" in
601 bad|good|reset|skip)
602 __gitcomp "$(__git_refs)"
603 ;;
604 *)
605 COMPREPLY=()
606 ;;
607 esac
608}
609
610_git_branch ()
611{
612 local i c=1 only_local_ref="n" has_r="n"
613
614 while [ $c -lt $COMP_CWORD ]; do
615 i="${COMP_WORDS[c]}"
616 case "$i" in
617 -d|-m) only_local_ref="y" ;;
618 -r) has_r="y" ;;
619 esac
620 c=$((++c))
621 done
622
623 case "${COMP_WORDS[COMP_CWORD]}" in
624 --*=*) COMPREPLY=() ;;
625 --*)
626 __gitcomp "
627 --color --no-color --verbose --abbrev= --no-abbrev
628 --track --no-track --contains --merged --no-merged
629 "
630 ;;
631 *)
632 if [ $only_local_ref = "y" -a $has_r = "n" ]; then
633 __gitcomp "$(__git_heads)"
634 else
635 __gitcomp "$(__git_refs)"
636 fi
637 ;;
638 esac
639}
640
641_git_bundle ()
642{
643 local mycword="$COMP_CWORD"
644 case "${COMP_WORDS[0]}" in
645 git)
646 local cmd="${COMP_WORDS[2]}"
647 mycword="$((mycword-1))"
648 ;;
649 git-bundle*)
650 local cmd="${COMP_WORDS[1]}"
651 ;;
652 esac
653 case "$mycword" in
654 1)
655 __gitcomp "create list-heads verify unbundle"
656 ;;
657 2)
658 # looking for a file
659 ;;
660 *)
661 case "$cmd" in
662 create)
663 __git_complete_revlist
664 ;;
665 esac
666 ;;
667 esac
668}
669
670_git_checkout ()
671{
672 __git_has_doubledash && return
673
674 __gitcomp "$(__git_refs)"
675}
676
677_git_cherry ()
678{
679 __gitcomp "$(__git_refs)"
680}
681
682_git_cherry_pick ()
683{
684 local cur="${COMP_WORDS[COMP_CWORD]}"
685 case "$cur" in
686 --*)
687 __gitcomp "--edit --no-commit"
688 ;;
689 *)
690 __gitcomp "$(__git_refs)"
691 ;;
692 esac
693}
694
695_git_clean ()
696{
697 __git_has_doubledash && return
698
699 local cur="${COMP_WORDS[COMP_CWORD]}"
700 case "$cur" in
701 --*)
702 __gitcomp "--dry-run --quiet"
703 return
704 ;;
705 esac
706 COMPREPLY=()
707}
708
709_git_clone ()
710{
711 local cur="${COMP_WORDS[COMP_CWORD]}"
712 case "$cur" in
713 --*)
714 __gitcomp "
715 --local
716 --no-hardlinks
717 --shared
718 --reference
719 --quiet
720 --no-checkout
721 --bare
722 --mirror
723 --origin
724 --upload-pack
725 --template=
726 --depth
727 "
728 return
729 ;;
730 esac
731 COMPREPLY=()
732}
733
734_git_commit ()
735{
736 __git_has_doubledash && return
737
738 local cur="${COMP_WORDS[COMP_CWORD]}"
739 case "$cur" in
740 --*)
741 __gitcomp "
742 --all --author= --signoff --verify --no-verify
743 --edit --amend --include --only
744 "
745 return
746 esac
747 COMPREPLY=()
748}
749
750_git_describe ()
751{
752 local cur="${COMP_WORDS[COMP_CWORD]}"
753 case "$cur" in
754 --*)
755 __gitcomp "
756 --all --tags --contains --abbrev= --candidates=
757 --exact-match --debug --long --match --always
758 "
759 return
760 esac
761 __gitcomp "$(__git_refs)"
762}
763
764_git_diff ()
765{
766 __git_has_doubledash && return
767
768 local cur="${COMP_WORDS[COMP_CWORD]}"
769 case "$cur" in
770 --*)
771 __gitcomp "--cached --stat --numstat --shortstat --summary
772 --patch-with-stat --name-only --name-status --color
773 --no-color --color-words --no-renames --check
774 --full-index --binary --abbrev --diff-filter
775 --find-copies-harder --pickaxe-all --pickaxe-regex
776 --text --ignore-space-at-eol --ignore-space-change
777 --ignore-all-space --exit-code --quiet --ext-diff
778 --no-ext-diff
779 --no-prefix --src-prefix= --dst-prefix=
780 --base --ours --theirs
781 "
782 return
783 ;;
784 esac
785 __git_complete_file
786}
787
788_git_fetch ()
789{
790 local cur="${COMP_WORDS[COMP_CWORD]}"
791
792 case "${COMP_WORDS[0]},$COMP_CWORD" in
793 git-fetch*,1)
794 __gitcomp "$(__git_remotes)"
795 ;;
796 git,2)
797 __gitcomp "$(__git_remotes)"
798 ;;
799 *)
800 case "$cur" in
801 *:*)
802 local pfx=""
803 case "$COMP_WORDBREAKS" in
804 *:*) : great ;;
805 *) pfx="${cur%%:*}:" ;;
806 esac
807 __gitcomp "$(__git_refs)" "$pfx" "${cur#*:}"
808 ;;
809 *)
810 local remote
811 case "${COMP_WORDS[0]}" in
812 git-fetch) remote="${COMP_WORDS[1]}" ;;
813 git) remote="${COMP_WORDS[2]}" ;;
814 esac
815 __gitcomp "$(__git_refs2 "$remote")"
816 ;;
817 esac
818 ;;
819 esac
820}
821
822_git_format_patch ()
823{
824 local cur="${COMP_WORDS[COMP_CWORD]}"
825 case "$cur" in
826 --*)
827 __gitcomp "
828 --stdout --attach --thread
829 --output-directory
830 --numbered --start-number
831 --numbered-files
832 --keep-subject
833 --signoff
834 --in-reply-to=
835 --full-index --binary
836 --not --all
837 --cover-letter
838 --no-prefix --src-prefix= --dst-prefix=
839 "
840 return
841 ;;
842 esac
843 __git_complete_revlist
844}
845
846_git_gc ()
847{
848 local cur="${COMP_WORDS[COMP_CWORD]}"
849 case "$cur" in
850 --*)
851 __gitcomp "--prune --aggressive"
852 return
853 ;;
854 esac
855 COMPREPLY=()
856}
857
858_git_grep ()
859{
860 __git_has_doubledash && return
861
862 local cur="${COMP_WORDS[COMP_CWORD]}"
863 case "$cur" in
864 --*)
865 __gitcomp "
866 --cached
867 --text --ignore-case --word-regexp --invert-match
868 --full-name
869 --extended-regexp --basic-regexp --fixed-strings
870 --files-with-matches --name-only
871 --files-without-match
872 --count
873 --and --or --not --all-match
874 "
875 return
876 ;;
877 esac
878 COMPREPLY=()
879}
880
881_git_help ()
882{
883 local cur="${COMP_WORDS[COMP_CWORD]}"
884 case "$cur" in
885 --*)
886 __gitcomp "--all --info --man --web"
887 return
888 ;;
889 esac
890 __gitcomp "$(__git_all_commands)
891 attributes cli core-tutorial cvs-migration
892 diffcore gitk glossary hooks ignore modules
893 repository-layout tutorial tutorial-2
894 "
895}
896
897_git_init ()
898{
899 local cur="${COMP_WORDS[COMP_CWORD]}"
900 case "$cur" in
901 --shared=*)
902 __gitcomp "
903 false true umask group all world everybody
904 " "" "${cur##--shared=}"
905 return
906 ;;
907 --*)
908 __gitcomp "--quiet --bare --template= --shared --shared="
909 return
910 ;;
911 esac
912 COMPREPLY=()
913}
914
915_git_ls_files ()
916{
917 __git_has_doubledash && return
918
919 local cur="${COMP_WORDS[COMP_CWORD]}"
920 case "$cur" in
921 --*)
922 __gitcomp "--cached --deleted --modified --others --ignored
923 --stage --directory --no-empty-directory --unmerged
924 --killed --exclude= --exclude-from=
925 --exclude-per-directory= --exclude-standard
926 --error-unmatch --with-tree= --full-name
927 --abbrev --ignored --exclude-per-directory
928 "
929 return
930 ;;
931 esac
932 COMPREPLY=()
933}
934
935_git_ls_remote ()
936{
937 __gitcomp "$(__git_remotes)"
938}
939
940_git_ls_tree ()
941{
942 __git_complete_file
943}
944
945_git_log ()
946{
947 __git_has_doubledash && return
948
949 local cur="${COMP_WORDS[COMP_CWORD]}"
950 case "$cur" in
951 --pretty=*)
952 __gitcomp "
953 oneline short medium full fuller email raw
954 " "" "${cur##--pretty=}"
955 return
956 ;;
957 --date=*)
958 __gitcomp "
959 relative iso8601 rfc2822 short local default
960 " "" "${cur##--date=}"
961 return
962 ;;
963 --*)
964 __gitcomp "
965 --max-count= --max-age= --since= --after=
966 --min-age= --before= --until=
967 --root --topo-order --date-order --reverse
968 --no-merges --follow
969 --abbrev-commit --abbrev=
970 --relative-date --date=
971 --author= --committer= --grep=
972 --all-match
973 --pretty= --name-status --name-only --raw
974 --not --all
975 --left-right --cherry-pick
976 --graph
977 --stat --numstat --shortstat
978 --decorate --diff-filter=
979 --color-words --walk-reflogs
980 --parents --children --full-history
981 --merge
982 "
983 return
984 ;;
985 esac
986 __git_complete_revlist
987}
988
989_git_merge ()
990{
991 local cur="${COMP_WORDS[COMP_CWORD]}"
992 case "${COMP_WORDS[COMP_CWORD-1]}" in
993 -s|--strategy)
994 __gitcomp "$(__git_merge_strategies)"
995 return
996 esac
997 case "$cur" in
998 --strategy=*)
999 __gitcomp "$(__git_merge_strategies)" "" "${cur##--strategy=}"
1000 return
1001 ;;
1002 --*)
1003 __gitcomp "
1004 --no-commit --no-stat --log --no-log --squash --strategy
1005 "
1006 return
1007 esac
1008 __gitcomp "$(__git_refs)"
1009}
1010
1011_git_mergetool ()
1012{
1013 local cur="${COMP_WORDS[COMP_CWORD]}"
1014 case "$cur" in
1015 --tool=*)
1016 __gitcomp "
1017 kdiff3 tkdiff meld xxdiff emerge
1018 vimdiff gvimdiff ecmerge opendiff
1019 " "" "${cur##--tool=}"
1020 return
1021 ;;
1022 --*)
1023 __gitcomp "--tool="
1024 return
1025 ;;
1026 esac
1027 COMPREPLY=()
1028}
1029
1030_git_merge_base ()
1031{
1032 __gitcomp "$(__git_refs)"
1033}
1034
1035_git_mv ()
1036{
1037 local cur="${COMP_WORDS[COMP_CWORD]}"
1038 case "$cur" in
1039 --*)
1040 __gitcomp "--dry-run"
1041 return
1042 ;;
1043 esac
1044 COMPREPLY=()
1045}
1046
1047_git_name_rev ()
1048{
1049 __gitcomp "--tags --all --stdin"
1050}
1051
1052_git_pull ()
1053{
1054 local cur="${COMP_WORDS[COMP_CWORD]}"
1055
1056 case "${COMP_WORDS[0]},$COMP_CWORD" in
1057 git-pull*,1)
1058 __gitcomp "$(__git_remotes)"
1059 ;;
1060 git,2)
1061 __gitcomp "$(__git_remotes)"
1062 ;;
1063 *)
1064 local remote
1065 case "${COMP_WORDS[0]}" in
1066 git-pull) remote="${COMP_WORDS[1]}" ;;
1067 git) remote="${COMP_WORDS[2]}" ;;
1068 esac
1069 __gitcomp "$(__git_refs "$remote")"
1070 ;;
1071 esac
1072}
1073
1074_git_push ()
1075{
1076 local cur="${COMP_WORDS[COMP_CWORD]}"
1077
1078 case "${COMP_WORDS[0]},$COMP_CWORD" in
1079 git-push*,1)
1080 __gitcomp "$(__git_remotes)"
1081 ;;
1082 git,2)
1083 __gitcomp "$(__git_remotes)"
1084 ;;
1085 *)
1086 case "$cur" in
1087 *:*)
1088 local remote
1089 case "${COMP_WORDS[0]}" in
1090 git-push) remote="${COMP_WORDS[1]}" ;;
1091 git) remote="${COMP_WORDS[2]}" ;;
1092 esac
1093
1094 local pfx=""
1095 case "$COMP_WORDBREAKS" in
1096 *:*) : great ;;
1097 *) pfx="${cur%%:*}:" ;;
1098 esac
1099
1100 __gitcomp "$(__git_refs "$remote")" "$pfx" "${cur#*:}"
1101 ;;
1102 +*)
1103 __gitcomp "$(__git_refs)" + "${cur#+}"
1104 ;;
1105 *)
1106 __gitcomp "$(__git_refs)"
1107 ;;
1108 esac
1109 ;;
1110 esac
1111}
1112
1113_git_rebase ()
1114{
1115 local cur="${COMP_WORDS[COMP_CWORD]}" dir="$(__gitdir)"
1116 if [ -d "$dir"/rebase-apply ] || [ -d "$dir"/rebase-merge ]; then
1117 __gitcomp "--continue --skip --abort"
1118 return
1119 fi
1120 case "${COMP_WORDS[COMP_CWORD-1]}" in
1121 -s|--strategy)
1122 __gitcomp "$(__git_merge_strategies)"
1123 return
1124 esac
1125 case "$cur" in
1126 --strategy=*)
1127 __gitcomp "$(__git_merge_strategies)" "" "${cur##--strategy=}"
1128 return
1129 ;;
1130 --*)
1131 __gitcomp "--onto --merge --strategy --interactive"
1132 return
1133 esac
1134 __gitcomp "$(__git_refs)"
1135}
1136
1137_git_send_email ()
1138{
1139 local cur="${COMP_WORDS[COMP_CWORD]}"
1140 case "$cur" in
1141 --*)
1142 __gitcomp "--bcc --cc --cc-cmd --chain-reply-to --compose
1143 --dry-run --envelope-sender --from --identity
1144 --in-reply-to --no-chain-reply-to --no-signed-off-by-cc
1145 --no-suppress-from --no-thread --quiet
1146 --signed-off-by-cc --smtp-pass --smtp-server
1147 --smtp-server-port --smtp-ssl --smtp-user --subject
1148 --suppress-cc --suppress-from --thread --to"
1149 return
1150 ;;
1151 esac
1152 COMPREPLY=()
1153}
1154
1155_git_config ()
1156{
1157 local cur="${COMP_WORDS[COMP_CWORD]}"
1158 local prv="${COMP_WORDS[COMP_CWORD-1]}"
1159 case "$prv" in
1160 branch.*.remote)
1161 __gitcomp "$(__git_remotes)"
1162 return
1163 ;;
1164 branch.*.merge)
1165 __gitcomp "$(__git_refs)"
1166 return
1167 ;;
1168 remote.*.fetch)
1169 local remote="${prv#remote.}"
1170 remote="${remote%.fetch}"
1171 __gitcomp "$(__git_refs_remotes "$remote")"
1172 return
1173 ;;
1174 remote.*.push)
1175 local remote="${prv#remote.}"
1176 remote="${remote%.push}"
1177 __gitcomp "$(git --git-dir="$(__gitdir)" \
1178 for-each-ref --format='%(refname):%(refname)' \
1179 refs/heads)"
1180 return
1181 ;;
1182 pull.twohead|pull.octopus)
1183 __gitcomp "$(__git_merge_strategies)"
1184 return
1185 ;;
1186 color.branch|color.diff|color.status)
1187 __gitcomp "always never auto"
1188 return
1189 ;;
1190 color.*.*)
1191 __gitcomp "
1192 black red green yellow blue magenta cyan white
1193 bold dim ul blink reverse
1194 "
1195 return
1196 ;;
1197 *.*)
1198 COMPREPLY=()
1199 return
1200 ;;
1201 esac
1202 case "$cur" in
1203 --*)
1204 __gitcomp "
1205 --global --system --file=
1206 --list --replace-all
1207 --get --get-all --get-regexp
1208 --add --unset --unset-all
1209 --remove-section --rename-section
1210 "
1211 return
1212 ;;
1213 branch.*.*)
1214 local pfx="${cur%.*}."
1215 cur="${cur##*.}"
1216 __gitcomp "remote merge" "$pfx" "$cur"
1217 return
1218 ;;
1219 branch.*)
1220 local pfx="${cur%.*}."
1221 cur="${cur#*.}"
1222 __gitcomp "$(__git_heads)" "$pfx" "$cur" "."
1223 return
1224 ;;
1225 remote.*.*)
1226 local pfx="${cur%.*}."
1227 cur="${cur##*.}"
1228 __gitcomp "
1229 url fetch push skipDefaultUpdate
1230 receivepack uploadpack tagopt
1231 " "$pfx" "$cur"
1232 return
1233 ;;
1234 remote.*)
1235 local pfx="${cur%.*}."
1236 cur="${cur#*.}"
1237 __gitcomp "$(__git_remotes)" "$pfx" "$cur" "."
1238 return
1239 ;;
1240 esac
1241 __gitcomp "
1242 apply.whitespace
1243 core.fileMode
1244 core.gitProxy
1245 core.ignoreStat
1246 core.preferSymlinkRefs
1247 core.logAllRefUpdates
1248 core.loosecompression
1249 core.repositoryFormatVersion
1250 core.sharedRepository
1251 core.warnAmbiguousRefs
1252 core.compression
1253 core.packedGitWindowSize
1254 core.packedGitLimit
1255 clean.requireForce
1256 color.branch
1257 color.branch.current
1258 color.branch.local
1259 color.branch.remote
1260 color.branch.plain
1261 color.diff
1262 color.diff.plain
1263 color.diff.meta
1264 color.diff.frag
1265 color.diff.old
1266 color.diff.new
1267 color.diff.commit
1268 color.diff.whitespace
1269 color.pager
1270 color.status
1271 color.status.header
1272 color.status.added
1273 color.status.changed
1274 color.status.untracked
1275 diff.renameLimit
1276 diff.renames
1277 fetch.unpackLimit
1278 format.headers
1279 format.subjectprefix
1280 gitcvs.enabled
1281 gitcvs.logfile
1282 gitcvs.allbinary
1283 gitcvs.dbname gitcvs.dbdriver gitcvs.dbuser gitcvs.dbpass
1284 gitcvs.dbtablenameprefix
1285 gc.packrefs
1286 gc.reflogexpire
1287 gc.reflogexpireunreachable
1288 gc.rerereresolved
1289 gc.rerereunresolved
1290 http.sslVerify
1291 http.sslCert
1292 http.sslKey
1293 http.sslCAInfo
1294 http.sslCAPath
1295 http.maxRequests
1296 http.lowSpeedLimit
1297 http.lowSpeedTime
1298 http.noEPSV
1299 i18n.commitEncoding
1300 i18n.logOutputEncoding
1301 log.showroot
1302 merge.tool
1303 merge.summary
1304 merge.verbosity
1305 pack.window
1306 pack.depth
1307 pack.windowMemory
1308 pack.compression
1309 pack.deltaCacheSize
1310 pack.deltaCacheLimit
1311 pull.octopus
1312 pull.twohead
1313 repack.useDeltaBaseOffset
1314 showbranch.default
1315 tar.umask
1316 transfer.unpackLimit
1317 receive.unpackLimit
1318 receive.denyNonFastForwards
1319 user.name
1320 user.email
1321 user.signingkey
1322 branch. remote.
1323 "
1324}
1325
1326_git_remote ()
1327{
1328 local subcommands="add rm show prune update"
1329 local subcommand="$(__git_find_subcommand "$subcommands")"
1330 if [ -z "$subcommand" ]; then
1331 __gitcomp "$subcommands"
1332 return
1333 fi
1334
1335 case "$subcommand" in
1336 rm|show|prune)
1337 __gitcomp "$(__git_remotes)"
1338 ;;
1339 update)
1340 local i c='' IFS=$'\n'
1341 for i in $(git --git-dir="$(__gitdir)" config --list); do
1342 case "$i" in
1343 remotes.*)
1344 i="${i#remotes.}"
1345 c="$c ${i/=*/}"
1346 ;;
1347 esac
1348 done
1349 __gitcomp "$c"
1350 ;;
1351 *)
1352 COMPREPLY=()
1353 ;;
1354 esac
1355}
1356
1357_git_reset ()
1358{
1359 __git_has_doubledash && return
1360
1361 local cur="${COMP_WORDS[COMP_CWORD]}"
1362 case "$cur" in
1363 --*)
1364 __gitcomp "--mixed --hard --soft"
1365 return
1366 ;;
1367 esac
1368 __gitcomp "$(__git_refs)"
1369}
1370
1371_git_revert ()
1372{
1373 local cur="${COMP_WORDS[COMP_CWORD]}"
1374 case "$cur" in
1375 --*)
1376 __gitcomp "--edit --mainline --no-edit --no-commit --signoff"
1377 return
1378 ;;
1379 esac
1380 COMPREPLY=()
1381}
1382
1383_git_rm ()
1384{
1385 __git_has_doubledash && return
1386
1387 local cur="${COMP_WORDS[COMP_CWORD]}"
1388 case "$cur" in
1389 --*)
1390 __gitcomp "--cached --dry-run --ignore-unmatch --quiet"
1391 return
1392 ;;
1393 esac
1394 COMPREPLY=()
1395}
1396
1397_git_shortlog ()
1398{
1399 __git_has_doubledash && return
1400
1401 local cur="${COMP_WORDS[COMP_CWORD]}"
1402 case "$cur" in
1403 --*)
1404 __gitcomp "
1405 --max-count= --max-age= --since= --after=
1406 --min-age= --before= --until=
1407 --no-merges
1408 --author= --committer= --grep=
1409 --all-match
1410 --not --all
1411 --numbered --summary
1412 "
1413 return
1414 ;;
1415 esac
1416 __git_complete_revlist
1417}
1418
1419_git_show ()
1420{
1421 local cur="${COMP_WORDS[COMP_CWORD]}"
1422 case "$cur" in
1423 --pretty=*)
1424 __gitcomp "
1425 oneline short medium full fuller email raw
1426 " "" "${cur##--pretty=}"
1427 return
1428 ;;
1429 --*)
1430 __gitcomp "--pretty="
1431 return
1432 ;;
1433 esac
1434 __git_complete_file
1435}
1436
1437_git_show_branch ()
1438{
1439 local cur="${COMP_WORDS[COMP_CWORD]}"
1440 case "$cur" in
1441 --*)
1442 __gitcomp "
1443 --all --remotes --topo-order --current --more=
1444 --list --independent --merge-base --no-name
1445 --sha1-name --topics --reflog
1446 "
1447 return
1448 ;;
1449 esac
1450 __git_complete_revlist
1451}
1452
1453_git_stash ()
1454{
1455 local subcommands='save list show apply clear drop pop create branch'
1456 local subcommand="$(__git_find_subcommand "$subcommands")"
1457 if [ -z "$subcommand" ]; then
1458 __gitcomp "$subcommands"
1459 else
1460 local cur="${COMP_WORDS[COMP_CWORD]}"
1461 case "$subcommand,$cur" in
1462 save,--*)
1463 __gitcomp "--keep-index"
1464 ;;
1465 apply,--*)
1466 __gitcomp "--index"
1467 ;;
1468 show,--*|drop,--*|pop,--*|branch,--*)
1469 COMPREPLY=()
1470 ;;
1471 show,*|apply,*|drop,*|pop,*|branch,*)
1472 __gitcomp "$(git --git-dir="$(__gitdir)" stash list \
1473 | sed -n -e 's/:.*//p')"
1474 ;;
1475 *)
1476 COMPREPLY=()
1477 ;;
1478 esac
1479 fi
1480}
1481
1482_git_submodule ()
1483{
1484 __git_has_doubledash && return
1485
1486 local subcommands="add status init update"
1487 if [ -z "$(__git_find_subcommand "$subcommands")" ]; then
1488 local cur="${COMP_WORDS[COMP_CWORD]}"
1489 case "$cur" in
1490 --*)
1491 __gitcomp "--quiet --cached"
1492 ;;
1493 *)
1494 __gitcomp "$subcommands"
1495 ;;
1496 esac
1497 return
1498 fi
1499}
1500
1501_git_svn ()
1502{
1503 local subcommands="
1504 init fetch clone rebase dcommit log find-rev
1505 set-tree commit-diff info create-ignore propget
1506 proplist show-ignore show-externals
1507 "
1508 local subcommand="$(__git_find_subcommand "$subcommands")"
1509 if [ -z "$subcommand" ]; then
1510 __gitcomp "$subcommands"
1511 else
1512 local remote_opts="--username= --config-dir= --no-auth-cache"
1513 local fc_opts="
1514 --follow-parent --authors-file= --repack=
1515 --no-metadata --use-svm-props --use-svnsync-props
1516 --log-window-size= --no-checkout --quiet
1517 --repack-flags --user-log-author $remote_opts
1518 "
1519 local init_opts="
1520 --template= --shared= --trunk= --tags=
1521 --branches= --stdlayout --minimize-url
1522 --no-metadata --use-svm-props --use-svnsync-props
1523 --rewrite-root= $remote_opts
1524 "
1525 local cmt_opts="
1526 --edit --rmdir --find-copies-harder --copy-similarity=
1527 "
1528
1529 local cur="${COMP_WORDS[COMP_CWORD]}"
1530 case "$subcommand,$cur" in
1531 fetch,--*)
1532 __gitcomp "--revision= --fetch-all $fc_opts"
1533 ;;
1534 clone,--*)
1535 __gitcomp "--revision= $fc_opts $init_opts"
1536 ;;
1537 init,--*)
1538 __gitcomp "$init_opts"
1539 ;;
1540 dcommit,--*)
1541 __gitcomp "
1542 --merge --strategy= --verbose --dry-run
1543 --fetch-all --no-rebase $cmt_opts $fc_opts
1544 "
1545 ;;
1546 set-tree,--*)
1547 __gitcomp "--stdin $cmt_opts $fc_opts"
1548 ;;
1549 create-ignore,--*|propget,--*|proplist,--*|show-ignore,--*|\
1550 show-externals,--*)
1551 __gitcomp "--revision="
1552 ;;
1553 log,--*)
1554 __gitcomp "
1555 --limit= --revision= --verbose --incremental
1556 --oneline --show-commit --non-recursive
1557 --authors-file=
1558 "
1559 ;;
1560 rebase,--*)
1561 __gitcomp "
1562 --merge --verbose --strategy= --local
1563 --fetch-all $fc_opts
1564 "
1565 ;;
1566 commit-diff,--*)
1567 __gitcomp "--message= --file= --revision= $cmt_opts"
1568 ;;
1569 info,--*)
1570 __gitcomp "--url"
1571 ;;
1572 *)
1573 COMPREPLY=()
1574 ;;
1575 esac
1576 fi
1577}
1578
1579_git_tag ()
1580{
1581 local i c=1 f=0
1582 while [ $c -lt $COMP_CWORD ]; do
1583 i="${COMP_WORDS[c]}"
1584 case "$i" in
1585 -d|-v)
1586 __gitcomp "$(__git_tags)"
1587 return
1588 ;;
1589 -f)
1590 f=1
1591 ;;
1592 esac
1593 c=$((++c))
1594 done
1595
1596 case "${COMP_WORDS[COMP_CWORD-1]}" in
1597 -m|-F)
1598 COMPREPLY=()
1599 ;;
1600 -*|tag|git-tag)
1601 if [ $f = 1 ]; then
1602 __gitcomp "$(__git_tags)"
1603 else
1604 COMPREPLY=()
1605 fi
1606 ;;
1607 *)
1608 __gitcomp "$(__git_refs)"
1609 ;;
1610 esac
1611}
1612
1613_git ()
1614{
1615 local i c=1 command __git_dir
1616
1617 while [ $c -lt $COMP_CWORD ]; do
1618 i="${COMP_WORDS[c]}"
1619 case "$i" in
1620 --git-dir=*) __git_dir="${i#--git-dir=}" ;;
1621 --bare) __git_dir="." ;;
1622 --version|-p|--paginate) ;;
1623 --help) command="help"; break ;;
1624 *) command="$i"; break ;;
1625 esac
1626 c=$((++c))
1627 done
1628
1629 if [ -z "$command" ]; then
1630 case "${COMP_WORDS[COMP_CWORD]}" in
1631 --*=*) COMPREPLY=() ;;
1632 --*) __gitcomp "
1633 --paginate
1634 --no-pager
1635 --git-dir=
1636 --bare
1637 --version
1638 --exec-path
1639 --work-tree=
1640 --help
1641 "
1642 ;;
1643 *) __gitcomp "$(__git_porcelain_commands) $(__git_aliases)" ;;
1644 esac
1645 return
1646 fi
1647
1648 local expansion=$(__git_aliased_command "$command")
1649 [ "$expansion" ] && command="$expansion"
1650
1651 case "$command" in
1652 am) _git_am ;;
1653 add) _git_add ;;
1654 apply) _git_apply ;;
1655 archive) _git_archive ;;
1656 bisect) _git_bisect ;;
1657 bundle) _git_bundle ;;
1658 branch) _git_branch ;;
1659 checkout) _git_checkout ;;
1660 cherry) _git_cherry ;;
1661 cherry-pick) _git_cherry_pick ;;
1662 clean) _git_clean ;;
1663 clone) _git_clone ;;
1664 commit) _git_commit ;;
1665 config) _git_config ;;
1666 describe) _git_describe ;;
1667 diff) _git_diff ;;
1668 fetch) _git_fetch ;;
1669 format-patch) _git_format_patch ;;
1670 gc) _git_gc ;;
1671 grep) _git_grep ;;
1672 help) _git_help ;;
1673 init) _git_init ;;
1674 log) _git_log ;;
1675 ls-files) _git_ls_files ;;
1676 ls-remote) _git_ls_remote ;;
1677 ls-tree) _git_ls_tree ;;
1678 merge) _git_merge;;
1679 mergetool) _git_mergetool;;
1680 merge-base) _git_merge_base ;;
1681 mv) _git_mv ;;
1682 name-rev) _git_name_rev ;;
1683 pull) _git_pull ;;
1684 push) _git_push ;;
1685 rebase) _git_rebase ;;
1686 remote) _git_remote ;;
1687 reset) _git_reset ;;
1688 revert) _git_revert ;;
1689 rm) _git_rm ;;
1690 send-email) _git_send_email ;;
1691 shortlog) _git_shortlog ;;
1692 show) _git_show ;;
1693 show-branch) _git_show_branch ;;
1694 stash) _git_stash ;;
1695 submodule) _git_submodule ;;
1696 svn) _git_svn ;;
1697 tag) _git_tag ;;
1698 whatchanged) _git_log ;;
1699 *) COMPREPLY=() ;;
1700 esac
1701}
1702
1703_gitk ()
1704{
1705 __git_has_doubledash && return
1706
1707 local cur="${COMP_WORDS[COMP_CWORD]}"
1708 local g="$(git rev-parse --git-dir 2>/dev/null)"
1709 local merge=""
1710 if [ -f $g/MERGE_HEAD ]; then
1711 merge="--merge"
1712 fi
1713 case "$cur" in
1714 --*)
1715 __gitcomp "--not --all $merge"
1716 return
1717 ;;
1718 esac
1719 __git_complete_revlist
1720}
1721
1722complete -o default -o nospace -F _git git
1723complete -o default -o nospace -F _gitk gitk
1724
1725# The following are necessary only for Cygwin, and only are needed
1726# when the user has tab-completed the executable name and consequently
1727# included the '.exe' suffix.
1728#
1729if [ Cygwin = "$(uname -o 2>/dev/null)" ]; then
1730complete -o default -o nospace -F _git git.exe
1731fi