从git数据库中完全删除提交 [英] Completely remove commit from git database

查看:98
本文介绍了从git数据库中完全删除提交的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要一个提交,使其不再位于提交的git数据库中.我需要能够删除提交abc123...,以使git checkout abc123...返回error: pathspec 'abc123...' did not match any file(s) known to git.

QA 如何删除"git commit" 部分回答了此问题,就像如何从HEAD删除对提交的引用一样,但它并不涵盖查找提交中存在的所有分支,也不涵盖在成为悬空提交后将其过期和清除.

我将如何实现?

解决方案

  1. 列出包含提交的所有分支:

    git branch --contains COMMITSHA
    

  2. 从这些分支中删除提交:

    git checkout BRANCH
    git rebase -i COMMITSHA^
    # delete line with commit and save
    

    如果在任何远程中都跟踪到更改的分支,请使用覆盖将其推到那里:

    git push --force REMOTE BRANCH
    

    例如:

    git push --force origin master
    

    (请注意,根据您的开发过程,提交也可能会出现在未跟踪的远程分支中.)

  3. 清除提交,因此无法从本地存储库中还原它:

    git reflog expire --all BRANCH1 BRANCH2 # list all branches you changed
    git prune --expire now
    

    请注意,还必须在具有此提交的所有远程存储库上运行此命令.如果您无权访问远程存储库,则必须用手指交叉-提交最终将自行失效,并被git gc清除.

    请注意,上述命令将从Git存储库中删除 all 个悬空对象以及所有分支更改历史记录-因此,您将无法(通过非司法手段)恢复之前丢失的任何内容一直运行.

  4. 告诉所有协作者以获取更改的分支,并更新基于它们的任何工作.他们应该执行以下操作:

    git fetch REMOTE      
    

    对于基于您在上面更改的分支的每个分支(包括分支本身,如果它们在本地具有的话):

    git checkout BRANCH
    git rebase REMOTE/BRANCH
    git reflog expire --all BRANCH
    

    完成后:

    git prune --expire now
    

I need a commit to no longer be in the git database of commits. I need to be able to remove commit abc123... such that git checkout abc123... returns error: pathspec 'abc123...' did not match any file(s) known to git.

The QA How to delete a 'git commit' answers this partially, as in how to remove references to a commit from the HEAD, but it doesn't cover finding all of the branches a commit is present in nor does it cover expiring and purging the commit once it has been made a dangling commit.

How would I achieve this?

解决方案

  1. List all branches that contain the commit:

    git branch --contains COMMITSHA
    

  2. Remove commit from these branches:

    git checkout BRANCH
    git rebase -i COMMITSHA^
    # delete line with commit and save
    

    If a changed branch is tracked in any remote, push it there with override:

    git push --force REMOTE BRANCH
    

    e.g:

    git push --force origin master
    

    (Note that, depending on your development process, the commit may appear in untracked remote branches as well.)

  3. Purge the commit, so it can not be restored from your local repo:

    git reflog expire --all BRANCH1 BRANCH2 # list all branches you changed
    git prune --expire now
    

    Note that you must also run this command on all remote repositories that had this commit. If you have no access to the remote repo, you have to cross your fingers — commit will eventually expire by itself and will be purged by git gc.

    Be warned that above commands will remove all dangling objects from Git repo and all the history of branch changes — so you wouldn't be able to restore (by non-forensic means) anything lost prior to its run.

  4. Tell all collaborators to fetch changed branches and update any work they might have based on them. They should do as follows:

    git fetch REMOTE      
    

    For each branch that is based on a branch you changed above (including the branch itself if they have it locally):

    git checkout BRANCH
    git rebase REMOTE/BRANCH
    git reflog expire --all BRANCH
    

    After they're done:

    git prune --expire now
    

这篇关于从git数据库中完全删除提交的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