@Mark Longair прибил это в своем ответе здесь , но я хотел бы добавить некоторую дополнительную информацию.
Связанный и отвечающий на вопрос о том, как разбить большой запрос на извлечение (PR), особенно когда сжатие ваших коммитов нецелесообразно из-за одного или нескольких слияний мастера в ваш feature_branch
Моя ситуация:
я заработал feature_branch30 коммитов и открыл запрос на извлечение (PR) на GitHub, чтобы объединить его master. Филиал masterизменил тонну подо мной и получил 200 коммитов, которых у меня feature_branchне было. Чтобы разрешить конфликты, которые я сделал, git checkout feature_branchи git merge masterобъединить masterизменения в свои feature_branch. Я предпочел, mergeа не потому, что это может стереть историю комментариев GitHub в PR. Итак, я слил master в свою ветку функций и разрешил конфликты один раз. Все было хорошо. Мой PR, однако, был слишком большим для моих коллег, чтобы рассмотреть. Мне нужно было разделить это. Я пошел, чтобы раздавить мои 30 коммитов и ОН НЕТ! ГДЕ ОНИ? ОНИ ВСЕ ЗАПРЕЩЕНЫ с 200 недавними коммитами, потому что я слился с моимrebase последнего мастера, поэтому мне придется разрешать конфликты только один раз, а не 30 раз (по одному разу для каждого из моих коммитов). Я не хотел сначала раздавить свои 30 коммитов в 1, а затем перенести на последнийmastermastermasterfeature_branch! ЧТО МНЕ ДЕЛАТЬ?
git cherryиспользование в случае, если вы хотите попробовать git cherry-pickотдельные коммиты:
git cherry на помощь (вроде)!
Чтобы увидеть все коммиты, которые находятся в, feature_branchно НЕ в masterя могу сделать:
git checkout feature_branch
git cherry master
ИЛИ, я могу проверить коммиты из ЛЮБОГО ветвления с ВНИМАНИЕМ, гарантируя, что я feature_branchпервым делаю git cherry [upstream_branch] [feature_branch], как это. Опять же, это проверяет, какие коммиты есть, feature_branchно нет upstream_branch( masterв этом случае):
git cherry master feature_branch
Добавление -vтакже показывает строки темы сообщения о коммите:
git cherry -v master
Трубопровод к «подсчету слов» «-lines» ( wc -l) подсчитывает, сколько существует коммитов :
git cherry master | wc -l
Вы можете сравнить это количество с номером коммита, показанным в вашем GithHub PR, чтобы почувствовать себя лучше, зная, что он git cherryдействительно работает. Вы также можете сравнить git-хэши один за другим и посмотреть, совпадают ли они с git cherryGitHub. Обратите внимание , что git cherryне будет рассчитывать любые слияния фиксаций, вы слиты masterв feature_branch, но GitHub ВОЛЯ. Так что, если вы видите небольшое расхождение в подсчете, поищите на странице коммита GitHub PR слово «слияние», и вы, вероятно, увидите, что это виновник, которого не видно git cherry. Пример: коммит под названием «Объединить ветку 'master' в feature_branch" будет отображаться в GitHub PR, но не при запуске git cherry master feature_branch. Это нормально и ожидаемо.
Итак, теперь у меня есть способ выяснить, какие различия я хочу выбрать из вишни на новую ветку функций, чтобы разделить эту разницу: я могу использовать git cherry master feature_branchлокально или посмотреть коммиты в GitHub PR.
Как может помочь раздавливание - если бы мы только могли раздавить:
Однако, чтобы разделить мой большой дифференциал, нужно разделить все 30 моих коммитов на один, залатать их в новую ветвь функций, мягко сбросить коммит патча, а затем использовать git guiдля добавления фрагментов файл за файлом, кусок за кусок или построчно. Как только я получу одну подфункцию, я могу зафиксировать то, что я добавил, затем проверить новую ветку, добавить еще несколько, зафиксировать, проверить новую ветку и т. Д., Пока моя большая функция не будет разбита на несколько подфункций. , Проблема в том, что мои 30 коммитов смешаны с другими 200 коммитами от других людей из-за моего git merge masterв мой feature_branch, поэтому перебазировка нецелесообразна, так как мне пришлось бы просеять 230 коммитов, чтобы переупорядочить и раздавить мои 30 коммитов.
Как использовать файл патча как гораздо более простую замену сквошу:
Обходной путь - просто получить файл патча, содержащий «эквивалент сквоша» из всех 30 моих коммитов, патчить его на новый masterветвь (новую ветвь подфункции) и работать оттуда следующим образом:
git checkout feature_branch
# ensure I have the latest changes from master merged into feature_branch
git merge master
# Obtain a patch file, which is the equivalent of a squash of my 30 commits into 1 commit:
git diff master..feature_branch > ~/mypatch.patch
git checkout master
# Create a new, sub-feature branch
git checkout -b feature_branch2
# Patch the 30 commit patch file onto it:
git apply ~/mypatch.patch
Теперь у меня есть 30-коммитный патч, примененный локально, но без изменений и без изменений.
Теперь используйте, git guiчтобы добавить файлы, чанки и / или строки и разбить ваш большой PR или «diff»:
Обратите внимание, что если у вас его нет git gui, вы можете легко установить его в Ubuntu с помощью sudo apt install git-gui.
Теперь я могу запустить git guiи начать добавлять файлы, чанки и / или строки (щелкнув правой кнопкой мыши в программе git GUI), и разбить ветвь функции 30 коммитов на подветви, как описано выше, многократно добавляя, фиксируя, затем разветвляясь ветвь новой функции и повторение этого цикла, пока все изменения не будут добавлены в ветку подфункции, и моя функция 30 коммитов успешно разбита на 3 или 4 подфункции. Теперь я могу открыть отдельный PR для каждой из этих подфункций, и моей команде будет легче их просматривать.
Ссылки:
- Создайте файл патча или diff из репозитория git и примените его к другому другому репозиторию git