Используя GIT, как я могу выборочно вытащить/слить изменения из другой "вилки"?

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

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

Каким будет наиболее эффективный метод получения этих избранных изменений, объединенных в мою "вилку"?

Ответ 1

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

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

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

EDIT: Хорошо, может быть, это не так просто. Вот полные шаги:

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

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

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

    git fetch someUser

  • Теперь вы можете запускать команды, такие как git log someUser/master, чтобы найти фиксацию SHA1, которую вы хотите объединить "частично".

  • Как только у вас есть SHA, вы можете запустить:

    git cherry-pick -n SHA1

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

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

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

    git reset HEAD

    git add --patch или git add -p

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

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

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

    git reset --hard HEAD

    По-видимому, git checkout -f - еще один вариант.

Ответ 2

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

Ответ 3

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

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

git difftool <branch> <file>

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

:e <file>
:set readonly!

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

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

Пример vimdiff http://j.mp/1dZVllt

Ответ 4

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

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

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