Как я могу объединить много коммитов, но оставьте его?

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

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

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

Ответ 1

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

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, как было предложено другим ответчиком.

Ответ 2

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

Ответ 3

Другая идея состоит в том, чтобы добавить отмененную фиксацию с кодом отладки и объединить ее в свою основную ветку. Впоследствии мы удаляем эту дополнительную фиксацию в ветки 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

Убедитесь, что рабочее дерево чистое. Сначала создайте отмененную фиксацию. Затем объедините его в мастер. Затем reset указатель ветвления ветки foo на родительский элемент возвращенного фиксации, поэтому он возвращается в исходное состояние.

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

Ответ 4

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

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

git rebase -i master

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

После перезагрузки просто вытащите foo-merge в master:

git checkout master
git pull . foo-merge