Start the 2.46 cycle
[git.git] / contrib / git-jump / git-jump
blob47e0c557e63f1b236a3ad763e03ac086f1842d23
1 #!/bin/sh
3 usage() {
4 cat <<\EOF
5 usage: git jump [--stdout] <mode> [<args>]
7 Jump to interesting elements in an editor.
8 The <mode> parameter is one of:
10 diff: elements are diff hunks. Arguments are given to diff.
12 merge: elements are merge conflicts. Arguments are given to ls-files -u.
14 grep: elements are grep hits. Arguments are given to git grep or, if
15 configured, to the command in `jump.grepCmd`.
17 ws: elements are whitespace errors. Arguments are given to diff --check.
19 If the optional argument `--stdout` is given, print the quickfix
20 lines to standard output instead of feeding it to the editor.
21 EOF
24 open_editor() {
25 editor=`git var GIT_EDITOR`
26 case "$editor" in
27 *emacs*)
28 # Supported editor values are:
29 # - emacs
30 # - emacsclient
31 # - emacsclient -t
33 # Wait for completion of the asynchronously executed process
34 # to avoid race conditions in case of "emacsclient".
35 eval "$editor --eval \"(let ((buf (grep \\\"cat \$1\\\"))) (pop-to-buffer buf) (select-frame-set-input-focus (selected-frame)) (while (get-buffer-process buf) (sleep-for 0.1)))\""
38 # assume anything else is vi-compatible
39 eval "$editor -q \$1"
41 esac
44 mode_diff() {
45 git diff --no-prefix --relative "$@" |
46 perl -ne '
47 if (m{^\+\+\+ (.*)}) { $file = $1; next }
48 defined($file) or next;
49 if (m/^@@ .*?\+(\d+)/) { $line = $1; next }
50 defined($line) or next;
51 if (/^ /) { $line++; next }
52 if (/^[-+]\s*(.*)/) {
53 print "$file:$line: $1\n";
54 $line = undef;
59 mode_merge() {
60 git ls-files -u "$@" |
61 perl -pe 's/^.*?\t//' |
62 sort -u |
63 while IFS= read fn; do
64 grep -Hn '^<<<<<<<' "$fn"
65 done
68 # Grep -n generates nice quickfix-looking lines by itself,
69 # but let's clean up extra whitespace, so they look better if the
70 # editor shows them to us in the status bar.
71 mode_grep() {
72 cmd=$(git config jump.grepCmd)
73 test -n "$cmd" || cmd="git grep -n --column"
74 $cmd "$@" |
75 perl -pe '
76 s/[ \t]+/ /g;
77 s/^ *//;
81 mode_ws() {
82 git diff --check "$@"
85 use_stdout=
86 while test $# -gt 0; do
87 case "$1" in
88 --stdout)
89 use_stdout=t
91 --*)
92 usage >&2
93 exit 1
96 break
98 esac
99 shift
100 done
101 if test $# -lt 1; then
102 usage >&2
103 exit 1
105 mode=$1; shift
106 type "mode_$mode" >/dev/null 2>&1 || { usage >&2; exit 1; }
108 if test "$use_stdout" = "t"; then
109 "mode_$mode" "$@"
110 exit 0
113 trap 'rm -f "$tmp"' 0 1 2 3 15
114 tmp=`mktemp -t git-jump.XXXXXX` || exit 1
115 "mode_$mode" "$@" >"$tmp"
116 test -s "$tmp" || exit 0
117 open_editor "$tmp"