使当前提交成为Git存储库中的唯一(初始)提交?

kae*_*ese 631 git github git-commit

我目前有一个本地Git存储库,我将其推送到Github存储库.

本地存储库有~10个提交,Github存储库是这个的同步副本.

我想要做的是从本地Git存储库中删除所有版本历史记录,因此存储库的当前内容显示为唯一的提交(因此存储库中的旧版本文件不会存储).

然后,我想将这些更改推送到Github.

我已经调查了Git rebase,但这似乎更适合删除特定版本.另一个可能的解决方案是删除本地仓库,并创建一个新的仓库 - 虽然这可能会创造很多工作!

ETA:有一些未跟踪的特定目录/文件 - 如果可能的话,我想保持这些文件的跟踪.

Fre*_*Foo 950

这是蛮力的方法.它还会删除存储库的配置.

注意:如果存储库有子模块,这不起作用!如果您正在使用子模块,则应使用例如交互式rebase

第1步:删除所有历史记录(确保您有备份,这不能还原)

cat .git/config  # note <github-uri>
rm -rf .git
Run Code Online (Sandbox Code Playgroud)

第2步:仅使用当前内容重建Git仓库

git init
git add .
git commit -m "Initial commit"
Run Code Online (Sandbox Code Playgroud)

第3步:推送到GitHub.

git remote add origin <github-uri>
git push -u --force origin master
Run Code Online (Sandbox Code Playgroud)

  • 之前保存.git/config,然后恢复. (47认同)
  • 如果您尝试删除敏感数据,请小心:在新推送的主分支中只存在一个提交是误导性的 - 历史记录仍然存在**它只是无法从该分支访问.例如,如果您有标记,指向较旧的提交,则可以访问这些提交.事实上,对于任何有点git foo的人,我确信在这个git推送之后,他们仍然能够从GitHub存储库恢复所有历史记录 - 如果你有其他分支或标签,那么他们不会甚至需要很多git foo. (21认同)
  • @kaese:我认为你的`.gitignore`应该处理那些,对吗? (5认同)
  • 谢谢larsmans - 我选择使用它作为我的解决方案.虽然初始化Git repo会丢失旧回购中未跟踪文件的记录,但对于我的问题,这可能是一个更简单的解决方案. (3认同)
  • 世界上有这么多糟糕的答案,一个小时后我终于得到了这个来满足我的要求! (2认同)

小智 575

唯一适合我的解决方案(并保持子模块正常工作)是

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
Run Code Online (Sandbox Code Playgroud)

