当重命名文件并使用旧名称创建新文件时,什么工作流可以减轻git合并冲突?
问题当重命名文件并使用旧名称创建新文件时,什么工作流可以减轻git合并冲突?,git,merge,rename,git-merge,git-merge-conflict,Git,Merge,Rename,Git Merge,Git Merge Conflict,问题 我有根分支master和feature从master分支 master具有文件A 功能已将文件A移动到B并创建了一个新文件A 在master中针对文件A工作需要合并到功能分支文件B 将master合并到功能中会导致合并冲突主文件A尝试合并到功能文件A中,即使主文件A和功能A不再相关。 我如何告诉git将masterA合并到featureB 步骤重现 在控制台中: mkdir git_rename_demo cd git_rename_demo git init echo "LineB1
master
和feature
从master分支master
具有文件A
功能
已将文件A
移动到B
并创建了一个新文件A
master
中针对文件A
工作需要合并到功能分支文件B
master
合并到功能中会导致合并冲突<代码>主文件A
尝试合并到功能文件A
中,即使主文件A
和功能A
不再相关。
我如何告诉git将master
A
合并到feature
B
mkdir git_rename_demo
cd git_rename_demo
git init
echo "LineB1\nLineB2\nLineB3\nLineB4" > A.txt
git add A.txt
git commit -m "Add A"
git checkout -b rename_A_to_B
git mv A.txt B.txt
echo "LineA1\nLineA2\nLineA3" > A.txt
git add A.txt
git commit -m "Moved Old A to B and Added New A"
git checkout master
echo "LineB5\nLineB5" >> A.txt
git add A.txt
git commit -m "Added More LineBs to A"
git checkout rename_A_to_B
git merge master
场景
我有一个主
分支和一个功能
分支。master
上的文件A
,包含执行“A”相关逻辑的代码
在功能
分支上,发现文件A
作为文件名没有意义,因为代码与“B”逻辑更相关。同时,编写了与feature
分支中的“A”逻辑相关的新代码。为了解决这个问题,文件A
被重命名为文件B
,这实际上意味着文件A
中所有与“B”相关的原始逻辑都已移动到新文件B
。所有新的“A”相关逻辑被添加到名为A
的新文件中,有效地替换了旧的A
文件
master
分支的工作仍在继续,在仍然存在的A
文件中添加了更多的“B”逻辑。这是功能
分支上已重命名为B
的文件
此时需要将
master
的工作合并到功能中,因为功能将继续与master
分开开发,直到稍后的日期。master
与feature
的合并会导致上述冲突。我们需要继续允许从事master
工作的开发人员针对A
执行与“B”相关的工作,并能够将A
文件工作合并到功能分支B
文件中,而无需每次手动解决冲突。我不确定您是否能找到自动解决方案。
但是您可以从git diff创建补丁,并在feature分支中手动更新git apply。TL;博士
没有真正好的方法来处理这个问题,但是您可以手动完成。见下文
长的
不要太担心分支名称。不要担心承诺;合并基于提交,而不是分支名称。分支名称只是帮助您和Git查找特定的提交。根据定义,分支名称始终包含分支中最后一次提交的原始提交哈希ID。添加新提交包括:
按名称检查分支,以便Git知道在步骤3中更新哪个分支名称。这使分支的提示提交成为当前提交。特殊名称HEAD
现在附加到分支名称,因此,HEAD
选择当前提交,这是分支中的最后一次(或提示)提交
以通常的方式做出新的承诺。Git将创建提交,将其父级设置为当前提交。这个新的提交将获得它自己唯一的hash ID,不同于以前的每个提交,也不同于将来的每个提交
此时,在进行了新提交之后,Git将新提交的哈希ID写入一个分支名称中:即HEAD
所附加的分支名称。因此,现在分支名称指向分支中的最后一个(提示)提交。新的提交指向过去的提示;分支现在比提交长一个
无论何时进行真正的合并(存在一些虚假的合并),都会涉及三种提交:
- 合并基,它是其他两个提交的最佳共同祖先李>
- 当前提交(或
头
),通常是分支的尖端;1及
- 在命令行中选择的提交:通常是另一个分支的尖端
Git自己查找合并基提交。你只要说出另一个名字就行了。如果要提前查看合并基础是哪个提交,可以运行:
git merge-base --all other
其中,other
是您计划提供给git merge
命令的内容,git从中选择第三个提交
1另一个选项是,您可能处于分离头状态,其中特殊名称HEAD
仅包含提交本身的原始散列ID。无论哪种方式,HEAD
命名当前提交。当你在一个分支上时,它只是使用一个分支名称。但通常在运行“合并”时,您位于分支上
简而言之,合并是如何工作的,这也是您的问题所在
想象一下一个简化的提交时间线,稍后的提交在右边,在这个时间线中,我们用单个大写字母替换提交哈希,以便更容易地讨论它们。我们可能会:
I--J <-- branch1 (HEAD)
/
...--G--H
\
K--L <-- branch2
这就是您的问题所在:--find renames
在第一个git diff
中会发现合并基中的文件A
,在提交中可能也称为A
,现在在头部提交中称为B
。所以diff会将“A在base中,B在ours中”配对并比较内容。这就是我们所改变的:内容改变了,文件名也改变了
第二个git diff
将“A在基地,A在他们的基地”配对,看看他们改变了什么。当我
git diff --find-renames <hash-of-H> <hash-of-J> # what we changed
git diff --find-renames <hash-of-H> <hash-of-L> # what they changed
git show :1:F > F.LOCAL # :1: means the merge base version
git show :2:F > F.OURS # :2: means our version, like `git checkout --ours`
git show :3:F > F.THEIRS # :3: means their version, like `git checkout --theirs`
git merge other
git merge-file B A.base A.other
git checkout --ours A
git add A