git cherry-pick различие между коммитами без общей истории?

Сценарий: хранилище с полностью отключенными фрагментами истории. Например. с разных пультов, у которых нет общей истории git. (Обычно это происходит в сценариях с поддеревом git.)

Можно ли выделить разницу между этими двумя коммитами, даже если у них нет общей истории? (И активная фиксация не имеет общей истории ни с одним из этих двух)

Я пробовал это (в подкаталог с опцией -X subtree=sub/dir):

git cherry-pick -X subtree=vendor/package aaa/aaa..bbb/bbb

Без поддерева это было бы проще:

git cherry-pick aaa/aaa..bbb/bbb

Где aaa / aaa и bbb / bbb - это два коммита с отключенной историей.

К сожалению, это не работает: aaa / aaa..bbb / bbb читается не как diff, а как что-то еще.

То же самое можно показать с git show aaa/aaa..bbb/bbb, который сильно отличается от git diff aaa/aaa bbb/bbb. Например. если у обоих одинаковые файлы, то git diff будет пустым, но git show a..b покажет только b, но не a.


Примечание. Мой личный вариант использования связан с фоном поддерева. Я упоминаю об этом, чтобы избежать искусственного варианта использования, когда люди обычно начинают обсуждать обоснованность варианта использования вместо фактического вопроса.

Идеальный ответ сначала обращается к общему случаю, а затем к случаю поддерева.


person donquixote    schedule 01.02.2016    source источник


Ответы (2)


@VonC указывает в правильном направлении. Кредит и +1 за эту идею.

было бы проще создать патч и применить его:

Однако это можно сделать с помощью простого однострочника (я пробовал это, и у меня это работает):

git diff aaa/aaa bbb/bbb | git apply --directory=vendor/package

Или в сценарии без поддерева:

git diff aaa/aaa bbb/bbb | git apply

Нет необходимости в git checkout, git cherry-pick или создании локального файла.
Тогда вам все равно нужно будет зафиксировать этот материал, очевидно ..

И вот как это сделать без добавления и / или извлечения каких-либо удаленных поддеревьев. Вместо этого вы можете клонировать репозитории пакетов в отдельные каталоги вне основного репозитория проекта.

git --git-dir="/path/to/package/repo/.git" diff aaa bbb | git apply --directory=vendor/package

Насколько я понимаю, это все еще в основном эквивалентно обычному git subtree рабочему процессу. Я имею в виду, что git-история основного проекта будет такой же. Поправьте меня если я ошибаюсь.

person donquixote    schedule 01.02.2016
comment
Конечно, git diff, вероятно, более прост (я колебался между diff и cherry-pick). +1 - person VonC; 01.02.2016

Поскольку выбор вишни применяет diff, было бы проще создать патч и применить его:

git checkout aaa/aaa
git cherry-pick -n bbb/bbb
git diff --cached > my.patch

Затем проверьте свой обычный филиал и git apply my.patch

Это берет фиксацию «bbb/bbb», сравнивает его с его непосредственным предком, а затем применяет это различие к «aaa/aaa»: могут ожидаться конфликты.
Проверить, помогает ли -X subtree=vendor/package в случае поддерева.

person VonC    schedule 01.02.2016
comment
git apply - хорошая идея! Но я не уверен, что ваши команды выполняют обещанное. - person donquixote; 01.02.2016
comment
Проблема, которую я вижу с вишневым выбором, заключается в том, что он выбирает только последний коммит, а не весь диапазон коммитов, ведущих от aaa / aaa до bbb / bbb (которого на самом деле не существует - в этом суть). - person donquixote; 01.02.2016