2013-12-17 5 views
1

Рассмотрите задачу поиска того, что изменилось в двух проектах, которые были разветвлены.Рекурсивный каталог-diff, принимающий внешний diff

diff -r меня закрыл: он способен находить, какие файлы отсутствуют в каждой целевой папке, и указывает файлы, которые были изменены путем представления их различий.

Я хочу использовать специальную утилиту diff. Я бы не хотел реализовывать в моей утилите diff рекурсивную логику хоста логики.

Итак, я просто хочу программу, которая делает то, что делает diff -r, но которая на самом деле не идет вперед и не запускает diff.

Существует ли такая вещь?

+0

Ваш вопрос не совсем ясен, но вы ищете опцию '-q' для' diff'? – devnull

+2

@devnull, как выясняется, да! –

ответ

0

Я думаю, что это более элегантно:

diff -rq dir1 dir2 | sed -ne 's/^Files \(.*\) and \(.*\) differ$/\1\n\2/p' | xargs -n 2 sift 

Основной трюк использует -q флаг, который будет печатать различия в кратком формате, например:

Files dir1/x and dir2/x differ 
Only in dir1: path/to/file 
Only in dir2: path/to/another 

И затем, как вы разбираете выход - ваш вопрос вкуса.

Наконец, чтобы правильно обрабатывать пробелы в именах файлов:

diff -rq dir1 dir2 | sed -ne 's/^Files \(.*\) and \(.*\) differ$/sift "\1" "\2"/p' | sh 

Это, вероятно, имеет смысл, чтобы обернуть это в функции:

xdiff() { 
    diff=$1; shift 
    dir1=$1; shift 
    dir2=$1; shift 
    diff -rq $dir1 $dir2 | sed -ne 's/^Files \(.*\) and \(.*\) differ$/'$diff' "\1" "\2"/p' | sh 
} 

Таким образом, вы можете назвать это так:

xdiff sift dir1 dir2 
+1

Ничего особенного, теперь 'diff' отличается не впустую. Также более сильное сито regex для менее ложноположительных ошибочных совпадений –

+0

Что такое 'p' flag для sed' s // '? –

+0

Это не флаг, это команда: «print». Если выполняется замещение, строка будет напечатана. Из-за '-n' в' sed -ne '...' 'по умолчанию ничего не печатается. Для строк, которые не соответствуют шаблону, замена не будет, и они не будут напечатаны. – janos

1

Я понял, что выход diff -r уже достаточно структурирован для меня, чтобы «стать умным» с ним. Вот суть этого.

diff -r proj1/src proj2/src | grep 'diff -r' | cut -d ' ' -f 3,4 | xargs -n 2 sift 

где sift моя маленькая из командной строки символ на основе различий Util, которая работает круги вокруг дифф выхода diff «s.

и используя diff (GNU diffutils) 2.8.1

Я открыт для более элегантные решения, как хорошо!

Редактировать: Спасибо @janos, -q вариант делает его довольно оптимальным!

Последнее, что нужно сделать, это сделать достаточно мощным, проложив трубопровод в программу opendiff в командной строке Mac (указав соответствующий файл в желаемом каталоге в качестве цели, который, конечно, уже находится внутри репозитория Git, правильно?) сделать ручное слияние красивым и быстрым.

Фактически установка opendiff, которая будет использоваться Git, когда потребуется человеческое слияние, - это, вероятно, путь.

Просто я не столкнулся с очень большим количеством конфликтных ситуаций слияния в одном и том же кодовом репо, в основном, когда forking repos (и имеет отдельные репозитории для разных проектов, содержащих общий код), что мне нужно сделать такой вид объединить, чтобы вручную обновить мои «первичные» проекты с изменениями, внесенными в траншеи.

+1

Вы спросили и ответили на это, чтобы получить шляпу, не я ;-) – janos

+0

Ха, нет, я сделал свой типичный «вопрос типа и пришел к ответу». –

Смежные вопросы