GIT: как мне сделать частичное слияние из одной ветви в другую? - PullRequest
6 голосов
/ 17 марта 2011

У меня коммиты A-B-C-D на одной ветке и хочу объединить A-B-C с другим.

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

Ответы [ 6 ]

9 голосов
/ 17 марта 2011

Как Самодержавие сказал, git rebase , вероятно, то, что вы хотите.

Пример:

Допустим,у вас есть A-B-C-D и вы хотите объединить A-B-C с Y.Создает клон C и перемещает клон на Y:

git checkout -b C_copy C
git rebase --onto Y A~1 C_copy  # <= --onto [target] [source] [what]

Проверьте, все ли прошло хорошо, и при необходимости разрешите конфликты на своем пути.

Теперь у вас естьC_copy поверх Y, например: Y-[A_copy]-[B-copy]-C_copy

Вы можете отредактировать это с помощью интерактивной перебазировки, например, чтобы раздавить ее (при условии, что вы все еще на C_copy):

git rebase -i HEAD~3

Если что-то пошло не так, вы можете просто выбросить C_copy, поскольку это не влияет на C.

Теперь вы можете либо перемотать вперед Y до C_copy, либо объединить егоиспользуя git merge --no-ff (укажите --no-commit для редактирования вашего коммита, если хотите):

git checkout Y
git merge --no-ff [--no-commit] C_copy
2 голосов
/ 18 марта 2011

Самое простое - это

git branch featureX C
git checkout branch_to_merge_to
git merge featureX

, при желании добавьте --squash к команде слияния, если вы хотите сквош.

Предполагается, что родитель A является базой слияния.Если это не так, вы не объединяетесь.

Надеюсь, это поможет.

2 голосов
/ 17 марта 2011

Не должно git checkout branch-to-merge-on; git merge tag-or-sha1-of-commit-c работать?

Следующее делает так, как я ожидаю:

git init
touch init; git add init; git commit -m 'init'
git checkout -b abcd
touch a; git add a; git commit -m 'a'
touch b; git add b; git commit -m 'b'
touch c; git add c; git commit -m 'c'; git tag commit-c
touch d; git add d; git commit -m 'd'
git checkout master
touch e; git add e; git commit -m 'e'
git merge commit-c

в результате

init -- e -- merged   <- (master)
 \           /   
  a -- b -- c -- d    <- (abcd)

Это объединяет все (вплоть до общего предка (в данном случае init)) перед c, но, похоже, именно это вы и хотите сделать. Если нет, то git rebase использование a-b-c-d в другом месте может быть уместным.

1 голос
/ 14 апреля 2011

Решение wnoise выглядит лучше, и его можно комбинировать с git rebase для завершения.

init -- e --  a -- b -- c (merged)   <- (master)
  \                    /
   \             -----
    \           /   
     a -- b -- c -- d    <- (abcd)

Если вы не хотите, чтобы 'a' на мастере, то вам проще использовать rebase:

git rebase -i init

и откажитесь от нежелательных коммитов

init -- e -- b -- c (merged)   <- (master)
0 голосов
/ 17 марта 2011

Вы можете сделать git cherry-pick --no-commit A B C, а затем выполнить коммит.

0 голосов
/ 17 марта 2011

Лучший способ сделать это - использовать git rebase -i. Вы можете сделать это с новой веткой, если хотите сохранить историю. Вы также можете перенестись на существующую базу и использовать интерактивный сеанс для сжатия или пропуска коммитов, а затем объединить его, если хотите, чтобы он отображался как слияние вместо прямых коммитов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...