Как вы сократите весь свой репозиторий до первого коммита?
Я могу вернуться к первому коммиту, но это оставило бы меня с 2 коммитами. Есть ли способ ссылаться на коммит до первого?
git
rebase
git-rebase
squash
git-rewrite-history
Verhogen
источник
источник
--root
на самом деле не лучшее решение для сжатия всех коммитов, если их много для сквоша): Объединить первые два коммита Git-репозитория? ,Ответы:
Возможно, самый простой способ - это просто создать новый репозиторий с текущим состоянием рабочей копии. Если вы хотите сохранить все сообщения о коммитах, которые вы могли бы сначала сделать,
git log > original.log
а затем отредактировать их для своего исходного сообщения о коммите в новом хранилище:или
источник
git rebase -i --root
. См .: stackoverflow.com/a/9254257/109618Начиная с git 1.6.2 , вы можете использовать
git rebase --root -i
.Для каждого коммита, кроме первого, измените
pick
наsquash
.источник
squash
для всех коммитов . Самый первый должен бытьpick
.Обновить
Я сделал псевдоним
git squash-all
.Пример использования :
git squash-all "a brand new start"
.Предостережение : не забудьте предоставить комментарий, в противном случае будет использоваться сообщение о фиксации по умолчанию «Новое начало».
Или вы можете создать псевдоним с помощью следующей команды:
Один лайнер
Примечание : здесь "
A new start
" это просто пример, не стесняйтесь использовать свой собственный язык.TL; DR
Не нужно раздавливать, использовать
git commit-tree
для создания коммитов сирот и идти с ним.объяснять
создать один коммит через
git commit-tree
Что
git commit-tree HEAD^{tree} -m "A new start"
это такое:Выражение
HEAD^{tree}
означает соответствующий объект дереваHEAD
, а именно кончик вашей текущей ветви. см. Tree-Objects и Commit-Objects .сбросить текущую ветку на новый коммит
Затем
git reset
просто сбросьте текущую ветку на вновь созданный объект коммита.Таким образом, ничего в рабочей области не затрагивается, и нет необходимости в ребазе / сквоше, что делает его действительно быстрым. И необходимое время не зависит от размера хранилища или глубины истории.
Вариация: новый репо из шаблона проекта
Это полезно для создания «начального коммита» в новом проекте с использованием другого хранилища в качестве шаблона / архетипа / семени / скелета. Например:
Это позволяет избежать добавления репо-шаблона в качестве удаленного (
origin
или иного) и сворачивает историю репо-шаблона в исходную фиксацию.источник
git push -f
для распространения.git clone
. Если добавить--hard
кgit reset
и переключательHEAD
сFETCH_HEAD
вgit commit-tree
вы можете создать первоначальное обязательство после загрузки шаблона репо. Я отредактировал ответ с разделом в конце, демонстрирующим это.${1?Please enter a message}
Если все, что вы хотите сделать, это сжать все ваши коммиты до корневого коммита, тогда
может работать, это нецелесообразно для большого количества коммитов (например, сотен коммитов), потому что операция rebase, вероятно, будет выполняться очень медленно, чтобы сгенерировать список коммитов редактора rebase редактора, а также запустить сам rebase.
Вот два более быстрых и эффективных решения, когда вы подавляете большое количество коммитов:
Альтернативное решение № 1: сиротские ветви
Вы можете просто создать новую потерянную ветку на кончике (то есть самой последней фиксации) вашей текущей ветки. Эта сиротская ветвь формирует начальный корневой коммит совершенно нового и отдельного дерева истории коммитов, которое фактически эквивалентно уничтожению всех ваших коммитов:
Документация:
Альтернативное решение № 2: мягкий сброс
Другое эффективное решение - просто использовать смешанный или программный сброс в корневой коммит
<root>
:Документация:
источник
git push origin master --force
.git push --force
Это создаст потерянный коммит с деревом HEAD и выведет его имя (SHA-1) на стандартный вывод. Тогда просто перезагрузите свою ветку там.
источник
git reset $(git commit-tree HEAD^{tree} -m "commit message")
сделает это проще.echo "message" | git commit-tree "HEAD^{tree}"
Вот как я это сделал, на случай, если это сработает для кого-то другого:
Помните, что всегда есть риск сделать что-то подобное, и никогда не плохая идея создать ветку сохранения перед запуском.
Начните с входа
Выделите первый коммит, скопируйте SHA
Заменить
<#sha#>
с SHA, скопированной из журналаУбедитесь, что все зеленое, иначе бегите
git add -A
Изменить все текущие изменения в текущем первом коммите
Теперь принудительно нажмите эту ветку, и она перезапишет то, что там.
источник
Я читал кое-что об использовании трансплантатов, но никогда не исследовал это много.
В любом случае, вы можете раздавить последние 2 коммита вручную примерно так:
источник
Самый простой способ - использовать команду «сантехника»
update-ref
для удаления текущей ветви.Вы не можете использовать,
git branch -D
поскольку он имеет предохранительный клапан, чтобы остановить удаление текущей ветви.Это вернет вас в состояние «начальная фиксация», где вы можете начать с новой первоначальной фиксации.
источник
Во-первых, раздавите все ваши коммиты в один коммит, используя
git rebase --interactive
. Теперь у вас осталось два коммита для сквоша. Для этого прочитайте любой изисточник
В одной строке 6 слов
источник
git help checkout
о--orphan
git help checkout --orphan
создать резервную копию
сброс до указанного коммита
затем добавьте все файлы в постановку
совершить без обновления сообщения
протолкнуть новую ветку с раздавленными коммитами в репо
источник
<root>
коммитом, к которому вы вернетесь.git commit --amend --no-edit
передаст все изменения в текущий коммит, который<root>
не требует редактирования сообщения коммита.Сквош, используя трансплантаты
Добавьте файл
.git/info/grafts
, поместите туда хеш коммита, который вы хотите использовать в качестве корняgit log
Теперь начнем с этого коммитаЧтобы сделать это «настоящий» бег
git filter-branch
источник
Этот ответ улучшен на пару выше (пожалуйста, проголосуйте за них), предполагая, что в дополнение к созданию одного коммита (без истории без истории), вы также хотите сохранить все данные фиксации этого коммита:
Конечно, коммит-SHA нового / одиночного коммита изменится, потому что он представляет новую (не) историю, становясь бездетным / корневым коммитом.
Это можно сделать, прочитав
git log
и установив некоторые переменные дляgit commit-tree
. Предполагая, что вы хотите создать один коммитmaster
в новой веткеone-commit
, сохраняя данные коммита выше:источник
Я обычно делаю это так:
Убедитесь, что все зафиксировано, и запишите последний идентификатор фиксации на случай, если что-то пойдет не так, или создайте отдельную ветку в качестве резервной копии.
Запустите,
git reset --soft `git rev-list --max-parents=0 --abbrev-commit HEAD`
чтобы сбросить голову на первый коммит, но оставьте свой индекс без изменений. Все изменения, произошедшие после первой фиксации, теперь будут готовы к фиксации.Запустите,
git commit --amend -m "initial commit"
чтобы изменить ваш коммит на первый коммит и изменить сообщение коммита, или, если вы хотите сохранить существующее сообщение коммита, вы можете запуститьgit commit --amend --no-edit
Беги,
git push -f
чтобы форсировать твои измененияисточник
Для этого вы можете сбросить свой локальный git-репозиторий на хэштег первой фиксации, поэтому все ваши изменения после этой фиксации будут неустановленными, а затем вы можете зафиксировать их с параметром --amend.
А затем отредактируйте первый коммит, если необходимо, и сохраните файл.
источник
Для меня это работало так: у меня было всего 4 коммита, и я использовал интерактивный ребаз:
Самый первый коммит остается, и я взял 3 последних коммита.
Если вы застряли в редакторе, который появляется рядом, вы видите что-то вроде:
Вы должны взять первый коммит и раздавить других на него. То, что вы должны иметь, это:
Для этого используйте клавишу INSERT, чтобы изменить режим «вставки» и «редактирования».
Для сохранения и выхода из редактора используйте
:wq
. Если ваш курсор находится между этими строками фиксации или где-то еще, нажмите ESC и попробуйте снова.В результате у меня было два коммита: самый первый, который остался, и второй с сообщением «Это комбинация из 3 коммитов».
Проверьте подробности здесь: https://makandracards.com/makandra/527-squash-several-git-commits-into-a-single-commit
источник