Перенести коммит в другую ветку git: используем cherry-pick для переноса commit в другую ветку

используем cherry-pick для переноса commit в другую ветку

Нередко возникает ситуация, когда срочно требуется выполнить небольшую задачу. Разработчик быстро пробегается глазами по ТЗ и старается максимально оперативно вникнуть в суть задачи. При этом можно попросту забыть создать новую ветку, и понять об ошибке уже после финального каммита.

В такой ситуации, когда возникает необходимость перенести commit из одной ветки в другую на помощь приходит команда git cherry-pick, применяющая к дереву проекта изменения, которые были внесены указанным каммитом.

Синтаксис команды git cherry-pick

Рассмотрим ситуацию на примере. Мы находились в master и сделали в него случайно коммит. Тогда чтобы вынести его в отдельную ветку и отправить на merge request нам потребуется выполнить следующие команды:

1. Смотрим историю изменений и запоминаем хэш коммита <hash-commit-0>, соответствующего правильному состоянию ветки master, то есть когда ещё в неё не было добавлено лишних коммитов по ошибке.

git log

2. Также следует запомнить хэш коммита <hash-commit-1>

, который был лишним в ветке master. Иногда бывает, что лишними оказываются сразу несколько коммитов, тогда если они расположены последовательно друг за другом следует запомнить самый давний <hash-commit-begin> и самый последний <hash-commit-end>.

3. Перейдём на найденный коммит <hash-commit-0>. Другими словами переходим на то состояние ветки master, от которого нам нужно создать новую ветку.

git checkout <hash-commit-0>

4. Создадим новую ветку, в которую планируется вынести неверно расположенный коммит, и перейдем на неё.

git checkout -b <name-branch>

5. Переносим коммит в новую ветку.

git cherry-pick <hash-commit-1>

В случае, когда необходимо перенести последний коммит ветки master, можно вместо хэша коммита просто написать

master, поскольку в данный момент указатель master ссылается на последний коммит.

git cherry-pick master

Если же нужно перенести не один, а несколько подряд идущих коммитов от <hash-commit-begin> до <hash-commit-end>, то это делается похожим образом.

git cherry-pick <hash-commit-begin>..<hash-commit-end>

Если же вы хотите, чтобы при переносе изменений коммит не создавался, то используйте параметр -n (—no-commit):

git cherry-pick -n d112ecf96

Как и при операции git rebase в процессе переноса коммита могут возникнуть конфликты. Как и при обычном git merge их следует разрешить, добавить изменения в индекс с помощью git add, а затем продолжить запустив git cherry-pick --continue.

6. Теперь когда коммиты перенесены в ветку <name-branch>, следует удалить их из ветки master. Поэтому переключаемся на ветку master

git checkout master

Смещаем указать master на коммит <hash-commit-0>

git reset --hard <hash-commit-0>

Понравилась статья? — Ставь лайк!

Как влить определённый коммит из одной ветки в другую git

git cherry-pick — применение к дереву проекта изменений, внесенных определённым коммитом.

git cherry-pick <hash коммита> — найдёт коммит по его хэшу и вольёт его в текущую ветку. Применятся изменения только конкретного коммита, причём изменения сразу же будут проиндексированы и будет создан новый коммит в активной ветке с таким же именем, как коммит и назывался. При наличии конфиликтных изменений, нужно будет решить конфликты, как и при «рядном» merge.

Если вам нужно перенести изменения в ветку из определённого коммита другой ветки так, чтобы коммит автоматически не создавался, то нужно использовать параметр -n (—no-commit). Пример:

git cherry-pick -n d3edb354cd3c080b28d13dcb92448de81e543297

Все поддериживаемые параметры cherry-pick:

$ git cherry-pick 

использование: git cherry-pick [options] <commit-ish>…

   или: git cherry-pick <subcommand>

 

    —quit                end revert or cherry-pick sequence

    —continue            resume revert or cherry-pick sequence

    —abort               cancel revert or cherry-pick sequence

    -n, —no-commit       don’t automatically commit

    -e, —edit            edit the commit message

    -s, —signoff         add Signed-off-by:

    -m, —mainline <n>    parent number

    —rerere-autoupdate   update the index with reused conflict resolution if possible

    —strategy <strategy>

                          merge strategy

    -X, —strategy-option <option>

                          option for merge strategy

    -x                    append commit name

    —ff                  allow fast-forward

    —allow-empty         preserve initially empty commits

    —allow-empty-message

                          allow commits with empty messages

    —keep-redundant-commits

                          keep redundant, empty commits

Как перенести коммиты в другую ветку? — git

Я бы хотел перенести мои последние несколько коммитов от мастера в их собственную ветвь.

Дерево на моем PC выглядит именно так:

   W (some branch)
  /       
X1--X2--X3--X4--Y--Z1--Z2 (master)

Я бы хотел, чтобы это выглядело так:

   W (some branch)
  /       
X1--X2--X3--X4 (master)
             \
              Y--Z1--Z2 (my new branch)

Однако дерево в GitHub выглядит следующим образом:

   W (some branch)
  /       
X1--X2--X3--X4--Y (master)

Это то, что я видел как решение для перемещения последних коммитов в другую ветвь:

git checkout master
git branch my_new_branch
git reset <commit_id>

Мой вопрос заключается в следующем: смогу ли я успешно нажать на GitHub после перемещения коммитов в новую ветвь и если да, то потребуется ли делать что-то еще, кроме этих трех команд?

git branch push commit
Поделиться Источник Albus Dumbledore     17 мая 2011 в 18:57

3 Ответа



18

(Я предполагаю, что <commit_id> — это имя объекта X4 …)

