Как убрать первый коммит в git?


179

Мне интересно, как удалить первый коммит в git.

Что такое ревизия, прежде чем совершать какие-либо вещи? У этой ревизии есть имя или тег?


2
Для начала с git, вы должны знать, что пересмотр не имеет смысла. Вы можете говорить о коммитах или их относительных SHA. Кроме того, почему вы хотите это сделать? Первый коммит - это то, на чем все построено. Вы могли бы раздавить несколько коммитов вместе, включая первый коммит, который становится новым первым коммитом, но что значит даже удалить первый коммит (или удалить любой, кроме последнего коммита)?
Шахбаз

@Shahbaz да, это лучший способ, посмотрите здесь, например: ariejan.net/2011/07/05/git-squash-your-latests-commits-into-one
timaschew

5
Вы можете использовать git rebase -i --root. Подробности см. В следующем ответе SO: stackoverflow.com/questions/2246208/…
MKroehnert


Этот ответ имеет правильное решение для удаления корневого коммита текущей ветки:git filter-branch --parent-filter "sed 's/-p <the_commit>//'" HEAD
Jody Bruchon

Ответы:


321

Для меня самый безопасный способ - использовать update-refкоманду:

git update-ref -d HEAD

Он удалит именованную ссылку HEAD, поэтому он сбросит (мягко, вы не потеряете свою работу) все ваши коммиты вашей текущей ветки .

Если вы хотите объединить первый коммит со вторым, вы можете использовать rebaseкоманду:

git rebase -i --root

Последний способ может состоять в том, чтобы создать потерянную ветвь, ветвь с тем же содержимым, но без истории изменений, и зафиксировать в ней новый контент:

git checkout --orphan <new-branch-name>

7
Жаль, что это не принятый ответ. Также очень плохо, что большинство обращений к Google более или менее говорят: «Вы не можете отменить первый коммит». Это помогло мне. Спасибо!
danielpops

1
Спасибо @danielpops за вашу поддержку! Приятно отметить, что я ответил на этот вопрос 3 года спустя. Git тем временем выкинул.
Цзи

Я использовал rebase, пометил второй коммит как "squash", а затем сделал --force push к origin. Спасибо!
Филипп Ац

1
git update-ref -d HEAD - это самый безопасный способ удалить всю историю, а не только первоначальный коммит.
user1767316

Я сделал это, и он удалил все мои файлы, которые я добавил в первый коммит. Печальный. По крайней мере, это было немного
Вячеслав Цивина

42

Перед первым коммитом ничего нет, так как каждый коммит ссылается на родительский коммит. Это делает первый коммит особенным (сиротский коммит), поэтому нет никакого способа сослаться на предыдущее «состояние».

Поэтому, если вы хотите исправить коммит, вы можете просто git commit --amend: это изменит коммит без создания другого.

Если вы просто хотите начать все сначала, удалите .gitрепозиторий и сделайте еще один сgit init


7
Этот ответ неверен: есть способ вернуться в состояние до первого коммита. Смотрите ответ Ци ниже.
Дэвид Нельсон

2
--amendТакже не будет обновлять автор правильно , если он изначально был неправильно настроен. Это то, что мне было нужно, поэтому я использовал принятый ответ, а затем просто сделал новый коммит.
Марк Эдингтон

11
# Check out to a temporary branch:
git checkout --orphan TEMP_BRANCH

# Add all the files:
git add -A

# Commit the changes:
git commit -am "Initial commit"

# Delete the old branch:
git branch -D master

# Rename the temporary branch to master:
git branch -m master

# Finally, force update to our repository:
git push -f origin master

3
Не ответ: вопрос был «как удалить первый коммит», а не «как удалить все, кроме последнего коммита».
Петер - Восстановить Монику

1
Я искал именно это. Спасибо!
Кшиштоф Томашевский

6

Вы можете просто отредактировать свой первый коммит (так как в git-репо всегда есть первый коммит). Попробуйте использовать git commit --amend --reset-authorвместо обычного git commit --amend.


1
Не ответ: вопрос хотел удалить первый коммит, а не изменять свойства последнего.
Петер - Восстановить Монику

@ peterh-ReinstateMonica Для пояснения: коммиты могут быть изменены во время интерактивной перебазировки, чтобы полностью изменить их содержимое, но для смены автора также необходимо указать --reset-author. При этом вы можете полностью заменить первый коммит по своему вкусу. Смотрите также ответ CharlesB.
Макс Бейкирх

3

Я искал способ отменить все git коммиты из репо, как будто их никогда не было.

Ребазинг будет работать до определенного момента. Тем не менее, самый первый (хронологически самый старый git commit) всегда будет проблематичным, так как у него нет родителя, поэтому произойдет ошибка.

Ни один из этих ответов не решил это для меня. Но после долгих поисков и проб и ошибок я обнаружил, что это работает!

git update-ref -d HEAD
git push origin master -f

Надеюсь, это поможет вам. Хорошего дня.


1
Чтобы было понятно всем, кто читает этот ответ: это удаляет каждый коммит, но OP хочет удалить только первый коммит, сделанный в репо; не запускайте это, чтобы удалить первый коммит, потому что он удалит ВСЕ коммиты.
Джоди Брухон