.git/当我有子模块时,删除总是会导致巨大的问题.使用git rebase --root会以某种方式导致我的冲突(并且需要很长时间,因为我有很多历史).

  • 这应该是正确的答案!只需添加一个`git push -f origin master`作为最后一个操作,太阳将再次闪耀在你的新回购!:) (48认同)
  • 我相信你应该将@JasonGoemaat的建议添加到你答案的最后一行.如果没有`git gc --aggressive --prune all',那么失去历史的整个过程就会被遗漏. (8认同)
  • @JonePolvora git fetch; git reset --hard origin/master http://stackoverflow.com/questions/4785107/git-pull-from-remote-can-i-force-it-to-overwrite-rather-than-report-conflicts (4认同)
  • 这样做后,回购自由空间? (4认同)
  • 这不是旧的提交吗? (2认同)
  • @Brad:我想知道同样的事情.似乎--orphan只获取最后一次提交,以便在删除分支时丢弃剩余的提交.参考:http://git-scm.com/docs/git-checkout (2认同)
  • 这不适用于远程仓库?我使用过脚本,但没有成功.我的.git文件夹仍然很大.我也尝试过@gru和echo的脚本.有什么建议? (2认同)
  • Git会将旧文件保留一段时间,以摆脱它们运行`git gc --aggressive --prune = all`.此外,git将继续存储使用分支或标记引用的任何提交的历史记录.要检查,运行`git tag -l`和`git branch -v`,然后删除你找到的任何内容.还可以使用`git ls-remote`仔细检查您的遥控器,您可能还需要删除远程标签/分支,或者当您获取时,您将再次获得所有链接文件. (2认同)
  • 可以将其重命名为`git branch -m master old_master`,并将push模式设置为current-branch-only`git config --local push.default current`,而不是删除原始_master_分支.通过这种方式,可以将历史提交保存在单独的分支中,并与新主控中的repo同步工作. (2认同)
  • 这是行不通的。我确实收到此错误:git branch -M master -f错误:refname refs / heads / newBranch未找到 (2认同)

dan*_*rth 89

这是我最喜欢的方法:

git branch new_branch_name $(echo "commit message" | git commit-tree HEAD^{tree})
Run Code Online (Sandbox Code Playgroud)

这将创建一个新分支,其中一个提交会在HEAD中添加所有内容.它不会改变任何其他东西,所以它是完全安全的.

  • 最好的办法!清楚,并做好工作.另外,我将分支重命名为"master"到"local-work"和"new_branch_name"到"master".在master中,执行以下操作:git -m local-changes git branch -m local-changes git checkout new_branch_name git branch -m master < (3认同)
  • 查找git引用语法问题答案的权威地点在`git-rev-parse`文档中.这里发生的是`git-commit-tree`需要引用树(repo的快照),但`HEAD`是修订版.要查找与提交相关联的树,我们使用`<rev> ^ {<type>}`形式. (3认同)
  • 所有内容都在一行中: `git Branch newbranch $(echo "commit message" | git commit-tree HEAD^{tree}) | git push --force origin newbranch:master` (3认同)
  • 很好的答案。效果很好。最后说`git push --force &lt;remote&gt; new_branch_name:&lt;remote-branch&gt;` (2认同)

Car*_*arl 31

另一个选项,如果你有很多提交,可能会成为很多工作,是一个交互式rebase(假设你的git版本> = 1.7.12):git rebase --root -i

在编辑器中显示提交列表时:

  • 第一次提交将"pick"更改为"reword"
  • 每次其他提交都将"选择"更改为"fixup"

保存并关闭.Git将开始变基础.

最后,您将拥有一个新的根提交,它是所有提交后的提交的组合.

优点是您不必删除您的存储库,如果您有第二个想法,您总是有一个后备.

如果您确实想要查看历史记录,请将master重置为此提交并删除所有其他分支.


lal*_*rde 18

larsmans提出的方法的变体:

保存未记录文件列表:

git ls-files --others --exclude-standard > /tmp/my_untracked_files
Run Code Online (Sandbox Code Playgroud)

保存你的git配置:

mv .git/config /tmp/
Run Code Online (Sandbox Code Playgroud)

然后执行larsmans的第一步:

rm -rf .git
git init
git add .
Run Code Online (Sandbox Code Playgroud)

恢复配置:

mv /tmp/config .git/
Run Code Online (Sandbox Code Playgroud)

取消您未跟踪的文件:

cat /tmp/my_untracked_files | xargs -0 git rm --cached
Run Code Online (Sandbox Code Playgroud)

然后提交:

git commit -m "Initial commit"
Run Code Online (Sandbox Code Playgroud)

最后推送到您的存储库:

git push -u --force origin master
Run Code Online (Sandbox Code Playgroud)


use*_*651 6

这将删除分支上的历史记录master(您可能需要在运行命令之前进行备份):

git branch tmp_branch $(echo "commit message" | git commit-tree HEAD^{tree})
git checkout tmp_branch
git branch -D master
git branch -m master
git push -f --set-upstream origin master
Run Code Online (Sandbox Code Playgroud)

这是基于@dan_waterworth 的回答。


Mat*_*s M 5

你可以使用浅克隆(git> 1.9):

git clone --depth depth remote-url
Run Code Online (Sandbox Code Playgroud)

进一步阅读:http://blogs.atlassian.com/2014/05/handle-big-repositories-git/

  • 无法将此类克隆推送到新的存储库. (4认同)

And*_*Dev 5

只需删除 Github 存储库并创建一个新的即可。迄今为止最快、最简单、最安全的方法。毕竟,当您想要的只是一次提交的主分支时,在已接受的解决方案中执行所有这些命令您必须获得什么?


Sha*_*mal 5

以下是根据@Zeelot的答案改编而成的脚本。它应该删除所有分支的历史记录,而不仅仅是master分支:

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
Run Code Online (Sandbox Code Playgroud)

它出于我的目的而工作(我不使用子模块)。

  • 我认为您忘了强迫推大师完成该过程。 (4认同)
  • 我必须稍作修改。“ git branch”将在您检出的分支旁边包含一个星号,然后将其选中,使其解析为所有文件或文件夹,就好像它们也是分支名称一样。取而代之的是,我使用了`git branch --format =“%(refname:lstrip = 2)”,它只给了我分支的名字。 (2认同)

归档时间:

查看次数:

227163 次

最近记录:

6 年,5 月 前