如何删除git中的第一次提交?


179

我很好奇如何删除git中的第一次提交。

提交任何内容之前的修订版本是什么?此修订版是否有名称或标签?


2
首先,您应该知道修订是没有意义的。您可以谈论提交或其相对的SHA。另外,您为什么要这样做?第一次提交就是一切的基础。您可以将一些提交压缩在一起,包括第一次提交,它将成为新的第一次提交,但是什至删除第一次提交(或删除除最后一次提交以外的任何内容)又意味着什么呢?
Shahbaz 2012年

@Shahbaz是的,那是最好的方法,例如,请看这里:ariejan.net/2011/07/05/git-squash-your-latests-commits-into-one
timaschew 2012年

5
您可以使用git rebase -i --root。请参阅下面的SO答案细节:stackoverflow.com/questions/2246208/...
MKroehnert


此答案具有删除当前分支的根提交的正确解决方案:git filter-branch --parent-filter "sed 's/-p <the_commit>//'" HEAD
Jody Bruchon

Answers:


320

对我来说,最安全的方法是使用以下update-ref命令:

git update-ref -d HEAD

它将删除命名的引用HEAD,因此它将重置(轻轻地,您不会丢失您的工作)对当前分支的所有提交

如果要合并第一个提交和第二个提交,可以使用以下rebase命令:

git rebase -i --root

最后一种方法是创建一个孤立分支,该分支具有相同的内容但没有任何提交历史记录,并在其上提交新内容:

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

7
很遗憾,这不是公认的答案。太糟糕了,以至于Google上的大多数点击或多或少都说“您不能撤消第一次提交”。这对我有用。谢谢!
danielpops

1
感谢@danielpops的支持!很高兴看到三年后我回答了这个问题。与此同时,Git不断发展。
tzi 2016年

我使用了rebase,将第二次提交标记为“ squash”,然后执行了--force推入原点操作。谢谢!
菲利普·阿兹

1
git update-ref -d HEAD是删除所有历史记录的最安全的方法,而不仅仅是初始提交。
user1767316

我做到了,它删除了我添加到第一次提交中的所有文件。伤心。至少不是很多
Vyacheslav Tsivina

42

第一次提交之前没有任何内容,因为每个提交都引用父提交。这使得第一次提交变得特别(孤立提交),因此无法引用先前的“状态”。

因此,如果您要修复提交,可以简单地进行以下操作git commit --amend:这将修改提交而不创建另一个提交。

如果您只想重新开始,请删除.git存储库,然后使用git init


7
这个答案是不正确的:有一种方法可以还原到第一次提交之前的状态。请参阅下面的tzi答案
David Nelson

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
没有答案:问题是“如何删除第一次提交”,而不是“如何删除除最后一次提交以外的所有内容”。
peterh-恢复莫妮卡

1
我正是在寻找这个。谢谢!
Krzysztof Tomaszewski

6

您可能只想编辑第一次提交(因为git repo中总是存在第一次提交)。考虑使用git commit --amend --reset-author代替通常的git commit --amend


1
不是答案:问题是要删除第一个提交,而不是修改最后一个提交的属性。
彼得-恢复莫妮卡

@ peterh-ReinstateMonica为澄清起见:可以在交互式rebase过程中修改提交以完全更改其内容,但是也需要提供--reset-author来更改作者。这样,您就可以完全替换自己喜欢的第一次提交。另请参阅CharlesB的答案。
Max Beikirch

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 repo。
彼得-恢复莫妮卡

@peterh我同意git rebase --root这可能是OP想要的,但是考虑到这个答案有两个反对意见,如果有人仍然认为它有意义,我将避免删除它。
user1338062

我认为这个答案是完全相关的-如果您要删除某个分支中的第一个提交,只有一个提交!(但是您还希望将其他提交保留在其他分支中;并且您也想这样做,以便更改最终可以在Bitbucket或Github中进行,而不仅仅是在本地。)我认为这可能是这样做的唯一方法。(这是因为-就我所知-没有办法强制将没有提交的本地分支推向有提交的远程分支。)
MikeBeaton

0

如果您刚刚提交但未推送,则只需删除.git目录,然后git init再次...


@peterh是的。您假设(我认为)OP的问题是关于要删除第一个提交但保留后续的提交。另一种可能性(我认为这完全符合OP的问题-该答案是对此的答案)想要删除分支中的第一个也是唯一的提交,然后再次将其还原为完全空。
MikeBeaton '19

@MikeBeaton你是对的。我删除了我的评论,但由于不清楚,我需要投票结束该问题。请注意,尽管只有我对此发表评论,但是在我身后有40000位访问者,其中很大一部分人通过google找到了这个问题-他们没有得到他们想要的东西。
peterh-恢复莫妮卡

那似乎是极端的。删除问题?是否可以(完全正确地)争论一个完全合理的问题的完整答案是,根据是否……等,需要采用两种不同的方法?(我的意思是,我有一个,想知道如何删除第一次提交时,它不是唯一的承诺,以及如何删除时,它的第一个承诺唯一的承诺。这当然并不明显,当然也要看有关具体实施细节的信息,事实证明每种情况下确实需要非常不同的方法。)
MikeBeaton,

0

问题的答案取决于是否:

  • 您想删除分支上的第一个且仅提交(仅保留其他分支不变),或者是否要删除

  • 您想删除某个分支上的第一个提交,同时“保留”后续的提交(和其他分支)。

第二个相对简单。从本质上讲,您必须扎根-此处的大多数答案都是关于执行此操作的方法。

要执行第二个操作(从一个分支中删除第一个也是唯一的提交,而让其他分支保持单独状态)则比较困难。或者,至少,如果您希望它发生并且使更改反映回GitHub或Bitbucket,则尤其困难。(据我所知)Git中根本没有办法推送或强制推送没有提交的分支。而且(据我所知)也完全没有办法在GitHub或Bitbucket中创建一个没有提交的新的空分支。因此,您基本上必须创建一个新的存储库才能创建一个完全空的分支,然后按照@ user1338062的答案重新添加所需的分支(包括所需的提交)。

因此,我希望这个答案能弄清楚可能不是很明显的东西-对于两种不同(或多或少合理)的场景,需要采取两种不同的方法,这两种方法都是您可能想做的,以便完全掌握OP的要求。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.