git merge:删除我想保留的文件!

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1407638/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 07:01:33  来源:igfitidea点击:

git merge: Removing files I want to keep!

gitmergebranch

提问by drfloob

How can you merge two branches in git, retaining necessaryfiles from a branch?

如何在 git 中合并两个分支,保留一个分支中的必要文件?

When merging two branches, if a file was deleted in one branch and not in another, the file is ultimately deleted.

合并两个分支时,如果文件在一个分支中被删除而不在另一个分支中被删除,则该文件最终被删除。

For example:

例如:

  • A file exists in master when you make a new branch
  • you remove the file from master since we don't need it (yet)
  • you make changes in the branch to add a feature, which relies on the file existing
  • you make bug fixes in master(cannot be discarded)
  • you merge some day, and the file is gone!
  • 创建新分支时,master 中存在一个文件
  • 您从 master 中删除文件,因为我们不需要它(还)
  • 您在分支中进行更改以添加依赖于现有文件的功能
  • 您在 master 中修复了错误(不能丢弃)
  • 有一天你合并了,文件就不见了!


How to Reproduce:

如何复制:

  1. Create a git repo with one file.

    git init
    echo "test" > test.txt
    git add .
    git commit -m "initial commit"
    
  2. Create a branch

    git branch branchA
    
  3. Delete the file in master

    git rm test.txt
    git commit -m "removed file from master"
    
  4. Make ANY changes in branchA that don't touch the deleted file (it has to be unchanged to avoid Conflict)

    git checkout branchA
    touch something.txt
    git add .
    git commit -m "some branch changes"
    
  1. 用一个文件创建一个 git repo。

    git init
    echo "test" > test.txt
    git add .
    git commit -m "initial commit"
    
  2. 创建一个分支

    git branch branchA
    
  3. 删除master中的文件

    git rm test.txt
    git commit -m "removed file from master"
    
  4. 在 branchA 中进行任何不涉及已删除文件的更改(必须保持不变以避免冲突)

    git checkout branchA
    touch something.txt
    git add .
    git commit -m "some branch changes"
    

From here, any way I've found to merge these two branches, the test.txt file is deleted. Assuming we were relying on the filefor branchA, this is a big problem.

从这里开始,我发现以任何方式合并这两个分支,删除 test.txt 文件。假设我们依靠文件branchA,这是一个很大的问题。



Failing examples:

失败的例子:

Merge 1

合并 1

git checkout branchA
git merge master
ls test.txt

Merge 2

合并 2

git checkout master
git merge branchA
ls test.txt

Rebase 1

变基 1

git checkout branchA
git rebase master
ls test.txt

采纳答案by cmcginty

This is an interesting issue. Because you deleted the file after BranchAwas created, and then are merging masterinto BranchA, I'm not sure how Git would be able to realize there is a conflict.

这是一个有趣的问题。因为您在BranchA创建后删除了文件,然后合并master到.git 中BranchA,所以我不确定 Git 如何能够意识到存在冲突。

After the bad merge you can undo, and then re-merge, but add back the file:

错误合并后,您可以撤消,然后重新合并,但重新添加文件:

git checkout HEAD@{1} .
git merge --no-commit master
git checkout master test.txt
git add test.txt
git commit

回答by Phil

For a quick fix in this case, "git revert" the commit that deleted the file.

在这种情况下,要快速修复,请“git revert”删除文件的提交。

When this situation comes up in the future, the better way to handle it is to ensure that the creation of the new file happens on the branch. Then it gets added on master when you merge, but you don't have the file lying around in master in the meantime.

当以后出现这种情况时,更好的处理方法是确保新文件的创建发生在分支上。然后在您合并时将其添加到 master 上,但同时您没有该文件位于 master 中。

回答by Alex Dean

Casey's example didn't work for my case - I couldn't checkout test.txtfrom master, because it was no longer in that branch:

Casey的示例对我的情况不起作用 - 我无法test.txt从结帐master,因为它不再在该分支中:

$ git checkout master test.txt
error: pathspec 'test.txt' did not match any file(s) known to git.

Happily I could pull the file out of branchA's own HEAD:

很高兴我可以从branchA自己的文件中提取文件HEAD

$ git checkout branchA
$ git merge --no-commit master
$ git checkout HEAD test.txt
$ git add test.txt
$ git commit

回答by Alex S

My solution to this was to simply modify the files I needed to keep (added a comment which was needed anyway) and commit those changes on the target branch, thus generating a merge conflict which could easily be resolved with a git addand a normal commit.

我对此的解决方案是简单地修改我需要保留的文件(添加了无论如何都需要的注释)并在目标分支上提交这些更改,从而产生合并冲突,可以通过git add正常提交轻松解决。

My history went something like this. Branch names have been changed to protect the innocent.

我的历史是这样的。分支名称已更改以保护无辜者。

  1. create and commit files for a new feature to master
  2. realize this addition going to be more involved than originally planned, thus, branched to feature_branch
  3. Removed files from master so as not to disrupt normal workflow with RBs and such
  4. Time passes, more commits on master, none on feature_branch
  5. Resume work on the feature, git merge masteron feature_branch causes original files to be removed (of course), git reset --hardto before the merge
  6. Applied the solution described above
  1. 为要掌握的新功能创建和提交文件
  2. 意识到这个添加将比最初计划的更复杂,因此,分支到 feature_branch
  3. 从 master 中删除了文件,以免破坏 RB 等的正常工作流程
  4. 时间流逝,更多提交在 master 上,没有在 feature_branch 上
  5. 恢复功能的工作,git merge master在 feature_branch 上导致原始文件被删除(当然),git reset --hard在合并之前
  6. 应用上述解决方案

回答by Chris Dodd

You need to modify the file in the branch, so that there's a merge conflict with the delete in the trunk.

需要修改分支中的文件,这样与trunk中的delete就会产生合并冲突。

The exact same thing will happen if you, for example, delete a declaration for something in a headerfile in the trunk (because nothing needs it), and add a dependency on that declaration to some non-header file(s) in the branch. When you merge, since the branch doesn't touch (that part of) the header, it will just delete the declaration and things will break.

例如,如果您删除主干中头文件中某些内容的声明(因为没有任何东西需要它),并将对该声明的依赖添加到分支中的某些非头文件中,则会发生完全相同的事情。当您合并时,由于分支不会触及(该部分)标题,它只会删除声明并且事情会中断。

Whenever you have stuff in multiple places that is interdependent and needs to be kept in sync, its very easy for a merge to silently introduce problems. Its just one of the things you have to know about and check when merging. Ideally, you use compile-time asserts or other build time checks that will make any failures immediately apparent.

每当您在多个地方有相互依赖且需要保持同步的东西时,合并很容易悄悄地引入问题。它只是您在合并时必须了解和检查的事情之一。理想情况下,您使用编译时断言或其他构建时检查,可以立即发现任何失败。