将旧分支合并到主分支时,Git 不会应用已删除的文件。如何告诉 Git 应用已删除的文件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37122124/
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-19 12:00:06  来源:igfitidea点击:

Git does not apply deleted files when merging an old branch into the master. How can I tell Git to apply deleted files?

gitgit-merge

提问by Matthieu Scarset

I have a master and a dev branch. I made commits in both. I also deleted some files in dev. I made other commit in master, so this master branch is more recent.

我有一个 master 和一个 dev 分支。我在两者中都做出了承诺。我还删除了dev中的一些文件。我在 master 中做了其他提交,所以这个 master 分支是最近的。

My issue is that merging dev into master dont delete files.

我的问题是将 dev 合并到 master 中不会删除文件。

Git consider that these files exists in master and consequently, keep them during the merge.

Git 认为这些文件存在于 master 中,因此在合并期间保留它们。

How can I merge these two branches and force Git to apply all and every commits made in dev ? including deleted files.

如何合并这两个分支并强制 Git 应用在 dev 中所做的所有提交?包括删除的文件。

Thks for your help!

感谢您的帮助!

回答by Jeff Puckett

Merges definitely delete files when there's not a conflict with changes in branches.

当与分支中的更改没有冲突时,合并肯定会删除文件。

git does not preserve files during merging if they are deleted in the merging branch. - Nils_M

如果在合并分支中删除了文件,则 git 在合并期间不会保留文件。- 尼尔斯_M

To prove it to myself, I had to try to reproduce your scenario. See this demonstration in hopes that you can see what it is you are doing differently.

为了向自己证明这一点,我不得不尝试重现您的场景。看看这个演示,希望你能看到你正在做的不同的事情。

create a new repository

创建一个新的存储库

mkdir test
cd test
git init

Initialized empty Git repository in /test/.git/

在 /test/.git/ 中初始化空 Git 存储库

create and add some files to master branch

创建并添加一些文件到 master 分支

echo one > 1.txt
echo two > 2.txt
git add .
git commit -m "init repo"

[master (root-commit) feaa910] init repo
2 files changed, 2 insertions(+)
create mode 100644 1.txt
create mode 100644 2.txt

[master (root-commit) fea910] init repo
2 个文件已更改,2 个插入 (+)
创建模式 100644 1.txt
创建模式 100644 2.txt

create new branch and add/delete some files

创建新分支并添加/删除一些文件

git checkout -b new

Switched to a new branch 'new'

切换到一个新的分支 'new'

echo three > 3.txt
rm 2.txt 
git add .
git status

On branch new
Changes to be committed:
(use "git reset HEAD ..." to unstage)

deleted: 2.txt
new file: 3.txt


要提交的分支新更改上:(
使用“git reset HEAD ...”取消暂存)

删除:2.txt
新文件:3.txt

git commit -m "changes in new"

[new db6b1a0] changes in new
2 files changed, 1 insertion(+), 1 deletion(-)
delete mode 100644 2.txt
create mode 100644 3.txt

[new db6b1a0] 更改新的
2 个文件已更改,1 个插入(+),1 个删除(-)
删除模式 100644 2.txt
创建模式 100644 3.txt

commit some more changes in master

在 master 中提交更多更改

git checkout master

Switched to branch 'master'

切换到分支“master”

echo update >> 1.txt 
git commit -am "update master"

[master 912a520] update master
1 file changed, 1 insertion(+)

[master 912a520] 更新 master
1 个文件已更改,1 个插入 (+)

tree

.
├── 1.txt
└── 2.txt

.
├── 1.txt
└── 2.txt

verify files still deleted in new

验证在新文件中仍删除的文件

git checkout new

Switched to branch 'new'

切换到分支“新”

tree

.
├── 1.txt
└── 3.txt

.
├── 1.txt
└── 3.txt

merge new into master

将新合并到主

git checkout master

Switched to branch 'master'

切换到分支“master”

git merge new master

Removing 2.txt
Merge made by the 'recursive' strategy.
2.txt | 1 -
3.txt | 1 +
2 files changed, 1 insertion(+), 1 deletion(-)
delete mode 100644 2.txt
create mode 100644 3.txt

删除
由“递归”策略进行的2.txt合并。
2.txt | 1 -
3.txt | 1 +
2 个文件更改,1 个插入(+),1 个删除(-)
删除模式 100644 2.txt
创建模式 100644 3.txt

