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

时间:2012-03-13 11:41:20

标签: git github git-commit

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

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

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

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

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

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

18 个答案:

答案 0 :(得分:918)

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

注意:如果存储库有子模块,这不起作用!如果您使用的是子模块,则应使用例如子模块。 interactive rebase

第1步:删除所有历史记录(确保您有备份,但无法还原

cat .git/config  # note <github-uri>
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 :(得分:531)

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

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会以某种方式导致我的冲突(并且因为我有很多历史记录需要很长时间)。

答案 2 :(得分:83)

这是我最喜欢的方法:

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

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

答案 3 :(得分:31)

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

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

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

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

最后,您将拥有一个新的root提交,它是所有提交后的提交。

优点是您不必删除您的存储库,如果您有其他想法,则总是会有后备。

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

答案 4 :(得分: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 :(得分:5)

您可以使用浅clones(git&gt; 1.9):

git clone --depth depth remote-url

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

答案 6 :(得分:4)

git filter-branch是主要的手术工具。

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

--parent-filter让父母加入stdin,并且应该在stdout上打印重写的父母; unix true成功退出并且不打印任何内容,因此:没有父母。 @^!Git shorthand for&#34;头部提交但不是其任何父母&#34;。然后删除所有其他参考并随意推送。

答案 7 :(得分:2)

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

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

答案 8 :(得分:2)

删除 .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:这不会保留您旧的提交历史

答案 9 :(得分:2)

以下是根据@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

它可以满足我的目的(我不使用子模块)。

答案 10 :(得分:1)

这会删除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的答案。

答案 11 :(得分:0)

以下是清除 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

答案 12 :(得分:0)

您在这里:

#!/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

答案 13 :(得分:0)

只需删除Github仓库并创建一个新仓库即可。迄今为止最快,最简单,最安全的方法。毕竟,当您只需要一次提交的master分支时,您将获得在已接受的解决方案中执行所有这些命令的条件?

答案 14 :(得分:0)

  

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

更具概念性的答案:

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

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

答案 15 :(得分:-1)

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

答案 16 :(得分:-1)

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

答案 17 :(得分:-2)

  

要从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