Частично вишневый коммит с Git
Я работаю над двумя разными ветками: релиз и разработка.
Я заметил, что мне все еще нужно интегрировать некоторые изменения, внесенные в ветку release, обратно в ветку development.
Проблема в том, что мне не нужны все коммиты, только некоторые фрагменты в определенных файлах, поэтому простой
git cherry-pick bc66559
не делает трюк.
Когда я делаю
git show bc66559
Я могу видеть разницу, но не знаю, как правильно применить ее частично к моему текущему рабочему дереву.
Ответы
Ответ 1
Основное, что вам нужно, это git add -p
(-p
является синонимом --patch
). Это обеспечивает интерактивный способ проверки содержимого, позволяя вам решить, должен ли идти каждый хоккей, и даже позволить вам вручную отредактировать патч, если это необходимо.
Чтобы использовать его в сочетании с вишневым выбором:
git cherry-pick -n <commit> # get your patch, but don't commit (-n = --no-commit)
git reset # unstage the changes from the cherry-picked commit
git add -p # make all your choices (add the changes you do want)
git commit # make the commit!
(Спасибо Тиму Хенигану за то, что он напомнил мне, что git -cherry-pick имеет опцию -no-commit, и благодаря Феликс Рабе за то, что вам нужно reset! Если вы хотите просто уйти несколько вещей из коммита, вы можете использовать git reset <path>...
для того, чтобы просто отключить эти файлы.)
Вы можете, конечно, указать конкретные пути к add -p
, если это необходимо. Если вы начинаете с патча, вы можете заменить cherry-pick
на apply
.
Если вы действительно хотите git cherry-pick -p <commit>
(этот параметр не существует), вы можете использовать
git checkout -p <commit>
Это будет отличать текущую фиксацию от комманды, которую вы укажете, и разрешить вам применять ханки из этой разницы по отдельности. Этот параметр может быть более полезен, если у фиксации, которую вы пытаетесь найти, есть конфликты слияния в части коммита, который вам неинтересен. (Обратите внимание, однако, что checkout
отличается от cherry-pick
: checkout
пытается применить <commit>
содержимое полностью, cherry-pick
применяет diff от указанной фиксации от родителя. Это означает, что checkout
может применять больше, чем только это commit, что может быть больше, чем вы хотите.)
Ответ 2
Я знаю, что отвечаю на старый вопрос, но похоже, что есть новый способ сделать это с интерактивной проверкой:
git checkout -p bc66559
Кредит Могу ли я интерактивно выбирать ханки из другого git commit?
Ответ 3
Предполагая, что изменения, которые вы хотите, находятся во главе ветки, из которой вы хотите внести изменения, используйте git checkout
для одного файла:
git checkout branch_that_has_the_changes_you_want path/to/file.rb
для нескольких файлов только цепочка:
git checkout branch_that_has_the_changes_you_want path/to/file.rb path/to/other_file.rb
Ответ 4
На основе Mike Monkiewicz ответьте, что вы также можете указать один или несколько файлов для проверки из поставляемого sha1/branch.
git checkout -p bc66559 -- path/to/file.java
Это позволит вам интерактивно выбирать изменения, которые вы хотите применить к текущей версии файла.
Ответ 5
Если вы хотите указать список файлов в командной строке и выполнить все это одной атомарной командой, попробуйте:
git apply --3way <(git show -- list-of-files)
--3way
: Если патч не применяется корректно, Git создаст конфликт слияния, чтобы вы могли запустить git mergetool
. Пропуск --3way
заставит Git отказаться от патчей, которые не применяются чисто.
Ответ 6
Если "частично вишня" означает "в файлах, выбирая некоторые изменения, но отбрасывая другие", это можно сделать, введя git stash
:
- Сделайте полный выбор вишни.
git reset HEAD^
, чтобы преобразовать весь выбранный вишневый коммит в неустановленные рабочие изменения.
- Теперь
git stash save --patch
: интерактивно выбирайте нежелательный материал для хранения.
- Git откатывает спрятанные изменения из вашей рабочей копии.
git commit
- Выбросьте stash нежелательных изменений:
git stash drop
.
Подсказка: если вы дадите имя stashу нежелательных изменений: git stash save --patch junk
, то если вы забудете выполнить (6) сейчас, позже вы узнаете, что это за stash.