2

Еще один способ сделать это:

  1. Оформить заказ на ветку, которую вы хотите сохранить (скажем, dev) git checkout dev
  2. Теперь удалите ветку, которую хотите сбросить git branch -D master
  3. Теперь создайте пустую ветку с тем же именем git checkout --orphan master

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


3
После этого перед удалением нужно удалить ветку в удаленном режиме. В противном случае при попытке нажатия у вас будет эта ошибка:! [отклонено] master -> master (без ускоренной перемотки вперед) - ошибка: не удалось отправить некоторые ссылки на «git@github.com: r1 / r2.git» - подсказка: обновления были отклонены, поскольку кончик вашей текущей ветви сзади - подсказка: его удаленный аналог. Интегрируйте удаленные изменения (например, подсказку: «git pull ...») перед повторным нажатием ... - Если вы делаете git pull, все коммиты возвращаются.
dxvargas

2

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

cd ..
git init newrepo
cd newrepo
# make some initial commits
git push ../oldrepo master:newmaster

Это создает newmasterветку в старом репозитории с историей, которая не является общей для других ветвей. Конечно, вы можете просто перезаписать master, с git push -f.

Если вы хотите уничтожить все ветви и весь существующий контент, просто запустите

rm -rf .git/

1
Не ответ: OP хотел удалить первый коммит и не запускать новое git-репо с текущим рабочим деревом в качестве начального коммита.
Петер - Восстановить Монику

@peterh Я согласен git rebase --root, вероятно, именно этого хотел OP, но, учитывая, что у этого ответа есть два возражения, я воздержусь от его удаления, если кто-то все еще сочтет его актуальным.
user1338062

Я думаю , что это ответ именно отношение - если вы хотите , чтобы удалить первый совершить в какой - то отрасли, и это только один совершить! (Но вы также хотите сохранить другие коммиты в других ветках; вы также хотите сделать это так, чтобы изменения заканчивались либо в Bitbucket, либо в Github, а не только локально.) Я считаю, что этот ответ - один из способов сделать это, и Я думаю, что это может быть единственный способ сделать это. (Это потому, что, насколько я могу судить, невозможно принудительно протолкнуть локальную ветвь без коммитов через удаленную ветвь с некоторыми
коммитами

0

Если вы только что зафиксировали его, но не нажали, просто удалите каталог .git и git initснова ...


@peterh Да, это так. Вы предполагаете (я думаю), что вопрос ОП заключается в желании удалить первый коммит, но сохранить последующие коммиты. Другая возможность (которая, я думаю, очень хорошо соответствует вопросу ОП - и на которую этот ответ является ответом) заключается в желании удалить первый и единственный коммит из ветви, вернув его обратно в полностью пустое состояние.
MikeBeaton

@MikeBeaton Вы правы. Я удаляю свой комментарий, но затем мне нужно проголосовать, чтобы закрыть вопрос как неясный. Обратите внимание, хотя этот комментарий был сделан только мне, но позади меня 40000 посетителей, и значительная часть из них нашла этот вопрос в Google - и они не получили то, что хотели.
Петер - Восстановить Монику

Это кажется крайним. Удалить вопрос? Разве нельзя (совершенно хорошо) утверждать, что полный ответ на совершенно разумный вопрос заключается в том, что есть два разных подхода, которые необходимо принять, в зависимости от того, ... и т. Д.? (Я имею в виду, я, например, хотел бы знать , как удалить первую фиксацию , когда это не только совершить, а также как удалить первую фиксацию , когда он является единственным совершить. Это, конечно , не очевидно, и , конечно же , завишу на конкретных деталях реализации, что на самом деле оказывается, что в каждом конкретном случае требуются действительно разные подходы.)
MikeBeaton

0

Ответ на вопрос зависит от того:

  • Вы хотите удалить первый И ТОЛЬКО коммит на ветке (оставив другие ветви такими, какими они были), или

  • Вы хотите удалить первый коммит в некоторой ветви, в то время как «оставляя на месте» последующие коммиты (и другие ветви).

Второй из них относительно проще. По сути, вам необходимо выполнить ребазинг - большинство ответов здесь о том, как это сделать.

Выполнение второго (удаление первого и единственного коммита из ветви с одновременным оставлением других ветвей) сложнее. Или, по крайней мере, особенно сложнее, если вы хотите, чтобы это произошло и чтобы изменения отразились обратно в GitHub или Bitbucket. Насколько я могу судить, в Git нет никакого способа толкать или принудительно толкать ветку без коммитов. И, опять же, насколько я понимаю, нет никакого способа создать новую пустую ветку без коммитов в GitHub или Bitbucket. Таким образом, вам по сути нужно создать новый репозиторий, чтобы создать полностью пустую ветвь, а затем добавить обратно те ветки, которые вы хотите (включая коммиты, которые вы хотите) - согласно ответу @ user1338062.

Поэтому я надеюсь, что этот ответ проясняет то, что, возможно, не было очевидным - что необходимо использовать два разных подхода для двух разных (более или менее разумных) сценариев, которые обе вещи, которые вы, возможно, захотите сделать, чтобы чтобы полностью освоить делать то, что просит ОП.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.