合并标记为冲突的差异的 2 个文本文件

Merge 2 text files with differences marked as conflicts

我想查看 2 个合并文件的完整输出,其中每个差异都以与 git 标记文件冲突相同的方式标记。 用例是合并 2 个相似的配置文件,检查合并后的文件,并提供视觉提示以明确文件之间的所有差异,以便轻松决定选择哪个文件。

我已经尝试过使用 diff 和 diff3,但我只能得到差异(使用 diff)或仅标记冲突的完全合并文件(使用 diff3 -m -A file1 file1 file2)。我用过 git diff 和相关工具,但它们都合并了不冲突的更改,而不是将它们标记为差异。

运行 环境将是一个 bash shell 脚本,因此最好使用常用的 linux 工具获得所需的输出。

示例:

文件 1 的内容:

environment:
  base_branch: master
  branch: this_is_the_same_for_both_files

文件 2 的内容:

environment:
  base_branch: a_different_base_branch
  branch: this_is_the_same_for_both_files
  a_new_key: the_new_key_value

期望的输出:

environment:
<<<<< file1
  base_branch: master
=====
  base_branch: a_different_base_branch
>>>>> file2
  branch: this_is_the_same_for_both_files
<<<<< file1
=====
  a_new_key: the_new_key_value
>>>>> file2

根据评论中的建议,我想出了这个似乎解决了我的问题的班轮。 我本来想在 sed 替换中对标记使用常量,但显然使用包含 \nsed 的变量来表示 mac os 并不简单.

即使在 docker alpine:3.8 中使用 diffutils,此代码似乎也能正常工作。 其他选项(brew gnu-sed 和类似选项)可能不容易移植。

diff -D AAAAAAA "${path}" <(echo -n "$decrypted") | \
  sed -e $'s/#ifndef AAAAAAA/<<<<<<< file-on-disk/g' | \
  sed -e $'s/#endif \/\* ! AAAAAAA \*\//=======\\n>>>>>>> file-from-secret/g' | \

  sed -e $'s/#else \/\* AAAAAAA \*\//=======/g' | \

  sed -e $'s/#ifdef AAAAAAA/<<<<<<< file-on-disk\\n=======/g' | \
  sed -e $'s/#endif \/\* AAAAAAA \*\//>>>>>>> file-from-secret/g';

解释:

diff -D AAAAAAA "${path}" <(echo -n "$decrypted"):输出带有“#ifdef NAME”差异的合并文本。我使用 AAAAAAA 作为标记名称。 Diff 使用 #ifndef AAAAAAA#endif /* ! AAAAAAA */ 包围仅存在于第一个文件中的文本,使用 /#ifdef AAAAAAA#endif /* AAAAAAA */ 包围仅存在于第二个文件中的文本。请注意第一个 #ifndef 中的 n 和第一个 #endif 注释中的 !。由于所有标记都不同,因此很容易进行替换。

sed -e $'s/#endif \/\* ! AAAAAAA \*\//=======\\n>>>>>>> file-from-secret/g':将标记替换为

=======
>>>>>>> file-from-secret

因为有 \n,替换字符串用 $'' 封装 os,这可以正确解释换行符。但是,\需要双重转义。