如何合并git中一直删除master中的文件的分支同时保持删除的文件在master分支中的完整性?

如何合并git中一直删除master中的文件的分支同时保持删除的文件在master分支中的完整性?

例如,在我的测试分支中,我删除了一个名为/ sounds的文件夹,在我的母版中,我也有该/ sounds文件夹,如何将我的测试分支合并到母版中并保留/ sounds文件夹?

评论
  • duang
    duang 回复

    Restore the files in the branch, then merge it.

    git checkout test
    git restore --source master sounds
    git add sounds
    git commit
    

    git diff master should now show no changes to sounds/. Now merge as normal.

    如果您无法更改该分支,请对其进行新分支,然后还原并合并该分支。

    git checkout test
    git checkout -b test2
    ...then restore as above...
    
  • 沉淀!
    沉淀! 回复

    理解这一点的关键是要认识以下两个事实:

    • Files aren't in branches. Files are in commits.
    • A merge commit is a commit.
    • Each commit stores a full snapshot of all files.
    • The files that are in a new commit you make—including a new merge commit—comes from the files that are in Git's index at the time you run git commit or git merge --continue.

    Hence, if git merge is going to make a commit that you don't like, you can do one of two things:

    • Allow it to make the commit you don't like, then add a second commit to fix it up.
    • Or: make sure git merge doesn't make the commit yet, using git merge --no-commit. The merge will stop before committing. Then, adjust the index to contain the files (and versions of those files) that you want to appear in the commit.

    如果您的问题是关于从某些提交中获取一些文件以进行下一次提交的机制,那么一旦您了解了Git的提交内容和工作原理,那么这部分就显得微不足道了。例如,假设您这样做:

    git checkout master
    
    git checkout -b otherbranch
    git rm -r sounds
    git commit
    
    git checkout master
    git merge otherbranch
    

    This actually makes the merge commit, assuming there are no merge conflicts (there won't be), and the new merge commit lacks the sounds/ files. But why is this a big deal? You want the sounds files back, just grab them from the commit that comes one step before the new merge commit, along the "main" line:

    git checkout master~1 -- sounds/
    

    然后重新提交:

    git commit
    

    that extends master by one more commit again. The new commit has the same files that the merge commit has, except that it also has all the sounds/ files too.

    Making the merge while retaining the files produces what some call an evil merge (see Evil merges in git?), but it's equally simple. Replace the git merge step with:

    git merge --no-commit otherbranch
    git checkout HEAD -- sounds/
    git merge --continue
    

    and you make a merge commit that doesn't delete the sounds/ files, because it copied all the sounds/ files from the commit that was the tip of master just a moment ago, before you made the new merge commit.