Эти команды действительно приведут вас к тому, что вы хотите локально. (Возможно, вы захотите использовать git reset --hard , чтобы сохранить рабочее дерево и индекс таким же, как и фиксация, к которой вы сбрасываете, но, как обычно, будьте очень осторожны, чтобы git status был чистым, прежде чем использовать эту команду.)

Если после этого вы попытаетесь нажать master на GitHub, он скажет вам, что все уже обновлено, потому что

master на GitHub-это один коммит вперед. Вы можете принудительно нажать кнопку, чтобы мастер был сброшен на GitHub, но это переписывание публичной истории, поэтому вы должны сделать это только в том случае, если (А) вы единственный, кто получит master из GitHub или (б) вы можете сообщить своим сотрудникам, что делать, чтобы они случайно не слили Y обратно. Если это OK, вы можете сделать:

 git push --force origin master

и тогда master на GitHub будет таким же, как ваша локальная версия.

Поделиться Mark Longair     17 мая 2011 в 19:13



3

Это должно сработать, но вам понадобится:

  • to
    push -f origin master
    (принудительный толчок, который будет означать неприятности, если кто-то еще уже клонировал ваше РЕПО)
  • чтобы нажать затем вашу новую ветвь (которая затем найдет X4 sha1, поверх которой будет установлена указанная новая ветвь).

Поделиться VonC     17 мая 2011 в 19:13



0

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

Просто скопируйте идентификатор ревизии вашего коммита, который вы хотите переместить. git log --oneline

Чем создать новую ветвь поверх прежней фиксации и изменить ее: git checkout -b "$newBranchName" HEAD~$n (HEAD~$n расшифровывается как n-th commit) или

git checkout -b "$newBranchName" $formerRevsion

Теперь вам просто нужно выбрать вишню, которую вы хотите совершить: git cherry-pick $revision

Старый коммит все еще будет находиться в другой ветке, но вы можете исправить это с помощью rebase. Вернитесь в свою старую ветку и используйте rebase: git rebase -i HEAD~$n

Просто удалите строку фиксации выбранного вишневого коммита, и ваша ветвь будет перебазирована без него. Вы должны использовать git push -f , потому что ревизии всех ребазированных коммитов изменились.

Поделиться Devpool     28 августа 2017 в 14:11


Похожие вопросы:


Как нажать на другую ветку с hg-git?

Пока я работал над своим клоном репозитория Git, удаленный контент изменился: $ hg push … abort: refs/heads/master changed on the server, please pull and merge before pushing Вместо слияния я хочу…


Как перенести многократные коммиты из одной ветви в другую с помощью git?

Есть две ветви: — производственная ветвь, содержащая продукт, принятый заказчиком — разработать ветку, где разработчики проводят свои жуткие эксперименты Однажды молодой разработчик решил отделить…


Git — как получить все новые коммиты из master в мою ветку

У меня есть мастер, из которого я создал другую ветвь и сделал некоторые коммиты на этой новой ветви. Между тем в это же время в master также происходили некоторые другие работы/коммиты. Итак,…


Переместить некоторые уже существующие и толкаемые коммиты в новую ветку

У меня есть ветвь функций по теме X, но в этой ветви я сделал коммиты, которые были бы лучше в ветви функций Y, но я забыл создать ее перед началом. Есть ли способ перенести этот коммит в новую…


Переместить коммиты из линейной истории в отдельную ветвь

Это не то же самое, что разделить ветку git на две ветви? а не как перенести определенные коммиты в другую ветку в git? У меня есть линейная история B—C , ветвящаяся от мастера: Master —A \ Foo…


Git : как протолкнуть некоторые коммиты на другую ветку

Это мой git : x—x—v2—x—x—x — dev / x—x—x—x—v1 — prod Теперь я хотел бы протолкнуть все коммиты до v2 из ветки dev в ветку prod, но v2 не является моим последним коммитом на ветке dev. Как я…


перемещение измененных файлов в другую ветку для регистрации

Это часто случается со мной: я пишу какой-то код, иду проверить свои изменения, а затем понимаю, что я не в той ветке, чтобы проверить эти изменения. Однако я не могу переключиться на другую ветку…


Переместить некоторые коммиты в другую ветку

У меня есть git РЕПО только в одной ветке A-B-C-D-E (master) Я хочу разделить коммиты B, C и D на другую ветку под названием develop A-E (master) \ B-C-D (develop) Каков самый простой способ сделать…


Как исключить коммиты из master в другую ветку

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


Переместить коммиты в другую ветку

Я сделал три коммита на мастер-ветку и отодвинул их на дистанционное управление. Изменения должны были быть незначительными (применяя исправленный выпуск фреймворка), но столкнулись с действительно…


Как переместить определенные коммиты в другую ветку в git?

ситуация:

  • мастер находится на X
  • quickfix1 находится на X + 2 коммитов

такое, что:

o-o-X (master HEAD)
     \
      q1a--q1b (quickfix1 HEAD)

затем я начал работать над quickfix2, но случайно взял quickfix1 в качестве исходной ветви для копирования, а не мастера. Теперь quickfix2 находится в X + 2 commits + 2 соответствующих коммитов.

o-o-X (master HEAD)
     \
      q1a--q1b (quickfix1 HEAD)
              \
               q2a--q2b (quickfix2 HEAD)

Теперь я хочу иметь ветку с quickfix2, но без 2 коммитов, которые принадлежат quickfix1.

      q2a'--q2b' (quickfix2 HEAD)
     /
o-o-X (master HEAD)
     \ 
      q1a--q1b (quickfix1 HEAD)

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

320

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Theme: Overlay by Kaira Extra Text
Cape Town, South Africa