diff options
Diffstat (limited to 'contrib')
-rwxr-xr-x | contrib/completion/git-completion.bash | 26 | ||||
-rwxr-xr-x | contrib/difftool/git-difftool-helper | 41 | ||||
-rw-r--r-- | contrib/difftool/git-difftool.txt | 3 | ||||
-rwxr-xr-x | contrib/git-resurrect.sh | 180 |
4 files changed, 225 insertions, 25 deletions
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 81f70ec644..307bf5d4f9 100755 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -34,6 +34,12 @@ # are currently in a git repository. The %s token will be # the name of the current branch. # +# In addition, if you set GIT_PS1_SHOWDIRTYSTATE to a nonempty +# value, unstaged (*) and staged (+) changes will be shown next +# to the branch name. You can configure this per-repository +# with the bash.showDirtyState variable, which defaults to true +# once GIT_PS1_SHOWDIRTYSTATE is enabled. +# # To submit patches: # # *) Read Documentation/SubmittingPatches @@ -116,10 +122,26 @@ __git_ps1 () fi fi + local w + local i + + if test -n "$GIT_PS1_SHOWDIRTYSTATE"; then + if test "$(git config --bool bash.showDirtyState)" != "false"; then + git diff --no-ext-diff --ignore-submodules \ + --quiet --exit-code || w="*" + if git rev-parse --quiet --verify HEAD >/dev/null; then + git diff-index --cached --quiet \ + --ignore-submodules HEAD -- || i="+" + else + i="#" + fi + fi + fi + if [ -n "${1-}" ]; then - printf "$1" "${b##refs/heads/}$r" + printf "$1" "${b##refs/heads/}$w$i$r" else - printf " (%s)" "${b##refs/heads/}$r" + printf " (%s)" "${b##refs/heads/}$w$i$r" fi fi } diff --git a/contrib/difftool/git-difftool-helper b/contrib/difftool/git-difftool-helper index 0c48506eeb..db3af6a833 100755 --- a/contrib/difftool/git-difftool-helper +++ b/contrib/difftool/git-difftool-helper @@ -1,7 +1,7 @@ #!/bin/sh # git-difftool-helper is a GIT_EXTERNAL_DIFF-compatible diff tool launcher. -# It supports kdiff3, tkdiff, xxdiff, meld, opendiff, emerge, ecmerge, -# vimdiff, gvimdiff, and custom user-configurable tools. +# It supports kdiff3, kompare, tkdiff, xxdiff, meld, opendiff, +# emerge, ecmerge, vimdiff, gvimdiff, and custom user-configurable tools. # This script is typically launched by using the 'git difftool' # convenience command. # @@ -73,6 +73,10 @@ launch_merge_tool () { > /dev/null 2>&1 ;; + kompare) + "$merge_tool_path" "$LOCAL" "$REMOTE" + ;; + tkdiff) "$merge_tool_path" -o "$MERGED" "$LOCAL" "$REMOTE" ;; @@ -134,7 +138,7 @@ valid_custom_tool() { # Built-in merge tools are always valid. valid_tool() { case "$1" in - kdiff3 | tkdiff | xxdiff | meld | opendiff | emerge | vimdiff | gvimdiff | ecmerge) + kdiff3 | kompare | tkdiff | xxdiff | meld | opendiff | emerge | vimdiff | gvimdiff | ecmerge) ;; # happy *) if ! valid_custom_tool "$1" @@ -177,31 +181,24 @@ fi # Try to guess an appropriate merge tool if no tool has been set. if test -z "$merge_tool"; then - # We have a $DISPLAY so try some common UNIX merge tools if test -n "$DISPLAY"; then - merge_tool_candidates="kdiff3 tkdiff xxdiff meld gvimdiff" - # If gnome then prefer meld - if test -n "$GNOME_DESKTOP_SESSION_ID"; then - merge_tool_candidates="meld $merge_tool_candidates" - fi - # If KDE then prefer kdiff3 - if test "$KDE_FULL_SESSION" = "true"; then - merge_tool_candidates="kdiff3 $merge_tool_candidates" + # If gnome then prefer meld, otherwise, prefer kdiff3 or kompare + if test -n "$GNOME_DESKTOP_SESSION_ID" ; then + merge_tool_candidates="meld kdiff3 kompare tkdiff xxdiff gvimdiff" + else + merge_tool_candidates="kdiff3 kompare tkdiff xxdiff meld gvimdiff" fi fi - - # $EDITOR is emacs so add emerge as a candidate if echo "${VISUAL:-$EDITOR}" | grep 'emacs' > /dev/null 2>&1; then - merge_tool_candidates="$merge_tool_candidates emerge" + # $EDITOR is emacs so add emerge as a candidate + merge_tool_candidates="$merge_tool_candidates emerge opendiff vimdiff" + elif echo "${VISUAL:-$EDITOR}" | grep 'vim' > /dev/null 2>&1; then + # $EDITOR is vim so add vimdiff as a candidate + merge_tool_candidates="$merge_tool_candidates vimdiff opendiff emerge" + else + merge_tool_candidates="$merge_tool_candidates opendiff emerge vimdiff" fi - - # $EDITOR is vim so add vimdiff as a candidate - if echo "${VISUAL:-$EDITOR}" | grep 'vim' > /dev/null 2>&1; then - merge_tool_candidates="$merge_tool_candidates vimdiff" - fi - - merge_tool_candidates="$merge_tool_candidates opendiff emerge vimdiff" echo "merge tool candidates: $merge_tool_candidates" # Loop over each candidate and stop when a valid merge tool is found. diff --git a/contrib/difftool/git-difftool.txt b/contrib/difftool/git-difftool.txt index ca3dbd2465..6e2610cda6 100644 --- a/contrib/difftool/git-difftool.txt +++ b/contrib/difftool/git-difftool.txt @@ -28,7 +28,8 @@ OPTIONS --tool=<tool>:: Use the merge resolution program specified by <tool>. Valid merge tools are: - kdiff3, tkdiff, meld, xxdiff, emerge, vimdiff, gvimdiff, ecmerge, and opendiff + kdiff3, kompare, tkdiff, meld, xxdiff, emerge, + vimdiff, gvimdiff, ecmerge, and opendiff + If a merge resolution program is not specified, 'git-difftool' will use the configuration variable `merge.tool`. If the diff --git a/contrib/git-resurrect.sh b/contrib/git-resurrect.sh new file mode 100755 index 0000000000..c364dda696 --- /dev/null +++ b/contrib/git-resurrect.sh @@ -0,0 +1,180 @@ +#!/bin/sh + +USAGE="[-a] [-r] [-m] [-t] [-n] [-b <newname>] <name>" +LONG_USAGE="git-resurrect attempts to find traces of a branch tip +called <name>, and tries to resurrect it. Currently, the reflog is +searched for checkout messages, and with -r also merge messages. With +-m and -t, the history of all refs is scanned for Merge <name> into +other/Merge <other> into <name> (respectively) commit subjects, which +is rather slow but allows you to resurrect other people's topic +branches." + +OPTIONS_SPEC="\ +git resurrect $USAGE +-- +b,branch= save branch as <newname> instead of <name> +a,all same as -l -r -m -t +k,keep-going full rev-list scan (instead of first match) +l,reflog scan reflog for checkouts (enabled by default) +r,reflog-merges scan for merges recorded in reflog +m,merges scan for merges into other branches (slow) +t,merge-targets scan for merges of other branches into <name> +n,dry-run don't recreate the branch" + +. git-sh-setup + +search_reflog () { + sed -ne 's~^\([^ ]*\) .*\tcheckout: moving from '"$1"' .*~\1~p' \ + < "$GIT_DIR"/logs/HEAD +} + +search_reflog_merges () { + git rev-parse $( + sed -ne 's~^[^ ]* \([^ ]*\) .*\tmerge '"$1"':.*~\1^2~p' \ + < "$GIT_DIR"/logs/HEAD + ) +} + +_x40="[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]" +_x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40" + +search_merges () { + git rev-list --all --grep="Merge branch '$1'" \ + --pretty=tformat:"%P %s" | + sed -ne "/^$_x40 \($_x40\) Merge .*/ {s//\1/p;$early_exit}" +} + +search_merge_targets () { + git rev-list --all --grep="Merge branch '[^']*' into $branch\$" \ + --pretty=tformat:"%H %s" --all | + sed -ne "/^\($_x40\) Merge .*/ {s//\1/p;$early_exit} " +} + +dry_run= +early_exit=q +scan_reflog=t +scan_reflog_merges= +scan_merges= +scan_merge_targets= +new_name= + +while test "$#" != 0; do + case "$1" in + -b|--branch) + shift + new_name="$1" + ;; + -n|--dry-run) + dry_run=t + ;; + --no-dry-run) + dry_run= + ;; + -k|--keep-going) + early_exit= + ;; + --no-keep-going) + early_exit=q + ;; + -m|--merges) + scan_merges=t + ;; + --no-merges) + scan_merges= + ;; + -l|--reflog) + scan_reflog=t + ;; + --no-reflog) + scan_reflog= + ;; + -r|--reflog_merges) + scan_reflog_merges=t + ;; + --no-reflog_merges) + scan_reflog_merges= + ;; + -t|--merge-targets) + scan_merge_targets=t + ;; + --no-merge-targets) + scan_merge_targets= + ;; + -a|--all) + scan_reflog=t + scan_reflog_merges=t + scan_merges=t + scan_merge_targets=t + ;; + --) + shift + break + ;; + *) + usage + ;; + esac + shift +done + +test "$#" = 1 || usage + +all_strategies="$scan_reflog$scan_reflog_merges$scan_merges$scan_merge_targets" +if test -z "$all_strategies"; then + die "must enable at least one of -lrmt" +fi + +branch="$1" +test -z "$new_name" && new_name="$branch" + +if test ! -z "$scan_reflog"; then + if test -r "$GIT_DIR"/logs/HEAD; then + candidates="$(search_reflog $branch)" + else + die 'reflog scanning requested, but' \ + '$GIT_DIR/logs/HEAD not readable' + fi +fi +if test ! -z "$scan_reflog_merges"; then + if test -r "$GIT_DIR"/logs/HEAD; then + candidates="$candidates $(search_reflog_merges $branch)" + else + die 'reflog scanning requested, but' \ + '$GIT_DIR/logs/HEAD not readable' + fi +fi +if test ! -z "$scan_merges"; then + candidates="$candidates $(search_merges $branch)" +fi +if test ! -z "$scan_merge_targets"; then + candidates="$candidates $(search_merge_targets $branch)" +fi + +candidates="$(git rev-parse $candidates | sort -u)" + +if test -z "$candidates"; then + hint= + test "z$all_strategies" != "ztttt" \ + && hint=" (maybe try again with -a)" + die "no candidates for $branch found$hint" +fi + +echo "** Candidates for $branch **" +for cmt in $candidates; do + git --no-pager log --pretty=tformat:"%ct:%h [%cr] %s" --abbrev-commit -1 $cmt +done \ +| sort -n | cut -d: -f2- + +newest="$(git rev-list -1 $candidates)" +if test ! -z "$dry_run"; then + printf "** Most recent: " + git --no-pager log -1 --pretty=tformat:"%h %s" $newest +elif ! git rev-parse --verify --quiet $new_name >/dev/null; then + printf "** Restoring $new_name to " + git --no-pager log -1 --pretty=tformat:"%h %s" $newest + git branch $new_name $newest +else + printf "Most recent: " + git --no-pager log -1 --pretty=tformat:"%h %s" $newest + echo "** $new_name already exists, doing nothing" +fi |