799

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

本地存储库有大约 10 个提交,Github 存储库是它的同步副本。

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

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

我调查了 Git rebase,但这似乎更适合删除特定版本。另一个可能的解决方案是删除本地 repo,然后创建一个新的——尽管这可能会产生很多工作!

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

4

18 回答 18

1086

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

注意:如果存储库有子模块,这将不起作用!如果你正在使用子模块,你应该使用例如交互式变基

第1步:删除所有历史记录(确保您有备份,这无法恢复

cat .git/config  # note <github-uri>
rm -rf .git

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

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

第三步:推送到 GitHub。

git remote add origin <github-uri>
git push -u --force origin master
于 2012-03-13T11:44:55.310 回答
750

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

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会以某种方式对我造成冲突(并且需要很长时间,因为我有很多历史)。

于 2012-10-27T18:16:44.770 回答
113

这是我最喜欢的方法:

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

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

于 2013-03-22T13:53:36.633 回答
36

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

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

  • 将第一次提交的“pick”更改为“reword”
  • 每隔一次提交将“pick”更改为“fixup”

保存并关闭。Git 将开始变基。

最后,您将获得一个新的根提交,它是其后所有提交的组合。

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

如果你真的想删除你的历史记录,请将 master 重置为此提交并删除所有其他分支。

于 2012-03-14T20:24:09.287 回答
21

larsmans提出的方法的变体:

保存您的 untrackfiles 列表:

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
于 2014-04-19T08:58:18.553 回答
7

以下是改编自@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

它适用于我的目的(我没有使用子模块)。

于 2019-02-12T05:28:22.963 回答
7

删除该.git 文件夹可能会导致您的 git 存储库出现问题。如果您想删除所有提交历史记录但将代码保持在其当前状态,则按照以下方式执行此操作非常安全:

  1. 查看

    git checkout --orphan latest_branch

  2. 添加所有文件

    git add -A

  3. 提交更改

    git commit -am "commit message"

  4. 删除分支

    git branch -D master

  5. 将当前分支重命名为 master

    git branch -m master

  6. 最后,强制更新您的存储库

    git push -f origin master

PS:这不会保留您的旧提交历史记录

于 2021-02-07T18:37:52.703 回答
5

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

git clone --depth depth remote-url

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

于 2016-04-04T11:05:15.437 回答
4

git filter-branch是大手术的工具。

git filter-branch --parent-filter true -- @^!

--parent-filter在标准输入上获取父母,并在标准输出上打印重写的父母;unixtrue成功退出并且什么也不打印,所以:没有父母。 @^!Git 的“head commit but not any of its parents”的简写。然后删除所有其他 refs 并在闲暇时推送。

于 2014-04-05T01:42:16.110 回答
4

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

一个更具概念性的答案:

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

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

于 2016-04-04T11:27:13.633 回答
4

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

于 2018-12-31T18:31:24.250 回答
3

以下是清除 Github 存储库历史记录的步骤

首先,从 .git 中删除历史记录

rm -rf .git

现在,仅从当前内容重新创建 git repos

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

推送到 Github 远程仓库,确保您覆盖历史记录


git remote add origin git@github.com:<YOUR ACCOUNT>/<YOUR REPOS>.git
git push -u --force origin master
于 2021-03-19T15:36:54.453 回答
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

于 2013-02-06T16:46:42.177 回答
2

这将删除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

这是基于@dan_waterworth 的回答。

于 2020-09-28T16:58:07.920 回答
1

干得好:

#!/bin/bash
#
# By Zibri (2019)
#
# Usage: gitclean username password giturl
#
gitclean () 
{ 
    odir=$PWD;
    if [ "$#" -ne 3 ]; then
        echo "Usage: gitclean username password giturl";
        return 1;
    fi;
    temp=$(mktemp -d 2>/dev/null /dev/shm/git.XXX || mktemp -d 2>/dev/null /tmp/git.XXX);
    cd "$temp";
    url=$(echo "$3" |sed -e "s/[^/]*\/\/\([^@]*@\)\?\.*/\1/");
    git clone "https://$1:$2@$url" && { 
        cd *;
        for BR in "$(git branch|tr " " "\n"|grep -v '*')";
        do
            echo working on branch $BR;
            git checkout $BR;
            git checkout --orphan $(basename "$temp"|tr -d .);
            git add -A;
            git commit -m "Initial Commit" && { 
                git branch -D $BR;
                git branch -m $BR;
                git push -f origin $BR;
                git gc --aggressive --prune=all
            };
        done
    };
    cd $odir;
    rm -rf "$temp"
}

也在这里托管:https ://gist.github.com/Zibri/76614988478a076bbe105545a16ee743

于 2019-09-01T13:12:53.500 回答
-1

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

于 2017-04-11T18:54:18.073 回答
-1

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

于 2017-08-23T15:55:38.553 回答
-3

要从 git 中删除最后一次提交,您可以简单地运行

git reset --hard HEAD^ 

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

git reset --hard HEAD~2 

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

更多信息在这里。

此处的 Git 教程提供了有关如何清除存储库的帮助:

您想从历史记录中删除该文件并将其添加到 .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
于 2013-06-05T05:41:44.040 回答