From: Junio C Hamano Date: Sat, 24 Jan 2009 05:51:38 +0000 (-0800) Subject: Merge branch 'js/patience-diff' X-Git-Tag: v1.6.2-rc0~97 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/5dc1308562ab5991ecada68b06707709bea408c9?hp=-c Merge branch 'js/patience-diff' * js/patience-diff: bash completions: Add the --patience option Introduce the diff option '--patience' Implement the patience diff algorithm Conflicts: contrib/completion/git-completion.bash --- 5dc1308562ab5991ecada68b06707709bea408c9 diff --combined Documentation/diff-options.txt index 43793d7500,808bf87277..1f8ce979bb --- a/Documentation/diff-options.txt +++ b/Documentation/diff-options.txt @@@ -19,12 -19,16 +19,12 @@@ endif::git-format-patch[ ifndef::git-format-patch[] -p:: +-u:: Generate patch (see section on generating patches). {git-diff? This is the default.} endif::git-format-patch[] --u:: - Synonym for "-p". - -U:: - Shorthand for "--unified=". - --unified=:: Generate diffs with lines of context instead of the usual three. Implies "-p". @@@ -36,6 -40,9 +36,9 @@@ --patch-with-raw:: Synonym for "-p --raw". + --patience: + Generate a diff using the "patience diff" algorithm. + --stat[=width[,name-width]]:: Generate a diffstat. You can override the default output width for 80-column terminal by "--stat=width". @@@ -116,7 -123,7 +119,7 @@@ --abbrev[=]:: Instead of showing the full 40-byte hexadecimal object name in diff-raw format output and diff-tree header - lines, show only handful hexdigits prefix. This is + lines, show only a partial prefix. This is independent of --full-index option above, which controls the diff-patch output format. Non default number of digits can be specified with --abbrev=. @@@ -186,28 -193,30 +189,28 @@@ can name which subdirectory to make the output relative to by giving a as an argument. +-a:: --text:: Treat all files as text. --a:: - Shorthand for "--text". - --ignore-space-at-eol:: Ignore changes in whitespace at EOL. +-b:: --ignore-space-change:: Ignore changes in amount of whitespace. This ignores whitespace at line end, and considers all other sequences of one or more whitespace characters to be equivalent. --b:: - Shorthand for "--ignore-space-change". - +-w:: --ignore-all-space:: Ignore whitespace when comparing lines. This ignores differences even if one line has whitespace where the other line has none. --w:: - Shorthand for "--ignore-all-space". +--inter-hunk-context=:: + Show the context between diff hunks, up to the specified number + of lines, thereby fusing hunks that are close to each other. --exit-code:: Make the program exit with codes similar to diff(1). diff --combined Makefile index 270b223adb,33e6fa403e..b4d9cb4949 --- a/Makefile +++ b/Makefile @@@ -1287,7 -1287,7 +1287,7 @@@ $(LIB_FILE): $(LIB_OBJS $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(LIB_OBJS) XDIFF_OBJS=xdiff/xdiffi.o xdiff/xprepare.o xdiff/xutils.o xdiff/xemit.o \ - xdiff/xmerge.o + xdiff/xmerge.o xdiff/xpatience.o $(XDIFF_OBJS): xdiff/xinclude.h xdiff/xmacros.h xdiff/xdiff.h xdiff/xtypes.h \ xdiff/xutils.h xdiff/xprepare.h xdiff/xdiffi.h xdiff/xemit.h @@@ -1307,9 -1307,6 +1307,9 @@@ html info: $(MAKE) -C Documentation info +pdf: + $(MAKE) -C Documentation pdf + TAGS: $(RM) TAGS $(FIND) . -name '*.[hcS]' -print | xargs etags -a @@@ -1356,15 -1353,7 +1356,15 @@@ endi ### Testing rules -TEST_PROGRAMS = test-chmtime$X test-genrandom$X test-date$X test-delta$X test-sha1$X test-match-trees$X test-parse-options$X test-path-utils$X +TEST_PROGRAMS += test-chmtime$X +TEST_PROGRAMS += test-ctype$X +TEST_PROGRAMS += test-date$X +TEST_PROGRAMS += test-delta$X +TEST_PROGRAMS += test-genrandom$X +TEST_PROGRAMS += test-match-trees$X +TEST_PROGRAMS += test-parse-options$X +TEST_PROGRAMS += test-path-utils$X +TEST_PROGRAMS += test-sha1$X all:: $(TEST_PROGRAMS) @@@ -1377,8 -1366,6 +1377,8 @@@ export NO_SVN_TEST test: all $(MAKE) -C t/ all +test-ctype$X: ctype.o + test-date$X: date.o ctype.o test-delta$X: diff-delta.o patch-delta.o @@@ -1444,12 -1431,10 +1444,12 @@@ endi { $(RM) "$$execdir/git-add$X" && \ ln git-add$X "$$execdir/git-add$X" 2>/dev/null || \ cp git-add$X "$$execdir/git-add$X"; } && \ - { $(foreach p,$(filter-out git-add$X,$(BUILT_INS)), $(RM) "$$execdir/$p" && \ - ln "$$execdir/git-add$X" "$$execdir/$p" 2>/dev/null || \ - ln -s "git-add$X" "$$execdir/$p" 2>/dev/null || \ - cp "$$execdir/git-add$X" "$$execdir/$p" || exit;) } && \ + { for p in $(filter-out git-add$X,$(BUILT_INS)); do \ + $(RM) "$$execdir/$$p" && \ + ln "$$execdir/git-add$X" "$$execdir/$$p" 2>/dev/null || \ + ln -s "git-add$X" "$$execdir/$$p" 2>/dev/null || \ + cp "$$execdir/git-add$X" "$$execdir/$$p" || exit; \ + done } && \ ./check_bindir "z$$bindir" "z$$execdir" "$$bindir/git-add$X" install-doc: @@@ -1464,9 -1449,6 +1464,9 @@@ install-html install-info: $(MAKE) -C Documentation install-info +install-pdf: + $(MAKE) -C Documentation install-pdf + quick-install-doc: $(MAKE) -C Documentation quick-install diff --combined contrib/completion/git-completion.bash index 703f4c2e90,b98d765deb..81f70ec644 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@@ -1,4 -1,3 +1,4 @@@ +#!bash # # bash completion support for core Git. # @@@ -51,11 -50,9 +51,11 @@@ case "$COMP_WORDBREAKS" i *) COMP_WORDBREAKS="$COMP_WORDBREAKS:" esac +# __gitdir accepts 0 or 1 arguments (i.e., location) +# returns location of .git repo __gitdir () { - if [ -z "$1" ]; then + if [ -z "${1-}" ]; then if [ -n "$__git_dir" ]; then echo "$__git_dir" elif [ -d .git ]; then @@@ -70,8 -67,6 +70,8 @@@ fi } +# __git_ps1 accepts 0 or 1 arguments (i.e., format string) +# returns text to add to bash PS1 prompt (includes branch name) __git_ps1 () { local g="$(git rev-parse --git-dir 2>/dev/null)" @@@ -116,7 -111,7 +116,7 @@@ fi fi - if [ -n "$1" ]; then + if [ -n "${1-}" ]; then printf "$1" "${b##refs/heads/}$r" else printf " (%s)" "${b##refs/heads/}$r" @@@ -124,7 -119,6 +124,7 @@@ fi } +# __gitcomp_1 requires 2 arguments __gitcomp_1 () { local c IFS=' '$'\t'$'\n' @@@ -137,8 -131,6 +137,8 @@@ done } +# __gitcomp accepts 1, 2, 3, or 4 arguments +# generates completion reply with compgen __gitcomp () { local cur="${COMP_WORDS[COMP_CWORD]}" @@@ -151,23 -143,22 +151,23 @@@ ;; *) local IFS=$'\n' - COMPREPLY=($(compgen -P "$2" \ - -W "$(__gitcomp_1 "$1" "$4")" \ + COMPREPLY=($(compgen -P "${2-}" \ + -W "$(__gitcomp_1 "${1-}" "${4-}")" \ -- "$cur")) ;; esac } +# __git_heads accepts 0 or 1 arguments (to pass to __gitdir) __git_heads () { - local cmd i is_hash=y dir="$(__gitdir "$1")" + local cmd i is_hash=y dir="$(__gitdir "${1-}")" if [ -d "$dir" ]; then git --git-dir="$dir" for-each-ref --format='%(refname:short)' \ refs/heads return fi - for i in $(git ls-remote "$1" 2>/dev/null); do + for i in $(git ls-remote "${1-}" 2>/dev/null); do case "$is_hash,$i" in y,*) is_hash=n ;; n,*^{}) is_hash=y ;; @@@ -177,16 -168,15 +177,16 @@@ done } +# __git_tags accepts 0 or 1 arguments (to pass to __gitdir) __git_tags () { - local cmd i is_hash=y dir="$(__gitdir "$1")" + local cmd i is_hash=y dir="$(__gitdir "${1-}")" if [ -d "$dir" ]; then git --git-dir="$dir" for-each-ref --format='%(refname:short)' \ refs/tags return fi - for i in $(git ls-remote "$1" 2>/dev/null); do + for i in $(git ls-remote "${1-}" 2>/dev/null); do case "$is_hash,$i" in y,*) is_hash=n ;; n,*^{}) is_hash=y ;; @@@ -196,10 -186,9 +196,10 @@@ done } +# __git_refs accepts 0 or 1 arguments (to pass to __gitdir) __git_refs () { - local i is_hash=y dir="$(__gitdir "$1")" + local i is_hash=y dir="$(__gitdir "${1-}")" local cur="${COMP_WORDS[COMP_CWORD]}" format refs if [ -d "$dir" ]; then case "$cur" in @@@ -229,7 -218,6 +229,7 @@@ done } +# __git_refs2 requires 1 argument (to pass to __git_refs) __git_refs2 () { local i @@@ -238,7 -226,6 +238,7 @@@ done } +# __git_refs_remotes requires 1 argument (to pass to ls-remote) __git_refs_remotes () { local cmd i is_hash=y @@@ -483,7 -470,6 +483,7 @@@ __git_aliases ( done } +# __git_aliased_command requires 1 argument __git_aliased_command () { local word cmdline=$(git --git-dir="$(__gitdir)" \ @@@ -496,7 -482,6 +496,7 @@@ done } +# __git_find_subcommand requires 1 argument __git_find_subcommand () { local word subcommand c=1 @@@ -578,7 -563,7 +578,7 @@@ _git_add ( --*) __gitcomp " --interactive --refresh --patch --update --dry-run - --ignore-errors + --ignore-errors --intent-to-add " return esac @@@ -643,6 -628,7 +643,6 @@@ _git_branch ( done case "${COMP_WORDS[COMP_CWORD]}" in - --*=*) COMPREPLY=() ;; --*) __gitcomp " --color --no-color --verbose --abbrev= --no-abbrev @@@ -773,29 -759,24 +773,30 @@@ _git_describe ( __gitcomp "$(__git_refs)" } -_git_diff () -{ - __git_has_doubledash && return - - local cur="${COMP_WORDS[COMP_CWORD]}" - case "$cur" in - --*) - __gitcomp "--cached --stat --numstat --shortstat --summary +__git_diff_common_options="--stat --numstat --shortstat --summary --patch-with-stat --name-only --name-status --color --no-color --color-words --no-renames --check --full-index --binary --abbrev --diff-filter= - --find-copies-harder --pickaxe-all --pickaxe-regex + --find-copies-harder --text --ignore-space-at-eol --ignore-space-change --ignore-all-space --exit-code --quiet --ext-diff --no-ext-diff --no-prefix --src-prefix= --dst-prefix= - --base --ours --theirs + --inter-hunk-context= + --patience + --raw +" + +_git_diff () +{ + __git_has_doubledash && return + + local cur="${COMP_WORDS[COMP_CWORD]}" + case "$cur" in + --*) + __gitcomp "--cached --pickaxe-all --pickaxe-regex + --base --ours --theirs + $__git_diff_common_options " return ;; @@@ -843,8 -824,6 +844,8 @@@ _git_format_patch ( --not --all --cover-letter --no-prefix --src-prefix= --dst-prefix= + --inline --suffix= --ignore-if-in-upstream + --subject-prefix= " return ;; @@@ -952,8 -931,6 +953,8 @@@ _git_ls_tree ( __git_complete_file } +__git_log_pretty_formats="oneline short medium full fuller email raw format:" + _git_log () { __git_has_doubledash && return @@@ -961,7 -938,8 +962,7 @@@ local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --pretty=*) - __gitcomp " - oneline short medium full fuller email raw + __gitcomp "$__git_log_pretty_formats " "" "${cur##--pretty=}" return ;; @@@ -981,16 -959,16 +982,16 @@@ --relative-date --date= --author= --committer= --grep= --all-match - --pretty= --name-status --name-only --raw + --pretty= --not --all --left-right --cherry-pick --graph - --stat --numstat --shortstat - --decorate --diff-filter= - --color-words --walk-reflogs + --decorate + --walk-reflogs --parents --children --full-history --merge - --patience + $__git_diff_common_options + --pickaxe-all --pickaxe-regex " return ;; @@@ -1391,7 -1369,7 +1392,7 @@@ _git_config ( _git_remote () { - local subcommands="add rm show prune update" + local subcommands="add rename rm show prune update" local subcommand="$(__git_find_subcommand "$subcommands")" if [ -z "$subcommand" ]; then __gitcomp "$subcommands" @@@ -1399,7 -1377,7 +1400,7 @@@ fi case "$subcommand" in - rm|show|prune) + rename|rm|show|prune) __gitcomp "$(__git_remotes)" ;; update) @@@ -1427,7 -1405,7 +1428,7 @@@ _git_reset ( local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --*) - __gitcomp "--mixed --hard --soft" + __gitcomp "--merge --mixed --hard --soft" return ;; esac @@@ -1489,14 -1467,13 +1490,14 @@@ _git_show ( local cur="${COMP_WORDS[COMP_CWORD]}" case "$cur" in --pretty=*) - __gitcomp " - oneline short medium full fuller email raw + __gitcomp "$__git_log_pretty_formats " "" "${cur##--pretty=}" return ;; --*) - __gitcomp "--pretty=" + __gitcomp "--pretty= + $__git_diff_common_options + " return ;; esac @@@ -1583,7 -1560,7 +1584,7 @@@ _git_svn ( --follow-parent --authors-file= --repack= --no-metadata --use-svm-props --use-svnsync-props --log-window-size= --no-checkout --quiet - --repack-flags --user-log-author $remote_opts + --repack-flags --user-log-author --localtime $remote_opts " local init_opts=" --template= --shared= --trunk= --tags= @@@ -1697,6 -1674,7 +1698,6 @@@ _git ( if [ -z "$command" ]; then case "${COMP_WORDS[COMP_CWORD]}" in - --*=*) COMPREPLY=() ;; --*) __gitcomp " --paginate --no-pager @@@ -1760,7 -1738,6 +1761,7 @@@ show) _git_show ;; show-branch) _git_show_branch ;; stash) _git_stash ;; + stage) _git_add ;; submodule) _git_submodule ;; svn) _git_svn ;; tag) _git_tag ;; @@@ -1788,16 -1765,13 +1789,16 @@@ _gitk ( __git_complete_revlist } -complete -o default -o nospace -F _git git -complete -o default -o nospace -F _gitk gitk +complete -o bashdefault -o default -o nospace -F _git git 2>/dev/null \ + || complete -o default -o nospace -F _git git +complete -o bashdefault -o default -o nospace -F _gitk gitk 2>/dev/null \ + || complete -o default -o nospace -F _gitk gitk # The following are necessary only for Cygwin, and only are needed # when the user has tab-completed the executable name and consequently # included the '.exe' suffix. # if [ Cygwin = "$(uname -o 2>/dev/null)" ]; then -complete -o default -o nospace -F _git git.exe +complete -o bashdefault -o default -o nospace -F _git git.exe 2>/dev/null \ + || complete -o default -o nospace -F _git git.exe fi diff --combined diff.c index 0731313160,4aeab7746c..82cff975b3 --- a/diff.c +++ b/diff.c @@@ -118,9 -118,7 +118,9 @@@ int git_diff_basic_config(const char *v } /* like GNU diff's --suppress-blank-empty option */ - if (!strcmp(var, "diff.suppress-blank-empty")) { + if (!strcmp(var, "diff.suppressblankempty") || + /* for backwards compatibility */ + !strcmp(var, "diff.suppress-blank-empty")) { diff_suppress_blank_empty = git_config_bool(var, value); return 0; } @@@ -1471,7 -1469,6 +1471,7 @@@ static void builtin_diff(const char *na ecbdata.file = o->file; xpp.flags = XDF_NEED_MINIMAL | o->xdl_opts; xecfg.ctxlen = o->context; + xecfg.interhunkctxlen = o->interhunkcontext; xecfg.flags = XDL_EMIT_FUNCNAMES; if (pe) xdiff_set_find_func(&xecfg, pe->pattern, pe->cflags); @@@ -2042,7 -2039,7 +2042,7 @@@ static void diff_fill_sha1_info(struct if (lstat(one->path, &st) < 0) die("stat %s", one->path); if (index_path(one->sha1, one->path, &st, 0)) - die("cannot hash %s\n", one->path); + die("cannot hash %s", one->path); } } else @@@ -2474,6 -2471,8 +2474,8 @@@ int diff_opt_parse(struct diff_options options->xdl_opts |= XDF_IGNORE_WHITESPACE_CHANGE; else if (!strcmp(arg, "--ignore-space-at-eol")) options->xdl_opts |= XDF_IGNORE_WHITESPACE_AT_EOL; + else if (!strcmp(arg, "--patience")) + options->xdl_opts |= XDF_PATIENCE_DIFF; /* flags options */ else if (!strcmp(arg, "--binary")) { @@@ -2541,9 -2540,6 +2543,9 @@@ options->b_prefix = arg + 13; else if (!strcmp(arg, "--no-prefix")) options->a_prefix = options->b_prefix = ""; + else if (opt_arg(arg, '\0', "inter-hunk-context", + &options->interhunkcontext)) + ; else if (!prefixcmp(arg, "--output=")) { options->file = fopen(arg + strlen("--output="), "w"); options->close_file = 1; diff --combined xdiff/xdiff.h index 361f802319,d238c8263e..4da052a3ff --- a/xdiff/xdiff.h +++ b/xdiff/xdiff.h @@@ -32,6 -32,7 +32,7 @@@ extern "C" #define XDF_IGNORE_WHITESPACE (1 << 2) #define XDF_IGNORE_WHITESPACE_CHANGE (1 << 3) #define XDF_IGNORE_WHITESPACE_AT_EOL (1 << 4) + #define XDF_PATIENCE_DIFF (1 << 5) #define XDF_WHITESPACE_FLAGS (XDF_IGNORE_WHITESPACE | XDF_IGNORE_WHITESPACE_CHANGE | XDF_IGNORE_WHITESPACE_AT_EOL) #define XDL_PATCH_NORMAL '-' @@@ -84,7 -85,6 +85,7 @@@ typedef long (*find_func_t)(const char typedef struct s_xdemitconf { long ctxlen; + long interhunkctxlen; unsigned long flags; find_func_t find_func; void *find_func_priv;