X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=git-mergetool.sh;h=e62351bcbabc00a3d89ddf1c8dd936cea400501f;hb=27090aa1eabdc44553a0d8a51ff4ab9543c64c65;hp=52386a5443ac19f1d8cbf7dc32c1237b2665b861;hpb=36db2399e023c1526fac0b142524229554b88419;p=git.git diff --git a/git-mergetool.sh b/git-mergetool.sh index 52386a544..e62351bcb 100755 --- a/git-mergetool.sh +++ b/git-mergetool.sh @@ -14,19 +14,19 @@ SUBDIRECTORY_OK=Yes require_work_tree # Returns true if the mode reflects a symlink -function is_symlink () { +is_symlink () { test "$1" = 120000 } -function local_present () { +local_present () { test -n "$local_mode" } -function remote_present () { +remote_present () { test -n "$remote_mode" } -function base_present () { +base_present () { test -n "$base_mode" } @@ -39,32 +39,29 @@ cleanup_temp_files () { fi } -function describe_file () { +describe_file () { mode="$1" branch="$2" file="$3" - echo -n " " + printf " {%s}: " "$branch" if test -z "$mode"; then - echo -n "'$path' was deleted" + echo "deleted" elif is_symlink "$mode" ; then - echo -n "'$path' is a symlink containing '" - cat "$file" - echo -n "'" + echo "a symbolic link -> '$(cat "$file")'" else if base_present; then - echo -n "'$path' was created" + echo "modified" else - echo -n "'$path' was modified" + echo "created" fi fi - echo " in the $branch branch" } resolve_symlink_merge () { - while /bin/true; do - echo -n "Use (r)emote or (l)ocal, or (a)bort? " + while true; do + printf "Use (l)ocal or (r)emote, or (a)bort? " read ans case "$ans" in [lL]*) @@ -73,13 +70,13 @@ resolve_symlink_merge () { cleanup_temp_files --save-backup return ;; - [rR]*) + [rR]*) git-checkout-index -f --stage=3 -- "$path" git-add -- "$path" cleanup_temp_files --save-backup return ;; - [qQ]*) + [aA]*) exit 1 ;; esac @@ -87,38 +84,69 @@ resolve_symlink_merge () { } resolve_deleted_merge () { - while /bin/true; do - echo -n "Use (m)odified or (d)eleted file, or (a)bort? " + while true; do + if base_present; then + printf "Use (m)odified or (d)eleted file, or (a)bort? " + else + printf "Use (c)reated or (d)eleted file, or (a)bort? " + fi read ans case "$ans" in - [mM]*) + [mMcC]*) git-add -- "$path" cleanup_temp_files --save-backup return ;; - [dD]*) - git-rm -- "$path" + [dD]*) + git-rm -- "$path" > /dev/null cleanup_temp_files return ;; - [qQ]*) + [aA]*) exit 1 ;; esac done } -merge_file () { - path="$1" +check_unchanged () { + if test "$path" -nt "$BACKUP" ; then + status=0; + else + while true; do + echo "$path seems unchanged." + printf "Was the merge successful? [y/n] " + read answer < /dev/tty + case "$answer" in + y*|Y*) status=0; break ;; + n*|N*) status=1; break ;; + esac + done + fi +} - if test ! -f "$path" ; then - echo "$path: file not found" - exit 1 +save_backup () { + if test "$status" -eq 0; then + mv -- "$BACKUP" "$path.orig" fi +} + +remove_backup () { + if test "$status" -eq 0; then + rm "$BACKUP" + fi +} + +merge_file () { + path="$1" f=`git-ls-files -u -- "$path"` if test -z "$f" ; then - echo "$path: file does not need merging" + if test ! -f "$path" ; then + echo "$path: file not found" + else + echo "$path: file does not need merging" + fi exit 1 fi @@ -139,7 +167,7 @@ merge_file () { remote_present && git cat-file blob ":3:$path" > "$REMOTE" 2>/dev/null if test -z "$local_mode" -o -z "$remote_mode"; then - echo "Deleted merge conflict for $path:" + echo "Deleted merge conflict for '$path':" describe_file "$local_mode" "local" "$LOCAL" describe_file "$remote_mode" "remote" "$REMOTE" resolve_deleted_merge @@ -147,17 +175,17 @@ merge_file () { fi if is_symlink "$local_mode" || is_symlink "$remote_mode"; then - echo "Symlink merge conflict for $path:" + echo "Symbolic link merge conflict for '$path':" describe_file "$local_mode" "local" "$LOCAL" describe_file "$remote_mode" "remote" "$REMOTE" resolve_symlink_merge return fi - echo "Normal merge conflict for $path:" + echo "Normal merge conflict for '$path':" describe_file "$local_mode" "local" "$LOCAL" describe_file "$remote_mode" "remote" "$REMOTE" - echo -n "Hit return to start merge resolution tool ($merge_tool): " + printf "Hit return to start merge resolution tool (%s): " "$merge_tool" read ans case "$merge_tool" in @@ -170,9 +198,7 @@ merge_file () { -o "$path" -- "$LOCAL" "$REMOTE" > /dev/null 2>&1) fi status=$? - if test "$status" -eq 0; then - rm "$BACKUP" - fi + remove_backup ;; tkdiff) if base_present ; then @@ -181,29 +207,13 @@ merge_file () { tkdiff -o "$path" -- "$LOCAL" "$REMOTE" fi status=$? - if test "$status" -eq 0; then - mv -- "$BACKUP" "$path.orig" - fi + save_backup ;; - meld) + meld|vimdiff) touch "$BACKUP" - meld -- "$LOCAL" "$path" "$REMOTE" - if test "$path" -nt "$BACKUP" ; then - status=0; - else - while true; do - echo "$path seems unchanged." - echo -n "Was the merge successful? [y/n] " - read answer < /dev/tty - case "$answer" in - y*|Y*) status=0; break ;; - n*|N*) status=1; break ;; - esac - done - fi - if test "$status" -eq 0; then - mv -- "$BACKUP" "$path.orig" - fi + $merge_tool -- "$LOCAL" "$path" "$REMOTE" + check_unchanged + save_backup ;; xxdiff) touch "$BACKUP" @@ -220,22 +230,18 @@ merge_file () { -R 'Accel.SearchForward: "Ctrl-G"' \ --merged-file "$path" -- "$LOCAL" "$REMOTE" fi - if test "$path" -nt "$BACKUP" ; then - status=0; + check_unchanged + save_backup + ;; + opendiff) + touch "$BACKUP" + if base_present; then + opendiff "$LOCAL" "$REMOTE" -ancestor "$BASE" -merge "$path" | cat else - while true; do - echo "$path seems unchanged." - echo -n "Was the merge successful? [y/n] " - read answer < /dev/tty - case "$answer" in - y*|Y*) status=0; break ;; - n*|N*) status=1; break ;; - esac - done - fi - if test "$status" -eq 0; then - mv -- "$BACKUP" "$path.orig" + opendiff "$LOCAL" "$REMOTE" -merge "$path" | cat fi + check_unchanged + save_backup ;; emerge) if base_present ; then @@ -244,9 +250,7 @@ merge_file () { emacs -f emerge-files-command "$LOCAL" "$REMOTE" "$path" fi status=$? - if test "$status" -eq 0; then - mv -- "$BACKUP" "$path.orig" - fi + save_backup ;; esac if test "$status" -ne 0; then @@ -288,10 +292,15 @@ done if test -z "$merge_tool"; then merge_tool=`git-config merge.tool` - if test $merge_tool = kdiff3 -o $merge_tool = tkdiff -o \ - $merge_tool = xxdiff -o $merge_tool = meld ; then - unset merge_tool - fi + case "$merge_tool" in + kdiff3 | tkdiff | xxdiff | meld | opendiff | emerge | vimdiff | "") + ;; # happy + *) + echo >&2 "git config option merge.tool set to unknown tool: $merge_tool" + echo >&2 "Resetting to default..." + unset merge_tool + ;; + esac fi if test -z "$merge_tool" ; then @@ -303,8 +312,12 @@ if test -z "$merge_tool" ; then merge_tool=xxdiff elif type meld >/dev/null 2>&1 && test -n "$DISPLAY"; then merge_tool=meld + elif type opendiff >/dev/null 2>&1; then + merge_tool=opendiff elif type emacs >/dev/null 2>&1; then merge_tool=emerge + elif type vimdiff >/dev/null 2>&1; then + merge_tool=vimdiff else echo "No available merge resolution programs available." exit 1 @@ -312,7 +325,7 @@ if test -z "$merge_tool" ; then fi case "$merge_tool" in - kdiff3|tkdiff|meld|xxdiff) + kdiff3|tkdiff|meld|xxdiff|vimdiff|opendiff) if ! type "$merge_tool" > /dev/null 2>&1; then echo "The merge tool $merge_tool is not available" exit 1 @@ -339,12 +352,12 @@ if test $# -eq 0 ; then echo Merging the files: $files git ls-files -u | sed -e 's/^[^ ]* //' | sort -u | while read i do - echo "" + printf "\n" merge_file "$i" < /dev/tty > /dev/tty done else while test $# -gt 0; do - echo "" + printf "\n" merge_file "$1" shift done