Как с помощью GIT выборочно объединить изменения из одного коммита в другой «форк»?

Возьмем такой сценарий:

  1. Я решаю «разветвить» кодовую базу на github.com и приступаю к своей рутине: Edit - Commit - Push; он же hack hack hack.
  2. После того, как я внес некоторые изменения, я вижу некоторые изменения, внесенные другим человеком в тот же проект, и они мне нравятся!
  3. Я решаю, что хочу объединить их в свою. Проблема в том, что мне нужна только «часть» одной конкретной фиксации из нескольких сделанных им коммитов.

Какой был бы наиболее эффективный метод объединения этого избранного количества изменений в мою «вилку»?


person Tim    schedule 10.09.2009    source источник
comment
Возможный дубликат Как выборочно объединить или выбрать изменения из другой ветки в Git?   -  person Inigo    schedule 01.05.2018
comment
Возможный дубликат Частичный выбор фиксации с помощью Git   -  person Inigo    schedule 07.10.2018


Ответы (4)


После троллинга волн мира IRC кто-то дал отличное решение:

git cherry-pick SHA1 --no-commit
git add --patch

Надеюсь, это поможет кому-нибудь еще с тем же вопросом!

РЕДАКТИРОВАТЬ: Хорошо, может быть, это не так просто. Вот полные шаги:

  1. Сначала вы должны быть в своем репозитории, сделать необходимое cd-ing, чтобы попасть в ваш рабочий каталог.

  2. Теперь вам нужно добавить удаленную ветку, а затем получить ее. Сделайте это:

    git remote add someUser git://github.com/someUser/someRepo.git

    git fetch someUser

  3. Теперь вы можете запускать такие команды, как git log someUser/master, чтобы найти коммит SHA1, который вы хотите слить «частично».

  4. Когда у вас есть SHA, вы можете запускать:

    git cherry-pick -n SHA1

    где SHA1 - это SHA фиксации, да!

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

  6. Теперь вам нужно сбросить индекс до версии HEAD, затем вы можете использовать надежную команду GIT add --patch, чтобы выбрать, какие изменения вы хотите:

    git reset HEAD

    git add --patch or git add -p

  7. Ура! Время фиксации:

    git commit -m "I merged a select amount of changes"

  8. Чтобы навести порядок (то, что вы сказали «нет» в git add --patch) и сохранить только выбранные изменения в рабочем репозитории, запустите:

    git reset --hard HEAD

    Видимо git checkout -f - тоже вариант.

person Tim    schedule 10.09.2009
comment
Я рад, что вы нашли git add -p; это чрезвычайно мощно. Если у вас уже есть рассматриваемая фиксация (например, вы не использовали --no-commit для выбора вишни, или это одна из ваших фиксаций), вы можете использовать git reset HEAD^ для перемотки индекса и фиксации обратно, а затем добавить изменения обратно с помощью git add -p, совершение пошагово. Если фиксация находится не на кончике ветки, вы можете использовать git rebase -i и выбрать редактирование рассматриваемой фиксации. - person Cascabel; 10.09.2009
comment
хорошая прогулка. помните, если вам просто нужна вся фиксация, вы просто передаете -n на шаге 4. Вот так: git cherry-pick SHA1 - person Hulvej; 17.10.2014
comment
Ключевой бит здесь git remote add <user> <fork-url> - тогда вы можете git cherry-pick как обычно. - person Tom; 06.03.2015

Я не понимаю, чего вы хотите. Если вы хотите внести только определенные коммиты из других форков, вы можете использовать git cherry-pick SHA. Полное объяснение gitready.

person hgmnz    schedule 10.09.2009
comment
Я только после "части" / "раздела" / "нескольких строк" одного конкретного коммита, слитого в мой репозиторий. Не особо специфичный для файла. - person Tim; 10.09.2009
comment
В этом случае можно использовать git format-patch SHA, git apply ‹patch›. - person hgmnz; 10.09.2009

Мне очень нравится решение Тима, но иногда мне нравится возиться с vimdiff. Мое решение этой проблемы грубое, но оно работает для меня, потому что мне нравится vim.

У меня есть vimdiff, установленный в качестве моего инструмента для сравнения, а затем для выборочного слияния я различаю ветку:

git difftool <branch> <file>

Затем я перехожу на панель с версией текущей ветки и редактирую оригинал в vim (иногда в этом нет необходимости, но иногда vimdiff открывает версию в / tmp) и отключаю режим только для чтения:

:e <file>
:set readonly!

Теперь я могу использовать инструменты vim patch, такие как do и dp, чтобы применять то, что я хочу, и вносить другие небольшие правки по ходу. Когда я закончу, я сохраняю файл, выхожу из vim, а затем обрабатываю и фиксирую файл в git, как при обычном редактировании.

Как я уже сказал, это не особо сложно, но очень мощно и все еще чисто в командной строке. Просто не забудьте добавить четкое сообщение о фиксации, так как git не будет автоматически включать сообщение о слиянии для вас.

http://j.mp/1dZVllt

person Mike Dacre    schedule 18.01.2014
comment
Я не думаю, что этот ответ в полной мере заслуживает того, чтобы быть независимым полноценным ответом. Информация полезная, но не особо актуальная. (почему это вверху ответов?) - person Mike Kormendy; 13.07.2015

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

git cherry-pick SHA1
git checkout HEAD file1 file2 ... fileN

Конечно, если у вас есть несколько измененных частей в файле и вы хотите сохранить только некоторые из них, у вас нет другого выбора, кроме как редактировать файл вручную, вырезая их изменения.

person Bombe    schedule 10.09.2009
comment
Здесь нужна касса? Разве команда Cherry Pick не помещает изменения в ваш рабочий каталог? - person Casey Watson; 11.09.2010