Нет способа добавить коммит в альтернативную ветку с git commit .Существуют способы использования низкоуровневых «слесарных» команд для выполнения именно того, что вы описали, но интерфейс, созданный этими командами, не предназначен для интерактивного использования 1 .Конечно, есть способы делать то, что вы хотите;в зависимости от деталей ваших изменений и содержимого участвующих веток это может быть довольно просто.
Простой случай: просто используйте git checkout
При переключении веток git checkout сохранит незафиксированные изменения или откажется переключаться (если вы не используете --force
, --merge
или --conflict
).Таким образом, до тех пор, пока ваши незафиксированные изменения касаются только тех файлов, которые одинаковы как в HEAD (текущая ветка), так и в вашей ветке назначения, git checkout оставит эти изменения в индексе и / или рабочем дереве, покапереключение веток.Если ваши неподтвержденные изменения удовлетворяют этому условию, вы можете сделать следующее:
git checkout safe-branch
git add -- files-with-safe-changes
git commit
git checkout -
Вы также можете использовать git add --patch
для подготовки и фиксации только некоторых изменений в файлах.
После этого ваши «безопасные изменения» станут частью «безопасной ветки»;переключение обратно на исходную ветку «оставит их позади» (помните, git checkout сохраняет только незафиксированные изменения при переключении ветвей).
Если ваши другие изменения зависят от «безопасных изменений», которые выможет потребоваться объединить «безопасную ветвь» с вашей рабочей ветвью (или, в зависимости от вашего рабочего процесса, переназначить вашу рабочую ветку на новую подсказку «безопасной ветки»).Для этого вам нужно будет спрятать ваши незафиксированные изменения (так как слияние и перебазирование откажутся работать, если есть незафиксированные изменения).
git stash save
git merge safe-branch
git stash pop --index
Если ваши другие изменения не зависят от «безопасных изменений»тогда вам, вероятно, не стоит беспокоиться о слиянии или перебазировании.В конце концов вы объедините эти ветви вместе (например, объединяя их обе в ветку 'qa' для предварительного тестирования), но нет причин преждевременно объединять их.
Все еще легко, но немного рискованно:git checkout -m
Если первая git checkout жалуется «У вас есть локальные изменения на some‑file
;не переключать ветки. », это означает, что вы внесли несоответствующие изменения в some-file
и что файл отличается от подсказок« безопасной ветки »и вашей текущей ветки;вам понадобится другой подход.
Если вы уверены, что изменения будут справедливо применяться к версии some‑file
, находящейся в «безопасной ветке», тогда вы можете использовать -m
/ --merge
возможность указать git checkout , чтобы попытаться адаптировать изменения, чтобы они применялись к файлам в «безопасной ветке».Если слияние не может быть выполнено без ошибок, то в конечном итоге вы столкнетесь с конфликтом слияний, и вам может быть трудно восстановить ваши первоначальные изменения (вот почему я называю это «рискованным»).
Безопасный: git stash
+ git checkout -m
Поскольку вы действительно хотите переместить подмножество изменений обратно в «безопасную ветвь», возможно, лучше сосредоточиться только на этих изменениях.Один из способов - использовать git stash для временного сохранения текущих изменений, чтобы вам не приходилось перетаскивать их все обратно в «безопасную ветвь» (а затем перетаскивать некоторые / большинство из них обратно на работу.филиал).
git stash save
git checkout stash -- files-with-save-changes
git checkout -m safe-branch
git commit
git checkout -
git stash pop --index
Возможны другие варианты.Вы можете использовать git checkout -p stash -- files
, чтобы выделить только некоторые изменения в этих файлах.Если в индексе нет поэтапных изменений, то вы могли бы сначала выполнить «безопасные изменения», git add -- files
(снова, необязательно с -p
), использовать git stash save --keep-index
, переключать ветви (с объединением), а затем фиксировать (т.е. замените git checkout stash -- files
на предварительно подготовленные «безопасные изменения» и git stash --keep-index
).
В этой ситуации я считаю git checkout -m
безопасным, потому что мы использовали git stash сохранить копию текущих изменений; если трехсторонняя попытка слияния приводит к безнадежному беспорядку, то вы можете легко отказаться от идеи поместить «безопасные изменения» в «безопасную ветвь» и вернуться к работе: переключитесь на исходную ветвь и вытолкните тайник ( git checkout -f - && git stash pop
).
Опять же, если ваши другие изменения зависят от «безопасных изменений», вам потребуется слить или перебазировать. С тем же успехом вы можете сделать это перед извлечением тайника (поскольку для слияния / перебазирования вам нужен чистый индекс и рабочее дерево).
Если вы не собираетесь объединять вашу рабочую ветку с (или перебазировать ее) с «безопасной веткой» сразу, то вы, вероятно, захотите отменить «безопасные изменения» после того, как вы вытолкнули тайник («безопасный»). изменения »были сохранены в исходном хранилище, и вы, вероятно, не захотите получить коммиты, которые делают одинаковые изменения с нуля в двух разных ветках 2 ). После того, как вы открыли тайник, используйте git checkout -- files-with-safe-changes
, чтобы вернуть эти файлы обратно к версиям в конце рабочей ветви.
1
Интерфейс «сантехника» предназначен для использования в скриптах. Было бы неудобно использовать их непосредственно в командной строке. Ранние версии git commit (и большинство других команд Git) были сценариями оболочки, основанными на этом интерфейсе. Они все еще могут быть написаны как сценарии оболочки сегодня, но версии C, как правило, намного быстрее.
Шаги, необходимые для фиксации в альтернативной ветви:
установить альтернативный индекс на основе дерева в кончике «безопасной ветви»,
обновить индекс «безопасными» изменениями (что, если изменения не могут быть применены корректно? было бы хорошо иметь рабочее дерево, позволяющее пользователю разрешать конфликты),
записать индекс в виде объекта дерева,
создайте новый объект фиксации, который указывает на новое дерево и в качестве родителя которого используется текущий совет «safe branch»,
обновите ссылку «безопасная ветка», чтобы она указала на новый коммит.
2
Технически нет ничего плохого в фиксации ваших «безопасных изменений» в двух ветвях, но обычно хорошей идеей является убедиться, что каждое изменение происходит только из одного места.