tree

.
├── 1.txt
└── 3.txt

.
├── 1.txt
└── 3.txt

as you can see, the file 2.txtdeleted in the newbranch is now definitely deleted in masterfollowing the merge.

如您所见,2.txtnew分支中删除的文件现在master在合并之后肯定会被删除。

回答by Jeff Puckett

The only way I can fathom this possible situation is if you created two different files, each with the same filename, in independent branches.

我能理解这种可能情况的唯一方法是,如果您在独立的分支中创建了两个不同的文件,每个文件都具有相同的文件名。

i.e. let's say that the masterand devbranches already exist.

即假设masterdev分支已经存在。

  1. create and commit file.txtto master
  2. checkout dev, then again createand commitfile.txtto dev. Now because you have created two distinct files, git views them as two separate entities despite the same filename, defeating the whole purpose of version control.
  3. later delete file.txtfrom dev
  4. merge devinto master, and low and behold file.txtstill exists in master, and this makes sense because like I said, git views the two files as completely independent.
  1. 创建并提交file.txtmaster
  2. checkout dev,然后再次创建并提交file.txtdev. 现在,因为您创建了两个不同的文件,尽管文件名相同,git 仍将它们视为两个独立的实体,从而违背了版本控制的全部目的。
  3. 后来file.txtdev
  4. 合并dev到 中master,而 low 和 beholdfile.txt仍然存在于 中master,这是有道理的,因为就像我说的,git 将这两个文件视为完全独立的。

noticeif you had notdeleted file.txtfrom devand attempted a merge, then you would have gotten a merge conflict because git wouldn't know how to handle two different entities with the same path/filename.

通知如果你有没有删除file.txtdev并试图合并,那么你会得到一个合并冲突,因为混帐不知道如何处理两个不同的实体具有相同路径/文件名。

If this is your scenario, then I'm going to risk arrogance and say you're doing it wrong ;)

如果这是您的情况,那么我将冒着傲慢的风险说您做错了 ;)

The point of a version control system is to let the tool manage your differences between a file at different stages in time as well as the relationship of those changes to other files in the repository.

版本控制系统的重点是让该工具及时管理不同阶段文件之间的差异,以及这些更改与存储库中其他文件的关系。

My suggestion to improve the workflow in this situation would be to checkout the specific file from the other branch:

我在这种情况下改进工作流程的建议是从另一个分支签出特定文件:

  1. create and commit file.txtto master
  2. checkout dev, then just grab the particular file from the other branch

    git checkout master -- file.txt
    

    In this situation, you will still be on the devbranch, but have now added file.txtfrom the masterbranch.

  3. now git recognizes that these are the same entity. so you can delete the file and commit the removal in dev

  4. merging devinto masterwill now delete file.txtfrom master
  1. 创建并提交file.txtmaster
  2. checkout dev,然后只需从另一个分支中获取特定文件

    git checkout master -- file.txt
    

    在这种情况下,您仍将在dev分支上,但现在file.txt已从master分支添加。

  3. 现在 git 认识到这些是同一个实体。所以你可以删除文件并提交删除dev

  4. 合并devmaster现在file.txt将从中删除master

回答by Stefan Monov

I had the same problem. In my case I think the problem was that, when I did the merge, my copy of the merged-from branch was outdated compared to the remote. (a colleague had done the deletion, not me)

我有同样的问题。就我而言,我认为问题在于,当我进行合并时,与远程分支相比,我的合并自分支副本已过时。(删除的是同事,不是我)

In any case, what fixed it was deleting the whole working copy and cloning it anew.

无论如何,修复它的是删除整个工作副本并重新克隆它。

回答by Strikeskids

You can run the merge without committing, make sure you have all of the correct files, and then run the commit.

您可以在不提交的情况下运行合并,确保您拥有所有正确的文件,然后运行提交。

  1. Perform the merge

    git checkout master
    git merge --no-commit dev
    
  2. Make the necessary changes, and fix merge conflicts (if any).

    git rm my-files-to-delete
    
  3. Commit the merge, finishing the process.

    git commit
    
  1. 执行合并

    git checkout master
    git merge --no-commit dev
    
  2. 进行必要的更改,并修复合并冲突(如果有)。

    git rm my-files-to-delete
    
  3. 提交合并,完成过程。

    git commit