如何在 Git 中执行三向比较而不合并?

2024-02-20

我想在具有公共合并基础的两个 git 分支之间执行三向差异,并使用 kdiff3 查看它。

我发现了很多关于SO的指导(以及一些非常相似的问题(1 https://stackoverflow.com/q/26301307/3380131, 2 https://stackoverflow.com/q/3635788/3380131, 3 https://stackoverflow.com/q/33440597/3380131) ) 但我还没有找到直接的答案。值得注意的是,评论这个答案 https://stackoverflow.com/a/5818279/3380131意味着我想要的东西是可能的,但它对我不起作用。希望该用户可以在这里插话:)

对于背景,当我执行合并时,我使用“diff3”冲突样式:

git config --global merge.conflictstyle diff3

我有git mergetool配置为使用 kdiff3。

解决合并冲突时,这显示了四个文件:

  1. 当前分支的文件($LOCAL)
  2. 另一个分支的文件($REMOTE)
  3. 该文件是两个分支的共同祖先 ($BASE)
  4. 合并的输出文件 ($MERGED)

然而,git difftool只会拉起两个分支尖端。我也想看看基础文件。需要明确的是,我希望能够执行此 diffbefore合并,包括没有合并冲突的文件. (git mergetool仅在存在冲突时显示三向差异)。


部分解决方案#1:

使用单个文件,我可以导出三个版本并手动调用差异:

git show local_branch:filename > localfile
git show remote_branch:filename > remotefile
git show `git merge-base local_branch remote_branch`:filename > basefile

{kdiff3_path}/kdiff3.exe --L1 "Base" --L2 "Local" --L3 "Remote" -o "outputfile" basefile localfile remotefile &

这样做有两个问题:

  1. 我希望它适用于整个项目,而不仅仅是特定文件。
  2. 这太丑了!我可以编写脚本,但我希望有一种使用标准 git 流程的更简洁的方法。

部分解决方案#2:

Thanks to this answer https://stackoverflow.com/a/5091756/3380131 and comment https://stackoverflow.com/questions/5074452/git-how-to-force-merge-conflict-and-manual-merge-on-selected-file#comment40997817_5091756 for the inspiration.

创建一个始终返回“false”的自定义合并驱动程序,这会创建冲突的合并状态,而不实际执行任何自动合并。然后使用执行差异git mergetool。然后在完成后中止合并。

  1. Add to .git/config:

    [merge "assert_conflict_states"]
        name = assert_conflict_states
        driver = false
    
  2. 创建(或附加).git/info/attributes使所有合并都使用新驱动程序:

    * merge=assert_conflict_states
    
  3. 执行合并,现在不执行任何自动合并。

  4. 做差异。就我而言:git mergetool这会调出 kdiff3 三向合并。

  5. 完成后,中止合并:git merge --abort.

  6. 撤消步骤 #2。

除了 kdiff3 在调用时执行自动合并之外,这(有点)有效,所以我还是不能查看预合并的差异。不过,我可以通过更改 Git 的库存 kdiff3 驱动程序文件来解决此问题(.../git-core/mergetools/kdiff3通过删除--auto switch.

即便如此,这仍然存在以下令人困扰的问题:

  1. 仅当两个文件都更改时才有效!在仅更改一个文件的情况下,更新的文件将替换旧的文件,并且永远不会调用合并。
  2. 我必须修改 Git kdiff3 驱动程序,它根本不可移植。
  3. 我必须修改attributes进行差异之前和之后。
  4. 当然,我希望在不合并的情况下做到这一点:)

赏金信息:

根据给出的答案,这对于标准 Git 来说是不可能的。所以现在我正在寻找一个更开箱即用的解决方案:如何调整 Git 来实现这一点?

这是一个线索:显然,如果三个文件中只有一个发生了更改,则在合并结果中使用这个较新的文件,而无需实际调用合并驱动程序。这意味着在这种情况下永远不会调用我的自定义“产生冲突”合并驱动程序。如果是的话,那么我的“部分解决方案#2”就会真正起作用。

可以通过调整文件或配置来改变这种行为吗?或者也许有一种方法可以创建自定义差异驱动程序?我还没准备好开始使用 Git 源代码......

有什么巧妙的想法吗?


我希望能够执行此差异before合并,包括没有合并冲突的文件。

您只需根据需要设置索引,无需提交结果。准确设置所要求内容的方法是,直接 diffs-since-base 而不进行合并准备

git merge -s ours --no-ff --no-commit $your_other_tip

一个完整的手卷,其中 git 只为您最终决定提交的任何内容设置父级,但最好通过正常合并来完成此操作,同时仍然能够进入那里并检查所有内容,

git merge --no-ff --no-commit $your_other_tip

选择你的起点,然后

  1. 对显示任何更改的所有条目强制进行合并访问 任一提示:

    #!/bin/sh
    
    git checkout -m .
    
    # identify paths that show changes in either tip but were automerged
    scratch=`mktemp -t`
    sort <<EOD | uniq -u >"$scratch"
    $(  # paths that show changes at either tip:
        (   git diff --name-only  ...MERGE_HEAD
            git diff --name-only  MERGE_HEAD...
        ) | sort -u )
    $(  # paths that already show a conflict:
        git ls-files -u | cut -f2- )
    EOD
    
    # un-automerge them: strip the resolved-content entry and explicitly 
    # add the base/ours/theirs content entries
    git update-index --force-remove --stdin <"$scratch"
    stage_paths_from () {
            xargs -a "$1" -d\\n git ls-tree -r $2 |
            sed "s/ [^ ]*//;s/\t/ $3\t/" |
            git update-index --index-info
    }
    stage_paths_from "$scratch" $(git merge-base @ MERGE_HEAD) 1 
    stage_paths_from "$scratch" @ 2
    stage_paths_from "$scratch" MERGE_HEAD 3
    
  2. ...如果你使用 vimdiff,第 2 步就只是git mergetool。 vimdiff 从工作树中的内容开始,并且不执行自己的自动合并。看起来 kdiff3 想要忽略工作树。无论如何,将其设置为在没有 --auto 的情况下运行看起来并不像too太老套了:

    # one-time setup:
    wip=~/libexec/my-git-mergetools
    mkdir -p "$wip"
    cp -a "$(git --exec-path)/mergetools/kdiff3" "$wip"
    sed -si 's/--auto //g' "$wip"/kdiff3
    

    然后你就可以

    MERGE_TOOLS_DIR=~/libexec/my-git-mergetools git mergetool
    

从这里退出只是平常的事git merge --abort or git reset --hard.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Git 中执行三向比较而不合并? 的相关文章

  • Python:合并嵌套列表

    初学者在这里 我有 2 个要合并的嵌套列表 list1 a b c d e f g h list2 p q r s t u v w 我正在寻找的输出是 list3 a p q b c r s d e t f g h u v w 这可以在没有
  • 使用与后期步骤中的 Shell 脚本中的克隆相同的 http git 凭据

    我想要自动化我们的发布过程 并且我有一个 Maven 项目的以下 Jenkins 构建作业 使用配置的 Jenkins 凭证 用户名 密码 克隆 Git 存储库 执行一些 Maven 命令以进行构建 配置一个后步骤来执行一些额外的 Git
  • 在 GitHub 上更新拉取请求后如何恢复审核流程?

    我分叉了 GitHub 存储库并创建了拉取请求 审稿人要求我修改 要求更改1 条评论请求由具有写入权限的审阅者进行更改 了解更多 https docs github com en github collaborating with issu
  • 使用 'gitbranch' 命令显示当前 git 分支

    我在处理太多分支时遇到问题 需要花费很多时间才能找到我现在正在处理的当前分支 有没有办法在使用时显示的列表顶部列出当前分支git branch命令 如果您只想要签出分支 请使用git branch show current
  • git push heroku master 通过代理后面的 ssh 出现错误

    简要背景 大家好 我是一名大学生 代理 10 3 100 211 8080 刚接触 ROR Git 和 Heroku 一直在关注 Ruby on Rails 教程 我解决了通过 ssh 推送 git repo 的问题 在我的 ssh con
  • TFS 2012 .gitignore .hgignore 等效项

    在TFS 2012中 有一种新的本地工作模式 本地工作区 这是个好消息 没有 签出 文件 使用 VS 以外的程序中的文件时 不会再出现只读文件和问题 不再有 获取最新 实际上并未获取最新的情况 但这也意味着我需要一种方法来告诉 TFS 在监
  • git-http-backend 与 AuthzUnixGroup 无法正常工作

    我正在尝试在 CentOS 6 机器上的 Apache 2 2 上设置一个 git 存储库 并安装了 git 我尝试过许多不同的方向 但我却不知所措 我目前的情况包括能够clone正常 但完全无法推动 似乎我无法使身份验证位正常工作 因为我
  • 克隆存储库时出现 Git 冲突复制错误

    我使用 dropbox 作为 git 存储库 现在由于同步中的一些问题 git 中存在一些冲突的副本 我该如何消除这种冲突 由于这种冲突 我无法克隆该存储库的内容 我在克隆存储库时遇到的错误是 Git 致命 参考格式无效 refs head
  • 我可以在 git 中使用单个命令推送到多个存储库吗?

    基本上我想做一些类似的事情git push mybranch to repo1 repo2 repo3 现在我只是多次输入push 如果我急于完成push 我只需将它们全部发送到后台git push repo1 git push repo2
  • Accurev 性能如何?

    当前版本 4 7 的性能如何Accurev http www accurev com 每 100mb 每 GB 的结账时间 每 个文件或 mb 的提交时间 当 100 流时 gui 的响应能力 我刚刚进行了 Accurev 的演示 这些流看
  • XSLT 分组/合并子项(使用密钥)

    我试图了解如何使用我已经编写的代码推导出解决方案 为了简化起见 我将首先解释我想要做什么以及到目前为止我得到了什么 假设我在 XSLT 中有一个 XML 变量 其中包含几个具有相同标题属性的节点 Using Dimitre Novatche
  • 恢复后如何挑选提交?

    我正在研究我的feature branch并在审核后合并到development待部署 后来 一位同事决定发布一个版本 并将他和我的合并到master 在部署时 他意识到他的代码有错误并恢复了master 在我们的分叉和拉动流程中 这意味着
  • 无法使用 File delete() 方法删除 git repo 中的 .pack 文件

    对于我正在编写的这个方法 我使用 jgit 库克隆一个 git 存储库 然后对这些文件执行一些操作 最后我想删除该存储库 我遇到的问题是 当我在 pack 文件 位于 git objects pack 中 上调用 delete 方法时 它无
  • 使用 .NET SDK / C# 在 StarTeam 中查找文件的过去修订版本

    我正在尝试编写一个 C 程序来比较 StarTeam 存储库中不同版本的文件 查看文件的当前版本与给定的先前签入之间是否有任何更改 我目前能够从当前版本中查找 签出文件 但很难找到正确的方法来查找这些文件的过去版本 至少在 NET 方面 B
  • Git推送更新远程服务器信息失败

    当我尝试将新分支推送到远程源时 出现以下错误 我能够在现有分支上推送提交 并且现有分支上没有问题 git push u origin master1 Fetching remote heads refs refs tags refs hea
  • 如何归档旧的 git 标签?

    我的 git 存储库中有一些不再重要的旧标签 我想存档标签 以便在运行 git tag 时默认情况下它们不会显示 我不想删除它们 因为我想保留历史记录 我怎样才能做到这一点 可以将标签保留在存储库中并避免将它们列为标签 它还可以避免默认克隆
  • 在 PowerShell 错误消息中使用 touch 命令创建新文件

    我的桌面上有一个使用 PowerShell 创建的目录 现在我尝试在其中创建一个文本文件 我确实将目录更改为新目录 然后输入touch textfile txt 这是我收到的错误消息 touch The term touch is not
  • 如何忽略Git中以数字开头的文件?

    在某个文件夹中 我有名为foo jpg bar png等等 我想将它们保留在版本控制中 除了那些命名为1 baz png 2 zaz jpg等 因为它们实际上是生成的 我应该添加什么条目 gitignore 正则表达式如 0 9 似乎不起作
  • 使用 Dropbox 作为跨多台机器的 git 工作目录 - 提交不能完美同步

    首先 我想强调这个问题与在 Dropbox 上托管我的中央存储库无关 而且我对使用 git 还很陌生 我能找到的其他涉及 Dropbox 和 git 的问题都没有真正回答我的问题 它们要么是关于使用 Dropbox 托管您的存储库 要么是关
  • git stash 和编辑帅哥

    我完全喜欢git add p and git stash但我偶尔会遇到以下问题 该问题是通过以下命令序列重现的 git add p my file 然后我手动编辑大块 using e 因为 git 建议的分割不适合我 git stash k

随机推荐

  • 如何从oracle表的多个分区中选择数据

    我正在尝试从分区表中的多个分区中选择数据 它适用于单个分区 select from table partition ParititonName 但不能选择多个分区 select from table partitions Part1 par
  • 添加自定义转换类型以进行字符串格式化

    python 中是否有向字符串格式添加额外的转换类型 使用的标准转换类型 基于字符串的格式化是这样的s对于字符串 d我想要做的是添加一个新字符 我可以为其指定一个自定义处理程序 例如 lambda 函数 该处理程序将返回要插入的字符串 例如
  • 在 C# 中将列表设置为只读

    我有这个示例代码 我想要做的是使 Nums 值只能使用 AddNum 方法写入 namespace ConsoleApplication1 public class Person string myName N A int myAge 0
  • ExecutorService 超时但不阻塞主线程

    我想在有时间限制的后台执行一些工作 问题是 我不想阻塞主线程 简单的实现是有两个执行器服务 一个负责安排 超时 第二个负责完成工作 final ExecutorService backgroundExecutor Executors new
  • F# 如何捕获所有异常

    我知道如何捕获特定异常 如下例所示 let test zip archive candidate zip archive let rc try ZipFile Open candidate zip archive ToString ZipA
  • Laravel 5.8 中 Auth::user() 返回 null

    我的 Laravel 5 8 10 项目中遇到身份验证问题 我没有使用 Laravel 创建的默认表单进行身份验证 当我在浏览器中访问 URL 仪表板时 通常用户会在登录时获得重定向 无论如何 应用程序允许它 另外当我使用时Auth use
  • TYPE_E_CANTLOADLIBRARY 仅当在 Windows 2003 x64 上的单独线程上使用 COM 对象时

    我有一个访问 COM 对象的 Windows 窗体应用程序 编译为 x86 它给了我以下错误 only在 Windows 2003 x64 上 当代码在单独的线程上运行时 创建 IDoc 期间出现异常 无法将类型 PTISG COM Tek
  • 修复 ARC 中潜在的内存泄漏

    以下单例类 SharedManager 辅助方法可能会导致保留周期 在静态分析器中收到警告 在行分配的对象的潜在泄漏 我该如何修复 我确实尝试使 ivar uuid weak 但在分析时仍然出现警告 NSString weak uuid b
  • std::numeric_limits::epsilon() 可以用来做什么?

    unsigned int updateStandardStopping unsigned int numInliers unsigned int totPoints unsigned int sampleSize double max hy
  • 有没有办法阻止 contentEditable 元素在光标到达底部时滚动?

    例如 我有一个 contentEditable div 我可以在其中输入内容 当文本到达 div 底部时 浏览器会自动滚动 div 以便文本末尾和光标仍然可见 如何防止 div 滚动 以便输入的文本超出 div 的底部 从而在键入时不再看到
  • 将二维 ArrayList 复制为新的

    所以我遇到的问题是在复制二维数组列表后 更改一个二维数组列表中的元素会影响另一个二维数组列表 我希望它们在内存中完全分开 第一个示例展示了它如何正确处理一维数组列表 import java util ArrayList public cla
  • 正则表达式匹配以测试有效年份

    给定一个值 我想验证它以检查它是否是有效的年份 我的标准很简单 其中值应该是整数4人物 我知道这不是最好的解决方案 因为几年前它不允许1000并将允许诸如5000 这个标准足以满足我当前的情况 我想出的是 d 4 虽然这有效 但它也允许负值
  • 性能:使用 JCIF 将文件复制到 Windows 网络的速度非常慢

    我正在尝试将文件从本地计算机复制到 Windows 服务器中的共享文件夹 这是我使用的功能 public static void copyFileUsingJcifs final String domain final String use
  • 如何将新工具箱添加到已安装的 Matlab 版本中?

    我需要向我的 Matlab Student 版本添加一个工具箱 我知道我必须下载工具箱文件 将它们放在某个目录中 然后指定路径 但是 我不太确定必须将文件放在哪里 我下载了两个 zip 存档 Symbolic Math Toolbox Co
  • 如何在 MMT 中粘合/识别两个结构中的内含物?

    我想形式化形式语言及其语义MMT https uniformal github io 并定义一个一般概念语义等价两种语义 one句法 准确地说 对后者进行编码实际上是一种识别 粘合 我不知道如何在 MMT 中做到这一点 接下来让我详细说明我
  • IE6 将 DOCTYPE 更改为错误的 DOCTYPE

    我正在使用定义了以下内容的网站DOCTYPE 当我访问该网站时IE6 DOCTYPE神奇地变成了 而且 好吧 它可以保留 因为一切看起来都很好 但这是重点 只有一页有DOCTYPE变成
  • 如何编写使用OpenERP ORM直接上传到Postgres数据库的Python脚本

    我需要在 Python 中编写一个 独立 脚本 仅使用 OpenERP 的 ORM 模块将销售税上传到数据库中的 account tax 表 我想做的是类似下面的伪代码 有人可以向我提供有关以下内容的更多详细信息 1 我需要设置什么sys
  • ImageView 内的 Android ProgressBar

    我有一个活动通过异步任务用数据填充列表视图 另外 我正在后台加载图片 在加载图片时 我想在图像视图中显示进度条而不是默认图标 我在互联网上搜索了任何示例等 但找不到任何有用的东西 我只找到一个响应 它说您必须使用图像视图和进度条进行框架布局
  • JQuery获取formaction和formmethod

    我有一个像这样的
  • 如何在 Git 中执行三向比较而不合并?

    我想在具有公共合并基础的两个 git 分支之间执行三向差异 并使用 kdiff3 查看它 我发现了很多关于SO的指导 以及一些非常相似的问题 1 https stackoverflow com q 26301307 3380131 2 ht