本文翻译自:Make the current commit the only (initial) commit in a Git repository?
I currently have a local Git repository, which I push to a Github repository. 我目前有一个本地Git存储库,我将其推送到Github存储库。
The local repository has ~10 commits, and the Github repository is a synchronised duplicate of this. 本地存储库有大约10个提交,而Github存储库是其同步副本。
What I'd like to do is remove ALL the version history from the local Git repository, so the current contents of the repository appear as the only commit (and therefore older versions of files within the repository are not stored). 我想做的是从本地Git存储库中删除所有版本历史记录,因此存储库中的当前内容显示为唯一的提交(因此不会存储存储库中较旧版本的文件)。
I'd then like to push these changes to Github. 然后,我想将这些更改推送到Github。
I have investigated Git rebase, but this appears to be more suited to removing specific versions. 我已经研究了Git变基,但是这似乎更适合删除特定版本。 Another potential solution is to delete the local repo, and create a new one - though this would probably create a lot of work! 另一个可能的解决方案是删除本地存储库,然后创建一个新的存储库-尽管这可能会导致很多工作!
ETA: There are specific directories / files that are untracked - if possible I would like to maintain the untracking of these files. 预计到达时间:有些特定的目录/文件无法跟踪-如果可能的话,我想保持对这些文件的跟踪。
#1楼
参考:https://stackoom.com/question/ed3v/使当前提交成为Git存储库中唯一的-初始-提交
#2楼
The only solution that works for me (and keeps submodules working) is 唯一适用于我(并使子模块保持工作状态)的解决方案是
git checkout --orphan newBranch
git add -A # Add all files and commit them
git commit
git branch -D master # Deletes the master branch
git branch -m master # Rename the current branch to master
git push -f origin master # Force push master branch to github
git gc --aggressive --prune=all # remove the old files
Deleting .git/
always causes huge issues when I have submodules. 当我有子模块时,删除.git/
总是会引起巨大的问题。 Using git rebase --root
would somehow cause conflicts for me (and take long since I had a lot of history). 使用git rebase --root
会以某种方式对我造成冲突(并且自从我有很多历史以来就花了很长时间)。
#3楼
The method below is exactly reproducible, so there's no need to run clone again if both sides were consistent, just run the script on the other side too. 下面的方法是完全可重现的,因此如果双方保持一致,则无需再次运行克隆,也只需在另一端运行脚本即可。
git log -n1 --format=%H >.git/info/grafts
git filter-branch -f
rm .git/info/grafts
If you then want to clean it up, try this script: 如果然后要清理它,请尝试以下脚本:
http://sam.nipl.net/b/git-gc-all-ferocious http://sam.nipl.net/b/git-gc-all-ferocious
I wrote a script which "kills history" for each branch in the repository: 我写了一个脚本,“杀死历史”存储库中的每个分支:
http://sam.nipl.net/b/git-kill-history http://sam.nipl.net/b/git-kill-history
see also: http://sam.nipl.net/b/confirm 另请参阅: http : //sam.nipl.net/b/confirm
#4楼
This is my favoured approach: 这是我最喜欢的方法:
git branch new_branch_name $(echo "commit message" | git commit-tree HEAD^{tree})
This will create a new branch with one commit that adds everything in HEAD. 这将创建一个带有一次提交的新分支,该分支将所有内容添加到HEAD中。 It doesn't alter anything else, so it's completely safe. 它不会改变任何其他内容,因此是完全安全的。
#5楼
To remove the last commit from git, you can simply run 要从git中删除最后一次提交,您只需运行
git reset --hard HEAD^
If you are removing multiple commits from the top, you can run 如果要从顶部删除多个提交,则可以运行
git reset --hard HEAD~2
to remove the last two commits. 删除最后两个提交。 You can increase the number to remove even more commits. 您可以增加数量以删除更多提交。
Git tutoturial here provides help on how to purge repository: 这里的Git tutoturial提供了有关如何清除存储库的帮助:
you want to remove the file from history and add it to the .gitignore to ensure it is not accidentally re-committed. 您要从历史记录中删除文件并将其添加到.gitignore中,以确保不会意外重新提交该文件。 For our examples, we're going to remove Rakefile from the GitHub gem repository. 对于我们的示例,我们将从GitHub gem存储库中删除Rakefile。
git clone https://github.com/defunkt/github-gem.git
cd github-gem
git filter-branch --force --index-filter \
'git rm --cached --ignore-unmatch Rakefile' \
--prune-empty --tag-name-filter cat -- --all
Now that we've erased the file from history, let's ensure that we don't accidentally commit it again. 现在我们已经从历史记录中删除了文件,让我们确保我们不会意外地再次提交它。
echo "Rakefile" >> .gitignore
git add .gitignore
git commit -m "Add Rakefile to .gitignore"
If you're happy with the state of the repository, you need to force-push the changes to overwrite the remote repository. 如果您对存储库的状态感到满意,则需要强制推送更改以覆盖远程存储库。
git push origin master --force
#6楼
git filter-branch
is the major-surgery tool. git filter-branch
是主要手术工具。
git filter-branch --parent-filter true -- @^!
--parent-filter
gets the parents on stdin and should print the rewritten parents on stdout; --parent-filter
在stdin上获取父级,并在stdout上打印重写的父级; unix true
exits successfully and prints nothing, so: no parents. unix true
成功退出并且不打印任何内容,因此:没有父母。 @^!
is Git shorthand for "the head commit but not any of its parents". 是Git的简写,意为 “负责任,但不负责任”。 Then delete all the other refs and push at leisure. 然后删除所有其他参考,并随意进行。