Есть ли альтернатива cherry-pick для отмены коммитов?
Мне нужно отменить больше сотни коммитов с показом возможных ошибок. Есть ли способ сделать это автоматически, как делает cherry-pick?
- Вопрос задан 21 нояб. 2022
- 152 просмотра
Комментировать
Решения вопроса 3

Токсичный шарпист
Черри пик же не отменяет коммиты, а копирует из одной ветки в другую.
А тебе, кажется, нужен либо revert, либо reset.
Ответ написан 22 нояб. 2022
Комментировать
Нравится Комментировать
«I’m here to consult you» © Dogbert
git revert умеет работать с диапазонами версий и продолжать/отменять процесс в случае конфликтов.
Ответ написан 22 нояб. 2022

KiGamji @KiGamji Автор вопроса
проблема в том, что у меня исходник новой версии, а мне нужно вернуться на старую версию. я попытался написать git revert новаяверсия..стараяверсия, но получил очевидную ошибку, что у меня нет коммитов для отмены. можно-ли как-то вернуться к старой версии посредством отмены коммитов из добавленного мной репозитория?
git revert стараяверсия..новаяверсия же

KiGamji @KiGamji Автор вопроса
jcmvbkbc, да, но я хочу отменить коммиты из удалëнного репо, а не из локального. git revert пишет, что нет локальных коммитов для отмены

KiGamji, пуллишь к себе удалённый репо, отменяешь, пушишь

KiGamji @KiGamji Автор вопроса
Василий Банников, а как это сделать? я добавлял его через git remote add название сайт
и потом
git fetch название
я хочу отменить коммиты из удалëнного репо, а не из локального
KiGamji, не надо всё мешать в одну кучу. Преврати удалённую репу в локальную (git remote add, git fetch), вычекни полученную ветку, выполни действия, сделай пуш обратно. Ну или продолжай работать с изменённой локально веткой если изменения в удалённой репе не требуются.

KiGamji, а git pull кто делать будет?
Как у вас вообще так получилось, что вы работаете с удалённым репо, который не запуллен?
а git pull кто делать будет?
Василий Банников, git fetch название же сделан.

jcmvbkbc, мне почему-то казалось, что fetch только загружает информацию об изменениях, но не накатывает на локальную ветку.
fetch только загружает информацию об изменениях, но не накатывает на локальную ветку
Василий Банников, так оно и есть. Зачем портить текущую ветку, если можно вычекнуть загруженную ветку отдельно?


KiGamji @KiGamji Автор вопроса
Сергей Кузнецов Василий Банников jcmvbkbc, моя ошибка в том, что я лишь косвенно поведал о своей проблеме.
У меня есть исходник ядра Linux под мой телефон. Версия исходника — 4.14.290. я поднял еë до 4.14.299 следующими командами:
git remote add upstreamkernel https://git.kernel.org/pub/scm/linux/kernel/git/st.
git fetch upstreamkernel
После этого я использовал команду
git cherry-pick v4.14.290..v4.14.291
и так до 299, т. к. мне удобнее поднимать по .001 версии.
Но можно-ли вернуться, к примеру, на v4.14.289? На сайте есть все коммиты для всех версий, для 4.14 это от 4.14-rc1 с 4.14 до 4.14.299. Мне нужно как-бы вычесть эти коммиты из моего исходника, чтобы откатиться назад, но с показом ошибок, т. к. мой исходник отличается от исходника оригинального ядра Linux.
Буду признателен за любую помощь.

KiGamji, на счёт показа ошибок не уверен, что имеется в виду, но revert и reset должны сработать — просто указывай номера коммитов из своей ветки

