Git: Как найти коммит, который наиболее точно соответствует каталогу?
Кто-то взял версию 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;
Были тысячи попыток перекопать, но этот кажется самым близким.
Ответы
Ответ 1
вы можете написать script, который отличает данное дерево от диапазона изменений в вашем репозитории.
Предположим, мы сначала извлекли измененное дерево (без истории) в наш собственный репозиторий:
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
Это было мое решение:
#!/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
Ответ 3
Как насчет использования git для создания патча из всех версий 1.8. и 1.9 к этой новой версии.
Затем вы можете увидеть, какой патч имеет больше смысла.
Например, если патч "удаляет" множество методов, то, вероятно, это не релиз, а первый. Если в патче есть много разделов, которые не имеют смысла как одно редактирование, то это, вероятно, и не релиз.
И так далее... На самом деле, к сожалению, алгоритма для этого не существует. Мне нужно быть эвристическим.
Ответ 4
Как насчет использования 'git wame'? Он покажет вам, для каждой строки, кто изменил ее и в какой версии.