Git: Как отменить все коммиты в ветке master?

Я ищу способ объединить все коммиты git в одну большую фиксацию в ветке master. Я полностью понимаю последствия того, что я пытаюсь сделать, не нужно объяснять, что это опасно или что это неправильный путь - я хочу потерять всю свою историю и превратить этот репозиторий в один большой коммит.

Основная проблема: у меня нет других живых веток, нет локальных коммитов, а все предыдущие коммиты уже были отправлены на удаленный master.

Также приветствуются хакерские скрипты.


git
person milosmns    schedule 24.03.2019    source источник
comment
Первое, что приходит в голову: git rebase -i <first-commit-hash>. Затем используйте функцию замены запроса вашего редактора, чтобы заменить все pick на squash и сохранить. Потом git push --force.   -  person JB Nizet    schedule 24.03.2019
comment
stackoverflow.com/search?q=%5Bgit%5D+squash+all+commits   -  person phd    schedule 24.03.2019
comment
Хм, есть много решений, так что это, не уверен, какое из них правильное   -  person milosmns    schedule 25.03.2019


Ответы (2)


Я бы использовал git reset --soft

git reset --soft id-of-first-revision-of-master
git commit --amend -m "single commit for master"

Затем вы можете нажать --force везде, где вам нужна эта новая ветка.

Обновлять

Я могу придумать другой простой способ сделать это с большим количеством команд git:

git checkout --orphan some-branch
git commit -m "First commit"
git branch -f master # move the local branch
git checkout master
git branch -d some-branch # delete the temp branch

Это также можно было бы сделать так, более хакерским способом:

git commit-tree -m "First commit" HEAD^{tree}

Это напишет ревизию .... если вы ее проверите, у вас будет единственная ревизия, содержимое будет точно таким же, как и там, где вы стояли раньше ... не стесняйтесь перемещать локальную ветвь (как объяснено в предыдущий рецепт)

person eftshift0    schedule 24.03.2019
comment
это сделало мой день - person hafizhanindito; 26.05.2020
comment
@ eftshift0 команда git git checkout --orphan -b some-branch вызывает ошибку fatal: 'some-branch' is not a commit and a branch '-b' cannot be created from it. Вы действительно имели в виду git checkout --orphan some-branch? - person Boris; 25.03.2021
comment
может иметь смысл без -b. Я имею в виду, если вы проверяете --orphan, то это новая ветка, верно? Тогда указывать -b не нужно. Возможно, это логика. - person eftshift0; 25.03.2021

Вы все еще можете изменить историю восходящего потока, используя git push --force-with-lease. Однако вы должны осознавать последствия.

Использование git push --force создаст параллельное дерево в вашем апстриме, поэтому все разработчики могут потеряться в устаревшей ветке.

Чтобы раздавить свою историю, просто сделайте:

git rebase -i HEAD~10

Где 10 - это количество + 1 коммитов, которые вы хотите объединить. Если вы хотите уничтожить все коммиты, просто укажите свой <first-commit-hash> вместо HEAD~10. Затем в редакторе вы выбираете squash для всех коммитов, которые хотите сгруппировать. Вы можете выполнить поиск / замену: pick на squash

После этого просто внесите свои изменения:

git push --force-with-lease

Я бы никогда не рекомендовал делать --force, потому что, если другой разработчик тем временем отправил фиксацию, вы удалите ее ход. Использование --force-with-lease Git не позволит вам нажимать, если кто-то другой нажал на ваше последнее изменение (см. вопрос для более подробной информации).

person nowox    schedule 24.03.2019
comment
Я считаю, что вместо использования <first-commit-hash> вы можете использовать git rebase -i --root для перебазирования всего пути до начальной фиксации - person Ru Chern Chong; 24.03.2019
comment
Параметр --root помогает мне. Решение с HEAD~number или хешем первой фиксации у меня не работает - они заканчиваются двумя фиксациями, а не единственной. - person eNca; 18.10.2020