KiGamji @KiGamji Автор вопроса
Василий Банников, эти коммиты находятся на сайте git.kernel.org, я не могу просто так их откатить, если мой исходник уже выложен с этими коммитами, но их не видно. грубо говоря, исходник выложен без единого коммита.
Но можно-ли вернуться, к примеру, на v4.14.289?
KiGamji, проще всего это делать навешивая теги на свою ветку после каждого обновления минорной версии. Например
git cherry-pick v4.14.290..v4.14.291 ; git tag v4.19.291-my
тогда возврат к конкретной версии — это например git checkout vX.YY.ZZZ-my или git rese —hard vX.YY.ZZZ-my или git revert vX.YY.ZZZ-my..HEAD , по обстоятельствам.
Навешивать теги можно и пост фактум, просто прийдётся искать коммиты которым они соответствуют через git grep или git log .
Мне нужно как-бы вычесть эти коммиты из моего исходника, чтобы откатиться назад,
KiGamji, зачем вычитать оригинальные коммиты, если можно вычесть свои, уже имеющиеся в ветке? Это действие точно не приведёт к новым конфликтам.

KiGamji @KiGamji Автор вопроса
jcmvbkbc, в том то и дело, что начальная версия моего исходника была 4.14.290, а мне нужно еë понизить.
Git Cherry Pick
git cherry-pick — это полезная команда, с помощью которой можно выборочно применить коммиты Git к текущей рабочей ветке HEAD. С ее помощью можно выбрать коммит из одной ветки и применить его к другой. Команда git cherry-pick — это удобный способ отменить изменения. Например, если коммит попал в ветку по ошибке, вы можете переключиться на нужную ветку и выполнить перенос.
Когда следует использовать команду git cherry-pick
Пользоваться командой git cherry-pick удобно, однако это не всегда оптимально. Она может привести к дублированию коммитов, поэтому нередко разработчики предпочитают обычное слияние. Таким образом, можно сказать, что команда git cherry-pick — средство эффективное, но узконаправленное.
Командная работа
Нередко отдельные участники команды работают над одним и тем же кодом. Это может происходить, когда новая функция продукта включает компоненты серверной и клиентской части, две составляющие продукта используют общий код или когда разработчик серверной части создает структуру данных, которую нужно будет использовать и в клиентской части. При этом разработчик клиентской части может с помощью команды git cherry-pick выбрать коммит, в котором условная структура данных была создана. Таким образом, он сможет продолжить работу над своими проектными задачами.
Основные команды и определения
Коммит в git-репозитории хранит снимок всех файлов в директории. Коммит — это набор изменений или «дельта» между текущей версией и предыдущей.
| Код | Описание |
|---|---|
| git commit | Коммит |
Ветвления
Ветки — это просто ссылки на определённый коммит — ничего более.
| Код | Описание |
|---|---|
| git branch [name] | Создание ветки |
| git checkout [name] | Переключение ветки |
Слияния
Слияния в Git создают особый вид коммита, который имеет сразу двух родителей. Коммит с двумя родителями обычно означает, что мы хотим объединить изменения из одного коммита с другим коммитом и всеми их родительскими коммитами.
| Код | Описание |
|---|---|
| git merge [name] | Слияние веток |
Git Rebase
При rebase Git по сути копирует набор коммитов и переносит их в другое место. Преимущество rebase в том, что c его помощью можно делать чистые и красивые линейные последовательности коммитов. История коммитов будет чище, если вы применяете rebase.
| Код | Описание |
|---|---|
| git rebase [name] | Rebase |
HEAD
HEAD — это символическое имя текущего выбранного коммита — это, по сути, тот коммит, над которым мы в данным момент работаем. HEAD всегда указывает на последний коммит из вашего локального дерева. Большинство команд Git, изменяющих рабочее дерево, начнут с изменения HEAD.
Отделение (detaching) HEAD
Отделение (detaching) HEAD означает лишь присвоение его не ветке, а конкретному коммиту.
| Код | Описание |
|---|---|
| HEAD -> master -> C1 | |
| git checkout C1 | |
| HEAD -> C1 | Отделение (detaching) HEAD |
Относительные ссылки
С относительными ссылками можно начать с какого-либо удобного места (например, с ветки или от HEAD) и двигаться от него.
| Код | Описание |
|---|---|
| git checkout [name]^ | Перемещение на один коммит назад |
| git checkout [name]~[num] | Перемещение на num коммитов назад |
Перемещение ветки (branch forcing)
Одна из наиболее распространённых целей, для которых используются относительные ссылки — это перемещение веток. Можно напрямую прикрепить ветку к коммиту при помощи опции -f .
| Код | Описание |
|---|---|
| git branch -f master HEAD~3 | Переместить (принудительно) ветку master на три родителя назад от HEAD. |
Отмена изменений в Git
Есть много путей для отмены изменений в Git. Так же как и коммит, отмена изменений в Git возможна и на низком уровне (добавление в коммит отдельных файлов и наборов строк), и на высоком (как изменения реально отменяются). Сейчас сфокусируемся на высокоуровневой части.
Есть два основных способа отмены изменений в Git.
git revert [name]
Git Reset
Git reset отменяет изменения, перенося ссылку на ветку назад, на более старый коммит. Это своего рода «переписывание истории»; git reset перенесёт ветку назад, как будто некоторых коммитов вовсе и не было.
| Код | Описание |
|---|---|
| git reset HEAD~1 | Git просто перенёс ссылку на master обратно на коммит C1. Теперь наш локальный репозиторий в состоянии, как будто C2 никогда не существовал. |
Git Revert
Git reset отлично работает на локальных ветках, в локальных репозиториях. Но этот метод переписывания истории не сработает на удалённых ветках, которые используют другие пользователи.
Чтобы отменить изменения и поделиться отменёнными изменениями с остальными, надо использовать git revert .
| Код | Описание |
|---|---|
| Git revert HEAD | Новый коммит C2′ просто содержит изменения, полностью противоположные тем, что сделаны в коммите C2. |
Git Cherry-pick
Это очень простой и прямолинейный способ сказать, что ты хочешь копировать несколько коммитов на место, где сейчас находишься (HEAD).
| Код | Код |
|---|---|
| git cherry-pick [commit1] [commit2] [. ] | git cherry-pick C2 C4 |
Git Interactive Rebase
Git cherry-pick применяется, когда точно известно, какие коммиты нужны (и известны их точные хеши).
Но, в случае, когда точно не известно какие коммиты нужны можно использовать интерактивный rebase — лучший способ отобрать набор коммитов для rebase .
| Код | Код | Описание |
|---|---|---|
| git rebase -i [name] | git rebase -i HEAD~4 | Rebase ordering C3, C4 |
results matching » «
No results matching » «
A3.8 Приложение C: Команды Git — Внесение исправлений
Некоторые команды в Git основываются на подходе к рассмотрению коммитов в терминах внесённых ими изменений, т. е. рассматривают историю коммитов как цепочку патчей. Ниже перечислены эти команды.
git cherry-pick
Команда git cherry-pick берёт изменения, вносимые одним коммитом, и пытается повторно применить их в виде нового коммита в текущей ветке. Эта возможность полезна в ситуации, когда нужно забрать парочку коммитов из другой ветки, а не сливать ветку целиком со всеми внесёнными в неё изменениями.
Этот процесс описан и показан в разделе Схема с перебазированием и отбором главы 5.
git rebase
git rebase — это «автоматизированный» cherry-pick . Он выполняет ту же работу, но для цепочки коммитов, тем самым как бы перенося ветку на новое место.
Мы в деталях разобрались с механизмом переноса веток в разделе Перебазирование главы 3, включая рассмотрение потенциальных проблем переноса опубликованных веток при совместной работе.
Мы использовали эту команду на практике для разбиения истории на два репозитория в разделе Замена главы 7, наряду с использованием флага —onto .
В разделе Rerere главы 7 мы рассмотрели случай возникновения конфликта во время переноса коммитов.
Также мы познакомились с интерактивным вариантом git rebase , включающемся с помощью опции -i , в разделе Изменение сообщений нескольких коммитов главы 7.
git revert
Команда git revert — полная противоположность git cherry-pick . Она создаёт новый коммит, который вносит изменения, противоположные указанному коммиту, по существу отменяя его.
Мы использовали её в разделе Отмена коммита главы 7 чтобы отменить коммит слияния (merge commit).