简体   繁体   English

删除分支上的Git提交

[英]Removing Git commits on a branch

How do I remove commits that are branched off master ? 如何删除分支master提交?

I have added a large library, along with a very rich commit history (and that predates my code) to a subdirectory via Git subtree . 我已经通过Git子树添加了一个大型库,以及一个非常丰富的提交历史(并且在我的代码之前)到一个子目录。 I'd like to retroactively squash that entire history, but still be able to merge in new commits to the library . 我想追溯整个历史, 但仍然可以合并到新的提交到库

I have tried various combinations of git rebase but I never get the expected result [*]. 我尝试了各种git rebase组合,但我从未得到预期的结果[*]。

My repository looks something like: 我的存储库看起来像:

A---B-----------F---G master
               /
  ... C---D---E

and I'd like for it to look something like: 我希望它看起来像:

A---B-----------F'--G' master
               /
              E'

or: 要么:

A---B-------E'--F'--G' master

[*]: [*]:

  • git rebase --onto CE master
  • git checkout F; git rebase --onto CE master
  1. This is history editing. 这是历史编辑。 You will end up in something like 你最终会得到类似的东西

     A---B-----------F'---G' master / E' 
  2. Merging will be a problem after this, because of Git will not be able to find common parents between your history and libraries's history. 在此之后合并将是一个问题,因为Git将无法在您的历史和图书馆历史之间找到共同的父母。

  3. To actually do it you need to 要真正做到这一点你需要

    1. Reset to B (creating tag or branch for G to keep it around) 重置为B(为G创建标记或分支以保持它)
    2. Perform merge with --no-commit . 使用--no-commit执行合并。
    3. Rebase or cherry-pick G here (it will be G') Rebase或者在这里挑选G(它将是G')

    The history will look like 历史将是如此

     A---B-----------F'---G' 

To make the shallow clone of the library, you need to do something like this (Warning: untested): 要制作库的浅层克隆,您需要执行以下操作(警告:未经测试):

  1. Save commits from F (not including) to G (including) to a patch ( git format-patch F --stdout > ~/saved_commits.patch ) 保存从F(不包括)到G(包括)到补丁( git format-patch F --stdout > ~/saved_commits.patch )的git format-patch F --stdout > ~/saved_commits.patch
  2. Reset to B. Ensure there are no branches that are poiting to F, E or G 重置为B.确保没有分支符合F,E或G
  3. Remove the remote together with it's ref namespace git remote rm 删除遥控器和它的ref命名空间git remote rm
  4. Erase reflogs: git reflog expire --expire=now --all 擦除reflogs: git reflog expire --expire=now --all
  5. Actually remove things from git: git gc --prune=now . 实际上从git中删除东西: git gc --prune=now Now you should see the repository shrank. 现在您应该看到存储库缩小了。
  6. Re-add the remote for library. 重新添加库的远程。
  7. git fetch --depth=10 libraryremote
  8. Repeat the merge (the usual way) 重复合并(通常的方式)
  9. Apply saved commits ( git am ~/saved_commits.patch ). 应用已保存的提交( git am ~/saved_commits.patch )。

To migrate into submodules solution (the best option probably), you need to rollback to the state before merge and set up submodules, then substitute each merge with changed commit-id for submodule. 要迁移到子模块解决方案(可能是最好的选项),您需要回滚到合并之前的状态并设置子模块,然后用更改的commit-id替换每个合并用于子模块。 Unlike for the case of splitting out project directory to submodule I don't know the automated solution for this (but it can be implemented the similar way). 将项目目录拆分为子模块情况不同,我不知道这个的自动化解决方案(但它可以以类似的方式实现)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM