Как я могу объединить много коммитов, но оставить один? - PullRequest
74 голосов
/ 26 октября 2009

Предположим, у меня есть эта ветка функций "foo". Теперь я хочу объединить его с мастером, но я добавил отладочный код, который мне не нужен в мастере.

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

Есть ли какая-то "обратная вишня", которая делает это, или интерактивное слияние?

Ответы [ 5 ]

68 голосов
/ 26 октября 2009

Несмотря на то, что другие СКМ используют его для обозначения, в git, git revert - обратная вишня.

53 голосов
/ 26 октября 2009

Использовать интерактивную перебазировку:

git rebase -i SHA-OF-FIRST-COMMIT-IN-BRANCH

Это откроет что-то вроде этого в вашем $ EDITOR:

    pick 8ac4783 folders and folders
    pick cf8b1f5 minor refactor
    pick 762b37a Lots of improvement. Folders adn shit.
    pick 3fae6e1 Be ready to tableview
    pick b174dc0 replace folder collection view w/ table view
    pick ef1b65b more finish
    pick ecc407f responder chain and whatnot
    pick 080a847 play/pause video
    pick 6719000 wip: movie fader
    pick c5f2933 presentation window fade transition

    # Rebase e6f77c8..c5f2933 onto e6f77c8
    #
    # Commands:
    #  p, pick = use commit
    #  e, edit = use commit, but stop for amending
    #  s, squash = use commit, but meld into previous commit
    #
    # If you remove a line here THAT COMMIT WILL BE LOST.
    # However, if you remove everything, the rebase will be aborted.
    #

Итак, вы просто удалите строку, содержащую коммит отладки, напишите файл и закроете свой редактор, и git скажет вам что-то вроде:

Successfully rebased and updated refs/heads/master.

Теперь вы можете просто объединить эту ветку с мастером.

ОБНОВЛЕНИЕ: Следует отметить, что изменение истории с rebase должно только происходить в частных филиалах. Если эта ветвь была открыта для общественности, используйте git revert, как предложено другим ответчиком.

7 голосов
/ 26 июля 2011

Другая идея состоит в том, чтобы добавить возвращенный коммит того с отладочным кодом и объединить его с вашей основной веткой. После этого мы удаляем этот дополнительный коммит в ветке foo.

git checkout foo
git revert COMMIT_REF_WITH_DEBUG_CODE

git checkout master
git merge foo

git checkout foo
git reset --hard HEAD~1

Убедитесь, что ваше рабочее дерево чистое. Сначала создайте отмененный коммит. Затем объедините его в мастер. После этого сбросьте указатель ветки foo на родителя отмененного коммита, чтобы он вернулся в исходное состояние.

Если вам не нравится git reset, вы можете создать временную ветвь, в которой вы создадите отмененный коммит. В конце вы удаляете временную ветку.

2 голосов
/ 27 октября 2009

Используйте интерактивное перебазирование, чтобы удалить коммиты, которые вы не хотите.

В новой ветке "foo-merge", созданной из "foo":

git rebase -i master

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

После перебазирования просто потяните foo-merge в master:

git checkout master
git pull . foo-merge
0 голосов
/ 08 апреля 2016

У меня был успех с:

git rebase -p --onto SHA^ SHA

Где SHA - коммит, который вы хотите удалить.

через http://sethrobertson.github.io/GitFixUm/fixup.html#remove_deep

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