Будет ли новый commit при cherry-pick?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Будет ли новый commit при cherry-pick
Да, при выполнении git cherry-pick будет создан НОВЫЙ commit. Это одна из ключевых особенностей cherry-pick, которую важно понимать при работе с Git.
Как работает cherry-pick
Когда вы выполняете git cherry-pick, Git не просто копирует commit в виде ссылки на исходный commit. Вместо этого происходит следующее:
- Git берет изменения (diff) из исходного commit'а
- Применяет эти изменения к текущей ветке
- СОЗДАЕТ НОВЫЙ commit с этими изменениями
- Исходный commit остается в исходной ветке
Простой пример
# Исходное состояние
# main: A -> B -> C
# feature: D -> E -> F
git checkout main
git cherry-pick feature~1 # cherry-pick commit E
# Результат
# main: A -> B -> C -> E' (E' это НОВЫЙ commit, копия E с новым hash)
# feature: D -> E -> F (E остается без изменений)
Важные детали о новом commit
1. Новый commit hash
# В ветке feature
git log --oneline
ab12345 Commit E # hash ab12345
cd67890 Commit D
# После cherry-pick в main
git checkout main
git cherry-pick ab12345
git log --oneline
ef11111 Commit E # НОВЫЙ hash ef11111, не ab12345!
1234567 Commit C
Хотя сообщение commit'а одинаковое, hash полностью отличается.
2. Новый author дата (по умолчанию)
# Исходный commit в feature ветке был создан недели 2 назад
# После cherry-pick, дата создания commit'а = сегодня
git show ab12345
# Date: 2 weeks ago
git cherry-pick ab12345
git show ef11111
# Date: today (совсем свежая дата)
Если нужно сохранить исходную дату, используйте флаг:
git cherry-pick --keep-commit-date ab12345
# Или для author дата
git cherry-pick -x ab12345
3. Сохранение сведений об исходном commit (флаг -x)
git cherry-pick -x ab12345
# В новом commit появится сообщение:
# Commit message
# (cherry picked from commit ab12345 in feature branch)
Практический сценарий
# Есть два commit'а в ветке bugfix которые нужны в main
git log --oneline bugfix
3c4d5e6 Fix: исправлена критическая ошибка
2b3c4d5 Feat: добавлена новая функция
1a2b3c4 начальный коммит
# Переходим на main и берем нужные commit'ы
git checkout main
git cherry-pick 2b3c4d5 3c4d5e6
# Теперь в main есть ДВА НОВЫХ commit'а
git log --oneline main
aa1122bb Fix: исправлена критическая ошибка (новый, другой hash)
bb2233cc Feat: добавлена новая функция (новый, другой hash)
3f4g5h6 предыдущий commit в main
# В bugfix ничего не изменилось
git log --oneline bugfix
3c4d5e6 Fix: исправлена критическая ошибка (исходный hash)
2b3c4d5 Feat: добавлена новая функция (исходный hash)
1a2b3c4 начальный коммит
Сравнение cherry-pick с другими операциями
cherry-pick vs rebase
# cherry-pick: Создает НОВЫЕ commit'ы
git cherry-pick commit1 commit2
# Результат: новые commit'ы с новыми hash'ами
# rebase: Переписывает commit'ы поверх другой ветки
git rebase main
# Результат: commit'ы переписаны, hash'ы изменились
Разница: cherry-pick не меняет исходные commit'ы и может применяться избирательно, rebase полностью переписывает историю.
cherry-pick vs merge
# merge: Создает один merge commit
git merge bugfix
# Результат: один commit который объединяет две ветки
# cherry-pick: Создает НОВЫЙ commit для каждого cherry-pick'ленного commit'а
git cherry-pick commit1
# Результат: один новый commit с изменениями от commit1
Когда появляется новый commit
Всегда! При успешном cherry-pick всегда создается новый commit. Но есть исключение:
Случай 1: Cherry-pick без конфликтов
git cherry-pick ab12345
# Автоматически создается новый commit
Случай 2: Cherry-pick с конфликтами
git cherry-pick ab12345
# CONFLICT: merge conflict in file.js
# Нужно разрешить конфликт
git add file.js
# Завершить cherry-pick
git cherry-pick --continue
# Создается новый commit с вашими изменениями + конфликт разрешен
# Или отменить
git cherry-pick --abort
# Новый commit НЕ создается
Случай 3: Пустой commit
# Если cherry-pick не привнес никаких изменений (уже все есть)
git cherry-pick ab12345
# warning: nothing to commit (working tree clean)
# Новый commit НЕ создается, но можно создать пустой
git cherry-pick --allow-empty ab12345
Важные флаги cherry-pick
# 1. Создать коммит с ссылкой на исходный
git cherry-pick -x commit_hash
# (cherry picked from commit xxx)
# 2. Сохранить дату автора
git cherry-pick --keep-commit-date commit_hash
# 3. Не создавать commit, только применить изменения
git cherry-pick --no-commit commit_hash
# Изменения применены, но commit НЕ создан
# Нужно вручную запустить: git commit
# 4. Изменить сообщение commit'а
git cherry-pick -e commit_hash
# Откроется редактор для редактирования сообщения
# 5. Позволить пустые commit'ы
git cherry-pick --allow-empty commit_hash
# 6. Позволить стратегию слияния с использованием -X
git cherry-pick -X theirs commit_hash
# При конфликте берет версию из cherry-pick'ленного commit'а
Практический пример с --no-commit
# Применить изменения, но не создавать коммит сразу
git cherry-pick --no-commit ab12345 cd56789
# Изменения применены, но коммитов нет
git status
# Changes to be committed: (показывает изменения)
# Можем отредактировать файлы перед commit'ом
# Или объединить несколько cherry-pick'ов в один commit
git commit -m "Несколько важных исправлений"
Проблемы при cherry-pick
Дублирование commit'ов
# Если потом сделать merge, может получиться дублирование
git cherry-pick feature~1 # применили commit E в main
git merge feature # теперь в main появляется еще один E
# Git обычно это обнаруживает и не создает дубль, но с правками может быть проблема
Потеря истории
# В новом commit'е нет информации о контексте из исходной ветки
# Используйте -x флаг для сохранения справки
git cherry-pick -x ab12345
Проверка что создался новый commit
# До cherry-pick
git log --oneline
abc1234 Feature X
# После cherry-pick
git log --oneline
def5678 Feature X (новый hash!)
abc1234 Feature X (исходный из другой ветки еще тут есть в истории)
Заключение
Ответ на вопрос: ДА, при cherry-pick ВСЕГДА создается новый commit (если нет ошибок или отмены операции). Это основное отличие cherry-pick от обычного merge или rebase. Новый commit имеет:
- Новый hash
- Новую дату создания (обычно текущую, если не использовать флаги)
- Но же самые изменения как в исходном commit'е
- Возможность добавить информацию об исходном commit'е с помощью флага -x
Это позволяет cherry-pick быть безопасной операцией, которая не влияет на исходные commit'ы.