使当前提交成为 Git 存储库中唯一的(初始)提交?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9683279/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Make the current commit the only (initial) commit in a Git repository?
提问by kaese
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. Another potential solution is to delete the local repo, and create a new one - though this would probably create a lot of work!
我已经调查过 Git rebase,但这似乎更适合删除特定版本。另一种可能的解决方案是删除本地存储库,然后创建一个新存储库 - 尽管这可能会产生大量工作!
ETA: There are specific directories / files that are untracked - if possible I would like to maintain the untracking of these files.
ETA:有未跟踪的特定目录/文件 - 如果可能,我想保持对这些文件的未跟踪。
回答by Fred Foo
Here's the brute-force approach. It also removes the configuration of the repository.
这是蛮力方法。它还删除了存储库的配置。
Note: This does NOT work if the repository has submodules! If you are using submodules, you should use e.g. interactive rebase
注意:如果存储库有子模块,这将不起作用!如果您使用子模块,则应该使用例如交互式变基
Step 1: remove all history (Make sure you have backup, this cannot be reverted)
第 1 步:删除所有历史记录(确保您有备份,无法恢复)
cat .git/config # note <github-uri>
rm -rf .git
Step 2: reconstruct the Git repo with only the current content
第 2 步:仅使用当前内容重建 Git 存储库
git init
git add .
git commit -m "Initial commit"
Step 3: push to GitHub.
第 3 步:推送到 GitHub。
git remote add origin <github-uri>
git push -u --force origin master
回答by Zeelot
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.
Using git rebase --root
would somehow cause conflicts for me (and take long since I had a lot of history).
.git/
当我有子模块时,删除总是会导致巨大的问题。使用git rebase --root
会以某种方式对我造成冲突(并且因为我有很多历史而需要很长时间)。
回答by dan_waterworth
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. It doesn't alter anything else, so it's completely safe.
这将创建一个带有一次提交的新分支,将所有内容添加到 HEAD 中。它不会改变任何其他东西,所以它是完全安全的。
回答by Carl
The other option, which could turn out to be a lot of work if you have a lot of commits, is an interactive rebase (assuming your git version is >=1.7.12):git rebase --root -i
另一个选项,如果你有很多提交,可能需要做很多工作,它是交互式 rebase(假设你的 git 版本 >=1.7.12):git rebase --root -i
When presented with a list of commits in your editor:
当在您的编辑器中显示提交列表时:
- Change "pick" to "reword" for the first commit
- Change "pick" to "fixup" every other commit
- 第一次提交时将“pick”更改为“reword”
- 每隔一次提交将“pick”更改为“fixup”
Save and close. Git will start rebasing.
保存并关闭。Git 将开始变基。
At the end you would have a new root commit that is a combination of all the ones that came after it.
最后,您将有一个新的根提交,它是它之后的所有提交的组合。
The advantage is that you don't have to delete your repository and if you have second thoughts you always have a fallback.
优点是你不必删除你的存储库,如果你有第二个想法,你总是有一个后备。
If you really do want to nuke your history, reset master to this commit and delete all other branches.
如果您真的想修改历史记录,请将 master 重置为此提交并删除所有其他分支。
回答by lalebarde
Variant of larsmans's proposed method:
larsmans提出的方法的变体:
Save your untrackfiles list:
保存您的 untrackfiles 列表:
git ls-files --others --exclude-standard > /tmp/my_untracked_files
Save your git configuration:
保存您的 git 配置:
mv .git/config /tmp/
Then perform larsmans's first steps:
然后执行 larsmans 的第一步:
rm -rf .git
git init
git add .
Restore your config:
恢复你的配置:
mv /tmp/config .git/
Untrack you untracked files:
取消跟踪您未跟踪的文件:
cat /tmp/my_untracked_files | xargs -0 git rm --cached
Then commit:
然后提交:
git commit -m "Initial commit"
And finally push to your repository:
最后推送到您的存储库:
git push -u --force origin master
回答by Shafique Jamal
Below is a script adapted from @Zeelot 's answer. It should remove the history from all branches, not just the master branch:
以下是改编自 @Zeelot 答案的脚本。它应该从所有分支中删除历史记录,而不仅仅是主分支:
for BR in $(git branch); do
git checkout $BR
git checkout --orphan ${BR}_temp
git commit -m "Initial commit"
git branch -D $BR
git branch -m $BR
done;
git gc --aggressive --prune=all
It worked for my purposes (I am not using submodules).
它适用于我的目的(我没有使用子模块)。
回答by Matthias M
You could use shallow clones(git > 1.9):
您可以使用浅克隆(git > 1.9):
git clone --depth depth remote-url
Further reading: http://blogs.atlassian.com/2014/05/handle-big-repositories-git/
进一步阅读:http: //blogs.atlassian.com/2014/05/handle-big-repositories-git/
回答by jthill
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; unix true
exits successfully and prints nothing, so: no parents. @^!
is Git shorthand for"the head commit but not any of its parents". Then delete all the other refs and push at leisure.
--parent-filter
在标准输入上获取父母,并应该在标准输出上打印重写的父母;unixtrue
成功退出并且什么也不打印,所以:没有父母。 @^!
是Git 的“头部提交但不是其任何父母”的简写。然后删除所有其他参考并在闲暇时推送。
回答by AndroidDev
Just delete the Github repo and create a new one. By far the fastest, easiest and safest approach. After all, what do you have to gain carrying out all those commands in the accepted solution when all you want is the master branch with a single commit?
只需删除 Github 存储库并创建一个新存储库即可。迄今为止最快、最简单和最安全的方法。毕竟,当您想要的只是具有单个提交的主分支时,您在已接受的解决方案中执行所有这些命令有什么好处?
回答by AnoE
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 存储库中删除所有版本历史记录,因此存储库的当前内容显示为唯一提交(因此不存储存储库中旧版本的文件)。
A more conceptual answer:
一个更概念化的答案:
git automatically garbage collects old commits if no tags/branches/refs point to them. So you simply have to remove all tags/branches and create a new orphan commit, associated with any branch - by convention you would let the branch master
point to that commit.
如果没有标签/分支/引用指向它们,git 会自动垃圾收集旧提交。所以你只需要删除所有标签/分支并创建一个新的孤立提交,与任何分支相关联 - 按照惯例,你会让分支master
指向该提交。
The old, unreachable commits will then never again be seen by anyone unless they go digging with low-level git commands. If that is enough for you, I would just stop there and let the automatic GC do it's job whenever it wishes to. If you want to get rid of them right away, you can use git gc
(possibly with --aggressive --prune=all
). For the remote git repository, there's no way for you to force that though, unless you have shell access to their file system.
旧的、无法访问的提交将再也不会被任何人看到,除非他们使用低级 git 命令进行挖掘。如果这对你来说足够了,我会停在那里,让自动 GC 随时完成它的工作。如果您想立即摆脱它们,您可以使用git gc
(可能与--aggressive --prune=all
)。对于远程 git 存储库,您无法强制执行此操作,除非您具有对其文件系统的 shell 访问权限。