Git: Как я могу найти коммит, который наиболее близко соответствует каталогу? - PullRequest
39 голосов
/ 17 июня 2011

Кто-то взял неизвестную мне версию Moodle, применил много изменений в каталоге и выпустил ее ( дерево здесь ).

Как определить, какой коммит исходного проекта наиболее вероятно был отредактирован для формирования этого дерева?

это позволило бы мне сформировать ветку при соответствующем коммите с этим патчем. Конечно, это произошло из веток 1.8 или 1.9 , возможно, из тега релиза, но различие между конкретными коммитами мне мало помогает.

Посмертное обновление: ответ Knittl подобрал меня настолько близко, насколько я собираюсь получить. Сначала я добавил свой патч-репо в качестве удаленного «чужого» (никаких общих коммитов, это нормально), затем сделал различий в циклах с парой опций формата. Первый использовал формат --shortstat:

for REV in $(git rev-list v1.9.0^..v1.9.5); do 
    git diff --shortstat "$REV" f7f7ad53c8839b8ea4e7 -- mod/assignment >> ~/rdiffs.txt; 
    echo "$REV" >> ~/rdiffs.txt; 
done;

Второй просто посчитал изменения строки в унифицированном diff без контекста:

for REV in $(git rev-list v1.9.0^..v1.9.5); do 
    git diff -U0 "$REV" f7f7ad53c8839b8ea4e7 -- mod/assignment | wc -l >> ~/rdiffs2.txt;
    echo "$REV" >> ~/rdiffs2.txt; 
done;

Было прорвано тысячи коммитов, но этот , кажется, самый близкий.

Ответы [ 4 ]

12 голосов
/ 17 июня 2011

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

предположим, что мы сначала извлекаем измененное дерево (без истории) в наш собственный репозиторий:

git remote add foreign git://…
git fetch foreign

затем мы выводим diffstat (в краткой форме) для каждой ревизии, с которой мы хотим сопоставить:

for REV in $(git rev-list 1.8^..1.9); do
   git diff --shortstat foreign/master $REV;
done

искать коммит с наименьшим количеством изменений (или использовать какой-то механизм сортировки)

2 голосов
/ 01 мая 2014

Это было мое решение:

#!/bin/sh

start_date="2012-03-01"
end_date="2012-06-01"
needle_ref="aaa"

echo "" > /tmp/script.out;
shas=$(git log --oneline --all --after="$start_date" --until="$end_date" | cut -d' ' -f 1)
for sha in $shas
do
    wc=$(git diff --name-only "$needle_ref" "$sha" | wc -l)
    wc=$(printf %04d $wc);
    echo "$wc $sha" >> /tmp/script.out
done
cat /tmp/script.out | grep -v ^$ | sort | head -5
0 голосов
/ 17 июня 2011

Как насчет использования git для создания патча из всех версий 1.8. и 1.9 к этому новому выпуску. Тогда вы сможете увидеть, какой патч имеет больше смысла.

Например, если патч «удаляет» много методов, то, вероятно, это не этот выпуск, а один из предыдущих. Если в патче много разделов, которые не имеют смысла как единичное редактирование, то, вероятно, это тоже не этот выпуск.

И так далее. В действительности, к сожалению, не существует алгоритма, который бы делал это идеально. Я должен быть немного эвристическим.

0 голосов
/ 17 июня 2011

Как насчет использования 'git blame'?Для каждой строки будет показано, кто ее изменил и в какой ревизии.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...