77
88gc_prog_name=" fmt-diff"
99
10- g_obj1=
11- g_obj2=
12-
1310g_config=
1411g_local_rc=
1512
@@ -325,32 +322,48 @@ git_diff () (
325322 -e " s/$( sed_esc -p " b$new " ) /$( sed_esc -s " b/$filename " ) /g"
326323)
327324
328- git_retrieve_file_from_obj () (
329- obj =" $1 "
325+ git_retrieve_file_from_sha () (
326+ sha =" $1 "
330327 file=" $2 "
331328
332- debug " obj = '$obj '"
329+ debug " sha = '$sha '"
333330 debug " file = '$file '"
334331
335- if [ -e " $file " ] && [ " $obj " = " $file " ]; then
336- cat " $file "
337- elif [ -n " $obj " ]; then
338- git show " $obj :$file " 2> /dev/null
339- elif [ -e " $file " ]; then
340- cat " $file "
332+ if [ " $sha " -eq 0 ] 2> /dev/null; then
333+ if [ -n " $file " ]; then
334+ cat " $file "
335+ else
336+ printf ' '
337+ fi
338+ else
339+ git show " $sha " 2> /dev/null
341340 fi
342341)
343342
344- process_file () (
345- obj1=" $1 "
346- obj2=" $2 "
347- line=" $3 "
343+ list_files () (
344+ if ! git rev-parse --is-inside-work-tree 2> /dev/null 1>&2 ; then
345+ [ -s " $1 " ] && printf ' 0 0 %s\n' " $( abspath " $1 " ) "
346+ return
347+ fi
348348
349- old_name=" $( echo " $line " | cut -f1) "
350- cur_name=" $( echo " $line " | cut -f2) "
351- [ -z " $cur_name " ] && cur_name=" $old_name "
349+ if [ -e " $1 " ] && ! git ls-files --error-unmatch " $1 " 2> /dev/null 1>&2 ; then
350+ printf ' 0 0 %s\n' " $( abspath " $1 " ) "
351+ return
352+ fi
353+
354+ # shellcheck disable=SC2086
355+ git diff $g_cached_opt --diff-filter=ARMC --raw " $@ " | \
356+ awk ' { print $3 " " $4 " " $6 " " $7 }'
357+ )
358+
359+ process_file () (
360+ sha1=" $1 "
361+ sha2=" $2 "
362+ old_name=" $3 "
363+ cur_name=" ${4:- $old_name } "
352364
353365 debug " --- PROCESSING: $cur_name ---"
366+ debug " args = " " $@ "
354367
355368 case " $( git_conf_get " $cur_name " ignore) " in
356369 true|1) return ;;
@@ -378,8 +391,8 @@ process_file () (
378391 cur_fmt=" $tempdir " /cur_fmt
379392 old_fmt=" $tempdir " /old_fmt
380393
381- git_retrieve_file_from_obj " $obj1 " " $old_name " > " $old "
382- git_retrieve_file_from_obj " $obj2 " " $cur_name " > " $cur "
394+ git_retrieve_file_from_sha " $sha1 " " " > " $old "
395+ git_retrieve_file_from_sha " $sha2 " " $cur_name " > " $cur "
383396 rm_list__push " $old " " $cur "
384397
385398 if [ ! -s " $cur " ]; then
@@ -404,42 +417,48 @@ process_file () (
404417 fi
405418)
406419
407- # running {{{1
420+ processing () (
421+ outdir=" $( mktemp -d) "
422+ rm_list__push " $outdir "
423+ debug " OUTDIR: $outdir "
408424
409- list_files () (
410- obj1=" $1 "
411- obj2=" $2 "
425+ files=" $( list_files " $@ " ) " # must be before 'cd $repo_root'
412426
413- [ " $obj1 " = " HEAD" ] && obj1=
427+ repo_root=" $( git rev-parse --show-toplevel 2> /dev/null) "
428+ [ -n " $repo_root " ] && { cd " $repo_root " || exit 1; }
414429
415- if ! git rev-parse --is-inside-work-tree 2> /dev/null 1>&2 ; then
416- [ -s " $obj1 " ] && abspath " $obj1 "
417- return
418- fi
430+ i=0
431+ i_len= " $( echo " $files " | wc -l | tr -d ' \n ' | wc -m ) "
432+ while read -r line ; do
433+ [ -z " $line " ] && continue
419434
420- if [ -e " $obj1 " ] && ! git ls-files --error-unmatch " $obj1 " 2> /dev/null 1>&2 ; then
421- abspath " $obj1 "
422- return
423- fi
435+ outfile=" $( printf ' %s/%.*d' " $outdir " " $i_len " " $i " ) "
436+ rm_list__push " $outfile "
424437
425- # shellcheck disable=SC2086
426- git diff $g_cached_opt --diff-filter=ARMC --name-status $obj1 $obj2 | cut -f2-
427- )
438+ # shellcheck disable=SC2086
439+ process_file $line > " $outfile " &
428440
429- setup_env () {
430- TMPDIR= " ${TMPDIR :-/ tmp} " /git- " $gc_prog_name "
431- mkdir -p " $TMPDIR "
432- rm_list__push " $TMPDIR "
441+ i= $(( i + 1 ))
442+ done << EOL
443+ $files
444+ EOL
433445
434- trap ' cleanup' EXIT
435- }
446+ wait
447+
448+ if [ -n " $( ls -A " $outdir " ) " ]; then
449+ cat " $outdir " /* | sh -c " $( git_conf_get pager) "
450+ fi
451+ )
452+
453+ # start {{{1
436454
437455usage () (
438456 cat << EOU
439457EOU
440458)
441459
442- parse_options () {
460+ main () (
461+ # parse options {{{2
443462 while : ; do
444463 case " $1 " in
445464 -h)
@@ -474,8 +493,6 @@ parse_options () {
474493 gf_use_color=0
475494 ;;
476495 --)
477- g_obj1=" $2 "
478- g_obj2=" $3 "
479496 break
480497 ;;
481498 -?* )
@@ -484,20 +501,22 @@ parse_options () {
484501 exit 1
485502 ;;
486503 * )
487- if [ -z " $1 " ]; then
488- break
489- elif [ -z " $g_obj1 " ]; then
490- g_obj1=" $1 "
491- elif [ -z " $g_obj2 " ]; then
492- g_obj2=" $1 "
493- else
494- warn " ignored object: $1 "
495- fi
504+ break
505+ ;;
496506 esac
497507
498508 shift
499509 done
500510
511+ for o in " $@ " ; do
512+ case " $o " in
513+ -?* )
514+ warn " option '$o ' must come before non-option arguments"
515+ return 1
516+ ;;
517+ esac
518+ done
519+
501520 [ -t 1 ] && gf_no_term=0 || gf_no_term=1
502521
503522 repo_root=" $( git rev-parse --show-toplevel 2> /dev/null) "
@@ -510,43 +529,18 @@ parse_options () {
510529 if [ -z " $gf_use_color " ] && [ " $gf_no_term " = 0 ]; then
511530 gf_use_color=1
512531 fi
513- }
514-
515- main () (
516- obj1=" ${1:- HEAD} "
517- obj2=" $2 "
518-
519- outdir=" $( mktemp -d) "
520- rm_list__push " $outdir "
521- debug " OUTDIR: $outdir "
522532
523- files=" $( list_files " $obj1 " " $obj2 " ) " # must be before 'cd $repo_root'
524-
525- repo_root=" $( git rev-parse --show-toplevel 2> /dev/null) "
526- [ -n " $repo_root " ] && { cd " $repo_root " || exit 1; }
527-
528- i=0
529- i_len=" $( echo " $files " | wc -l | tr -d ' \n' | wc -m) "
530- while read -r line; do
531- debug " $line "
532-
533- [ -e " $obj1 " ] && obj1=" HEAD"
534- outfile=" $( printf ' %s/%.*d' " $outdir " " $i_len " " $i " ) "
535-
536- process_file " $obj1 " " $obj2 " " $line " > " $outfile " &
537- rm_list__push " $outfile "
533+ # setup env {{{2
534+ TMPDIR=" ${TMPDIR:-/ tmp} " /git-" $gc_prog_name "
535+ mkdir -p " $TMPDIR "
536+ rm_list__push " $TMPDIR "
538537
539- i=$(( i+ 1 ))
540- done << EOL
541- $files
542- EOL
538+ trap ' cleanup' EXIT
539+ # }}}2
543540
544- wait
545- cat " $outdir " /* | sh -c " $( git_conf_get pager) "
541+ processing " $@ "
546542)
547543
548544# }}}1
549545
550- setup_env
551- parse_options " $@ "
552- main " $g_obj1 " " $g_obj2 "
546+ main " $@ "
0 commit comments