Открытие, где источник перешел от мерзавца

У меня есть репозиторий мерзавца (освещающий более или менее историю проекта) и отдельные источники (просто tarball с немногими файлами), которые разветвились некоторое время назад (на самом деле где-нибудь в 2004 или 2005).

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

Таким образом, то, что я в основном хочу, должно найти место в истории мерзавца, где код является самым подобным tarball источников, я имею. И я не хочу делать это вручную.

Также стоит упомянуть, что измененные источники включают только подмножество файлов и разделили некоторые файлы на больше. Однако код, который является там, кажется, получает только маленькие модификации и несколько дополнений.

Если Вы хотите играть с этим сами, tarball с источниками здесь, и Мерзавец размещается в Gitorious: git://gitorious.org/gammu/mainline.git

8
задан Mechanical snail 11 January 2013 в 19:23
поделиться

5 ответов

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

Вероятно, лучше всего будет ограничиться конкретными файлами. Если вы рассматриваете только один файл, то итерация по всем версиям этого файла не займет много времени (используйте git rev-list для получения списка, чтобы не проверять каждый коммит). Для каждого коммита, изменившего файл, вы можете проверить размер различия и довольно быстро найти минимум. Сделайте это для нескольких файлов, надеюсь, они согласятся!

Лучший способ подготовиться к сравнению - сделать временный коммит, просто скопировав свой tarball, чтобы у вас была ветвь с именем tarball для сравнения. Таким образом, вы можете сделать следующее:

git rev-list path/to/file | while read hash; do echo -n "$hash "; git diff --numstat tarball $hash path/to/file; done

чтобы получить хороший список всех коммитов с размерами различий (первые три колонки будут SHA1, количество добавленных строк и количество удалённых строк). Затем вы можете просто передать его в awk '{print $1,$2+$3}' | sort -n -k 2, и у вас будет отсортированный список коммитов и их diff размеров!

Если вы не можете ограничиться небольшой горсткой файлов для тестирования, я бы мог попробовать вручную реализовать что-то похожее на git-bisect - просто попытайтесь сузить свой путь до небольших различий, исходя из предположения, что, по всей вероятности, коммиты, близкие к вашему лучшему варианту, будут иметь меньшие различия, а коммиты, далёкие от него, будут иметь большие различия. (Где-то между методом Ньютона и полным бинарным/сеточным поиском, вероятно?)

Редактирование: Другая возможность, предложенная в ответе Дугласа, если вы думаете, что некоторые файлы могут быть идентичны тем, что в каком-то коммите, - это хэшировать их с помощью git-hash-object, а затем посмотреть, в каких коммитах в вашей истории есть этот блоб. Есть вопрос с отличными ответами о том, как это сделать. Если вы проделаете это с горсткой файлов - желательно часто изменяемых - вы сможете довольно быстро определить целевой коммит.

4
ответ дан 5 December 2019 в 21:16
поделиться

Не самое лучшее решение, но чтобы угадать, какие это могут быть ревизии: Предположим, что некоторые файлы в tar-архиве не были изменены с момента их разветвления. Запустите объект хэша git для каждого файла в tar-архиве, затем найдите эти файлы в репозитории, используя git show . Затем попробуйте найти коммиты, в которые были включены эти файлы, возможно, используя git whatchanged . Тогда ответом на ваш вопрос может быть фиксация с наиболее распространенными файлами, но это все равно будет немного случайным.

2
ответ дан 5 December 2019 в 21:16
поделиться

как был сделан форк? Это был клон, который сделал кто-то другой, а затем сделал свою собственную работу? если да, то это очень просто. все, что вам нужно сделать, это создать локальную ветку, которая берет код из форка. git увидит, что родословная форкнутой ветки указывает на один из коммитов из вашего оригинального хранилища и "соединит точки", так сказать... он соединит историю из вашего оригинального хранилища с форком.

у вас должно получиться:

git remote add thefork git://wherever.it.lives/thefork.git

git fetch thefork

git branch -f thefork-branch thefork/branchname

git checkout thefork-branch

в этот момент вы можете запустить gitk и посмотреть полную историю вилочной ветки и вашего локального репозитория, и увидеть, соединяются они или нет.

0
ответ дан 5 December 2019 в 21:16
поделиться

Импорт эти файлы из архива в ревизию git, в отдельную ветку или в совершенно новую ветку: позиция в графе ревизий не важна, мы просто хотим, чтобы она была доступна в виде дерева.

Теперь для каждой ревизии в мастере просто сравните с этим деревом / ревизией («импортированной») и просто выведите, насколько велико различие. Что-то вроде:

git rev-list master | while read rev; do patchsize=$(git diff $rev imported | wc -c); echo $rev $patchsize; done

Таким образом, ревизия с наименьшим размером патча будет «ближайшей» по очень грубому практическому правилу. (При идентичной ревизии размер патча будет равен 0, а все остальное обязательно будет отличным от нуля, и чем больше это будет изменено, тем больше).

0
ответ дан 5 December 2019 в 21:16
поделиться

основываясь на том, что сказал araqnid, я пришел к 9c6c864426bf88429e77c7e22b5aa78e9295b97a (просто попросил материал между 0.61. 0 и HEAD) это, вероятно, не лучший вариант) Вы можете сделать что-то вроде

git rev-list --no-merges --all | while read rev; do patchsize=$(git diff $rev | wc -c); echo $patchsize $rev; done | sort -n | less

если вы импортировали tarball в git и проверили эту ревизию (я сделал это с помощью untaring и затем

git init
git add .
git commit -m "import tarball"
git remote add origin git://gitorious.org/gammu/mainline.git

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

1
ответ дан 5 December 2019 в 21:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: