5

I'm writing a script to compare two directories recursively and run vimdiff when it finds a difference:

#!/bin/bash

dir1=${1%/}
dir2=${2%/}

find "$dir1/" -type f -not -path "$dir1/.git/*" | while IFS= read line; do
    file1="$line"
    file2=${line/$dir1/$dir2}

    isdiff=$(diff -q "$file1" "$file2")

    if [ -n "$isdiff" ]; then
        vimdiff "$file1" "$file2"
    fi
done

This doesn't work because vim throws a warning: "Input is not from a terminal." I understand that I need to supply the - argument, which is kind of tricky, but I have it more or less working:

#!/bin/bash

dir1=${1%/}
dir2=${2%/}

find "$dir1/" -type f -not -path "$dir1/.git/*" | while IFS= read line; do
    file1="$line"
    file2=${line/$dir1/$dir2}

    isdiff=$(diff -q "$file1" "$file2")

    if [ -n "$isdiff" ]; then
        cat "$file1" | vim - -c ":vnew $file2 | windo diffthis"
    fi
done

The problem with this is the right side of the diff window is a new file. I want to compare the original file in dir1 to the original file in dir2. How can I do this?

4 Answers 4

5

vim and therefore vimdiff seem to assume that stdin is an tty. You can workaround this by something like this in your script:

</dev/tty vimdiff "$file1" "$file2"
2

Try something like this:

#! /bin/sh

[ $# -eq 2 -a -d "$1" -a -d "$2" ] || exit 1

find "$1" -name .git -prune -o \( -type f -printf '%P\n' \) | \
    while IFS= read -r f; do
        if [ -f "$2/$f" ] && ! diff -q -- "$1/$f" "$2/$f" >/dev/null; then
            vimdiff -- "$1/$f" "$2/$f" </dev/tty
        fi
    done

The above assumes GNU find(1) (for the -printf action).

1

If you are running under X you can pull a couple different tricks. if you copy of vim is compiled with a gui adding -gf to vim may work for you. the g option enables the gui and the f option keeps it in the foreground. I have also been known to start vimdiff in its own xterm with xterm -e vimdiff "$@".

0

How about that:

vim -c ":e $file1 | vnew $file2 | windo diffthis"

It opens $file1 for edit, then the second file. Nothing to read from stdin, hence no unnamed file.

1
  • Doesn't work. It throws the same warning I mentioned in my question, then immediately exits: Vim: Warning: Input is not from a terminal Vim: Error reading input, exiting... Vim: Finished. Commented May 12, 2015 at 15:25

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .