bit*_*ack 23 git version-control diff merge
我想在具有公共合并基础的两个git分支之间执行三向差异,并使用kdiff3查看它.
我发现很多指导对SO(和一些非常相似的问题(1,2,3)),但我还没有找到一个直接的答案.值得注意的是,对这个答案的评论意味着我想要的是可能的,但它对我不起作用.希望用户可以在这里ch :) :)
对于背景,当我执行合并时,我使用"diff3"冲突样式:
git config --global merge.conflictstyle diff3
我已git mergetool配置为使用kdiff3.
解决合并冲突时,这会显示四个文件:
但是,git difftool只会拉起两个分支提示.我也希望看到基本文件. 为了清楚起见,我希望能够在合并之前执行此差异,包括没有合并冲突的文件.(git mergetool如果存在冲突,则仅显示三向差异).
部分解决方案#1:
使用单个文件,我可以导出三个版本并手动调用diff:
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 &
Run Code Online (Sandbox Code Playgroud)
这有两个问题:
部分解决方案#2:
创建一个始终返回"false"的自定义合并驱动程序,这会创建一个冲突的合并状态,而不会实际执行任何自动合并.然后执行diff使用git mergetool.然后在完成后中止合并.
添加到.git/config:
[merge "assert_conflict_states"]
name = assert_conflict_states
driver = false
Run Code Online (Sandbox Code Playgroud)创建(或追加).git/info/attributes以使所有合并使用新驱动程序:
* merge=assert_conflict_states
Run Code Online (Sandbox Code Playgroud)执行合并,现在不执行任何自动播放.
做差异.在我的情况下:git mergetool它带来了kdiff3三向合并.
完成后,中止合并:git merge --abort.
撤消步骤#2.
这将(sorta)工作,除了kdiff3在调用时执行automerge,所以我仍然看不到预合并的差异.不过,我可以通过更改Git的股票kdiff3驱动程序文件(.../git-core/mergetools/kdiff3通过删除--auto开关来解决这个问题).
即便如此,这还有以下显示停止问题:
attributes在做差异之前和之后修改.赏金信息:
根据给出的答案,使用标准Git是不可能的.所以现在我正在寻找一个更开箱即用的解决方案:我如何调整Git来实现这一目标?
这是一个主角:显然,如果三个文件中只有一个发生了变化,则在合并结果中使用这个较新的文件而不实际调用合并驱动程序.这意味着在这种情况下永远不会调用我的自定义"冲突创建"合并驱动程序.如果是,那么我的"部分解决方案#2"实际上将起作用.
可以通过调整文件或配置来改变这种行为吗?或许有一种方法可以创建自定义差异驱动程序?我还没准备好开始玩Git源代码......
任何聪明的想法?
jth*_*ill 10
我希望能够在合并之前执行此差异,包括没有合并冲突的文件.
您只需要根据需要设置索引,就不必提交结果.设置完全所要求的方式,直接diffs-since-base,没有合并准备,是
git merge -s ours --no-ff --no-commit $your_other_tip
Run Code Online (Sandbox Code Playgroud)
一个完整的手册,其中git只为你最终决定提交的内容设置父母作为结果,但是最好通过正常的合并来做到这一点,同时仍然可以进入并检查所有内容,
git merge --no-ff --no-commit $your_other_tip
Run Code Online (Sandbox Code Playgroud)
选择你的起点,然后
强制对所有条目进行合并访问,以显示任一提示中的任何更改:
#!/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
Run Code Online (Sandbox Code Playgroud)...如果你使用vimdiff,第2步就是git mergetool.vimdiff从worktree中的内容开始,并没有自己的automerge.看起来kdiff3想要忽略工作树.安美居,将其设置为运行不--auto看起来并不太多太哈克:
# 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
Run Code Online (Sandbox Code Playgroud)
然后你就可以了
MERGE_TOOLS_DIR=~/libexec/my-git-mergetools git mergetool
Run Code Online (Sandbox Code Playgroud)退出这是通常的git merge --abort或git reset --hard.
| 归档时间: |
|
| 查看次数: |
4578 次 |
| 最近记录: |