首页 文章

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

提问于
浏览
551

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

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

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

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

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

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

12 回答

  • -1

    为此使用Shallow Clone命令git clone --depth 1 URL - 它将只克隆存储库的当前HEAD

  • 856

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

    Note :如果存储库有子模块,这不起作用!如果您正在使用子模块,则应使用例如interactive rebase

    第1步:删除所有历史记录( Make sure you have backup, this cannot be reverted

    rm -rf .git
    

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

    git init
    git add .
    git commit -m "Initial commit"
    

    第3步:推送到GitHub .

    git remote add origin <github-uri>
    git push -u --force origin master
    
  • -1

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

    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
    

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

  • 1

    这是我最喜欢的方法:

    git branch new_branch_name $(echo "commit message" | git commit-tree HEAD^{tree})
    

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

  • 30

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

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

    • 将"pick"更改为"reword"进行第一次提交

    • 将"pick"更改为"fixup"每隔一次提交

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

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

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

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

  • 17

    larsmans提出的方法的变体:

    保存未记录文件列表:

    git ls-files --others --exclude-standard > /tmp/my_untracked_files
    

    保存你的git配置:

    mv .git/config /tmp/
    

    然后执行larsmans的第一步:

    rm -rf .git
    git init
    git add .
    

    恢复配置:

    mv /tmp/config .git/
    

    取消您未跟踪的文件:

    cat /tmp/my_untracked_files | xargs -0 git rm --cached
    

    然后提交:

    git commit -m "Initial commit"
    

    最后推送到您的存储库:

    git push -u --force origin master
    
  • 5

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

    git clone --depth depth remote-url
    

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

  • 2

    下面的方法是完全可重现的,因此如果双方都一致,则无需再次运行clone,只需在另一侧运行脚本 .

    git log -n1 --format=%H >.git/info/grafts
    git filter-branch -f
    rm .git/info/grafts
    

    如果您想要清理它,请尝试以下脚本:

    http://sam.nipl.net/b/git-gc-all-ferocious

    我为存储库中的每个分支编写了一个“杀死历史记录”的脚本:

    http://sam.nipl.net/b/git-kill-history

    另见:http://sam.nipl.net/b/confirm

  • 482
    git for-each-ref --format='git update-ref -d %(refname)' \
            refs/{heads,tags} | sh -x
    current=$(git commit-tree -m 'Initial commit' `git write-tree`)
    git update-ref -m 'Initial commit' `git symbolic-ref HEAD` $current
    

    这将删除所有本地分支和标记,使用当前结帐的状态进行单个无历史提交,无论当前分支是什么,并保留有关您的repo的其他所有信息 . 然后,您可以根据需要强制推送到遥控器 .

  • 72

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

    一个更概念性的答案:

    如果没有标签/分支/ refs指向它们,git会自动垃圾收集旧提交 . 因此,您只需删除所有标记/分支并创建与任何分支关联的新孤立提交 - 按照惯例,您可以让分支 master 指向该提交 .

    除非他们使用低级git命令进行挖掘,否则任何人都不会再看到旧的,无法访问的提交 . 如果这对你来说已经足够了,我会停在那里让自动GC随时随地完成它的工作 . 如果你想立即摆脱它们,可以使用 git gc (可能使用 --aggressive --prune=all ) . 对于远程git存储库,除非您具有对其文件系统的shell访问权限,否则您无法强制执行此操作 .

  • -1

    要从git中删除最后一次提交,您只需运行即可

    git reset --hard HEAD^
    

    如果要从顶部删除多个提交,则可以运行

    git reset --hard HEAD~2
    

    删除最后两次提交 . 您可以增加数量以删除更多提交 .

    More info here.

    Git tutoturial here提供了有关如何清除存储库的帮助:

    您要从历史记录中删除该文件并将其添加到.gitignore以确保不会意外重新提交 . 对于我们的示例,我们将从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
    

    既然我们已经从历史记录中删除了该文件,那么我们确保不会意外地再次提交它 .

    echo "Rakefile" >> .gitignore
    
    git add .gitignore
    
    git commit -m "Add Rakefile to .gitignore"
    

    如果您对存储库的状态感到满意,则需要强制推送更改以覆盖远程存储库 .

    git push origin master --force
    
  • 0

    我通过从项目中删除 .git 文件夹并通过IntelliJ重新集成版本控制来解决类似的问题 . 注意:隐藏了 .git 文件夹 . 您可以使用 ls -a 在终端中查看它,然后使用 rm -rf .git 将其删除 .

相关问题