Git - Как выборочно применять изменения из одной ветви в другую?

Можно ли выборочно применять изменения из одной ветви в другую с помощью Git?

Более конкретно, я использую публичный dev ветка для GitHub и частного master ветка для развертывания. Когда изменения вносятся в одну ветвь, их необходимо применять к другой, но некоторые строки кода должны оставаться разными. В моем случае это несколько классов CSS и канал.

Я новичок в Git, но я сделал свое исследование:

  • git merge --no-commit --no-ff может быть использован с последующим git mergetool выбрать то, что я хочу в случае конфликта. Проблема в том, что он работает только для конфликтов, которые Git не может автоматически объединять, поэтому то, что я хочу оставить по-другому, заменяется, прежде чем я получу возможность использовать свой mergetool.

  • git difftool --cached Это полезно, поскольку позволяет мне увидеть различия, но мне нужно скопировать то, что я хочу оттуда сохранить, и вручную заменить его текстовым редактором, поскольку я не могу просто выбрать и сохранить, как я могу с помощью mergetool.

  • git cherry-pick кажется, применяет определенный коммит к другому, но то, что я хочу оставить другим, может быть разбросано по разным коммитам, и эти коммиты могут включать не только то, что я хочу остаться другим. Я не смогу увидеть, как это работает, если я не совершу миллионы коммитов, которые сведут меня с ума.

Также, чтобы быть ясным, я не хочу, чтобы одна ветвь стала другой, что похоже на случай слияния. Я хочу две отдельные ветви с их соответствующими различиями и применять изменения от одного к другому.

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

3 ответа

Решение

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

Кстати, если вы хотите взять некоторые файлы из коммита, вы можете использовать cherry-pick с комбинацией других команд, как описано здесь.

Я также узнал о исправлении:

Чтобы создать патч: git diff dev > master.patch

Чтобы применить это: patch < master.patch

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

  1. Проверьте вашу ветку источника dev,
  2. Создать временную ветку. Это будет указывать на тот же коммит, который dev делает: checkout -b for_master

    Предположительно, вы знаете (или можете легко выяснить), какие совершить до dev ветвь является последней перед изменениями, которые вы (частично) хотите. В этом примере предположим, что этот коммит имеет хеш 1457B4 ("Последний раньше", получите?).

  3. Сбросить ваш for_master переход к этому коммиту: git reset 1457B4, (Не используйте --hard переключатель!)

    Теперь у вас есть рабочий каталог, содержащий все изменения, которые находятся в dev, но от POV из for_master ветви, эти изменения являются неустановленными и незафиксированными (в то время как dev ветвь по-прежнему указывает на коммиты, которые записывают все изменения, поэтому работа все еще безопасна).

  4. Использование интерактивной постановки (git add -p и / или git add -e), создайте коммит (или более одного, если хотите), который содержит все и только изменения, которые вы хотите применить к вашему master ветка.

    Запишите хэш последнего коммита (или присвойте ему тег). В этом примере я скажу, что его хэш C0DA,

  5. Проверять, выписываться master,

  6. Cherry-выберите коммит (ы), которые вы только что сделали: git cherry-pick 1457B4..C0DA,

    (Обратите внимание, что выбор диапазона вишни доступен только после git версии 1.7.2. В противном случае вам нужно будет выбрать все коммиты, сделанные вами на шаге 4).

    (Также обратите внимание, что когда вы выбираете диапазон "черри", начало диапазона - это фиксация перед первым, который будет фактически выбран.)

Этот процесс является своего рода обратным использованием git checkout -p как указано в выбранном ответе. Это может быть полезно для создания cherry-pick -able фиксирует между двумя ветвями, которые разделяют некоторый код, но также имеют много различий (например, между двумя основными версиями проекта), и вам не нужно тратить много времени на игнорирование ненужных файлов при вызове git checkout -p,

Лично я нашел удобным использовать два разных каталога рабочих деревьев для одного и того же репозитория (один для исходной ветви и один для места назначения) и переключаться между двумя командными оболочками, один с использованием исходного каталога ветви (рабочего дерева), а другой - место назначения. Но если вам неудобно пользоваться git worktree особенность, которая не может быть для вас.

Другие вопросы по тегам