Git - сквот всей ветки - одна команда squash
пока я работаю над новым кодом, я делаю много мелких коммитов для отслеживания изменений. Однако моя компания предпочитает, чтобы каждая функция была зафиксирована в одной транзакции. Таким образом, решение состоит в том, чтобы вырезать всю ветвь до одной фиксации.
Как вырезать всю ветку без использования git rebase --interactive
, а затем меняя pick
на squash
для всех коммитов?
Ответы
Ответ 1
Мой предпочтительный метод - двухстрочный (исключая шаги 1 и 4 ниже). Преимущества в том, что вам не нужно знать/записывать любые идентификаторы фиксации, вы можете написать простой псевдоним для выполнения всех шагов и фактическое перемещение всей ветки на происхождение/master, чтобы фактический слияние в мастер может быть быстрым, и конфликтов не может быть.
Во-первых, мои предположения:
- Вы работаете над ветвью с именем
my-feature-branch
. Эта ветвь отклонилась от master
несколькими коммитами; это отмеченная ветка.
- Ваш локальный
master
отслеживает удаленную ветку origin/master
- Вы хотите вырезать все свои коммиты из
my-feature-branch
в одно фиксированное ontop текущего состояния origin/master (а не локальный master
, который может быть устаревшим)
- Все ваши изменения зафиксированы, у вас нет неустановленных изменений (они будут потеряны во время
git reset --hard
)
Мой процесс выглядит следующим образом:
-
Извлечь, поэтому origin/master
является текущим:
$ git fetch
-
Отбросьте все коммиты в своей локальной ветке, сбросив его, чтобы указать на origin/master
$ git reset --mixed origin/master
-
Слейте все свои старые изменения из предыдущего состояния вашей ветки в индекс
$ git merge --squash [email protected]{1}
-
Зафиксируйте свои изменения - Git предварительно заполнит ваш редактор сообщением фиксации, содержащим все сообщения фиксации из раздавленных коммитов
Простой псевдоним, о котором я говорил, будет:
alias squash="git fetch; git reset --mixed origin/master; git merge --squash [email protected]{1}"
Ответ 2
Вероятно, лучшим вариантом для этого было бы использовать git merge --squash
во время слияния. Это приведет к тому, что ваш филиал будет развиваться, что довольно часто становится проще в устранении неполадок, поскольку у вас будет некоторое понятие о том, что "я изменял эту специфическую функциональность в commit Z", и, глядя на эту конкретную фиксацию, у вас есть все контекст любых изменений, внесенных вами в несколько файлов, - просмотр одной фиксации, которая представляет собой сжатые результаты вашего пути развития, немного усложняет запоминание. "О, да, мне пришлось изменить эту другую вещь в другом файле, слишком...". У вас также есть преимущество использования git bisect
, когда у вас есть весь доступный путь - все, что он мог сказать вам в раздавленном случае, - "эта огромная фиксация здесь сломала что-то".
Результатом использования git merge --squash
является единая фиксация на ветке, которую вы "объединяете", в которую входят кумулятивные изменения из вашей ветки, но она оставляет только исходную ветвь.
Ответ 3
Найдите хеш для фиксации непосредственно перед тем, как начать ветвь и скопируйте ее в буфер обмена. Затем сделайте reset для этого хэша.
$ git reset [hash]
Затем просто повторно добавьте и повторно зафиксируйте изменения в одном сообщении.
$ git add -A
$ git commit -m 'EVERYTHING SQUASHED'
Ответ 4
Измените конфигурационный файл git ~/.gitconfig
и добавьте следующее в раздел псевдонима
[alias]
squash = "!f(){ CUR=`git rev-parse HEAD` && git reset --soft ${1} && git commit -m \"$(git log --format=%B ${1}..${CUR})\"; };f"
Этот псевдоним получает текущий хеш-код фиксации HEAD, сбрасывается обратно на указанный вами коммит и создает новую фиксацию, сохраняющую все сообщения фиксации.
Использование:
git squash <refspec>
refspec может быть любой допустимой ссылкой фиксации, такой как хеш фиксации, имя ветки, имя тега, HEAD^
HEAD~3
Ответ 5
Я не думаю, что это правильный ответ на этот вопрос.
Но я обычно раздавливаю свою ветку, прежде чем делать запрос Pull для удаленного ведущего мастера, используя следующую команду:
git rebase -i master
Но вам все равно придется выбирать, что выбрать и сквош.
Ответ 6
Лучше всего сделать полный сброс и объединить предыдущую ГОЛОВКУ с сквошем. Вот псевдоним:
[alias]
squash = "!f() { git reset --hard $1; git merge --squash [email protected]{1}; git commit; }; f"
Таким образом, вы можете назвать это так:
git squash master
Или сквош из другой ветки, как у dev
:
git squash dev
Ответ 7
Это идеальный вариант использования для git reset --soft
.
Предположим, у вас есть история коммитов
D Your latest patch
C Your second patch
B Your first patch
A Someone else work
у вас нет поэтапных изменений, и git status
, git log
или git show
сообщают, что вы в настоящее время участвуете в коммите D.
Затем git reset --soft B
возьмет кумулятивные изменения коммитов C
и D
и подготовит их для фиксации. git commit --amend
затем "объединит" эти изменения в коммит B.
Используйте следующее:
git reset --soft B
git commit --amend
Вторая команда откроет ваш редактор с возможностью редактировать сообщение коммита.
Обратите внимание, что если вы подготовили поэтапные изменения до начала этого процесса (т.е. вы сделали git add XXX
, но не выполнили git commit
), то эти поэтапные изменения также будут объединены в коммит.