Используя 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
Конечно, если у вас несколько модифицированных частей в файле и вы хотите сохранить некоторые из них, у вас нет выбора, кроме как отредактировать файл вручную, отрезав их изменения.