天天看點

配置Beyond Compare 4作為git mergetool來解決git merge指令導緻的檔案沖突前言解決方案Beyond Compare檔案沖突及處理工具配置的參數含義思考總結

文章目錄

  • 前言
  • 解決方案
    • 前提
    • 配置
  • Beyond Compare
  • 檔案沖突及處理
    • 産生沖突
    • 解決沖突
  • 工具配置的參數含義
    • git config
    • git mergetool
  • 思考
  • 總結

前言

使用

git merge

指令合并代碼的時候可能會産生檔案沖突,産生這種沖突的根本原因是檔案的同一處同時被多次修改,這種同時修改常展現的不同分支上,當多個分支修改了同一處代碼,再合并代碼的時候就會産生沖突,因為

git

程式也不知道我們想要保留哪一份修改,這時就需要我們手動修改産生沖突的檔案。

當沖突内容很少的時候我們可以打開文本編輯器,找到

>>>>>>>>>>>>

===========

<<<<<<<<<<<<

這三行字元包裹的内容就是需要解決沖突的部分,但是當沖突内容特别多時我們還是習慣于通過可視化的工具來處理,

Beyond Compare

就是這樣一款工具,可以用來比較不同的文本檔案、表格檔案,還可以比較檔案夾内容,之前用着比較習慣,是以在處理

git

沖突的時候也想使用這個工具來做,通過查找技術文檔發現了下面的方法。

解決方案

鑒于大家都比較急,查找問題時想要直接找到答案,是以我這裡直接說明配置步驟,送給不求甚解的小夥伴,也友善今後我可以直接找到,不過配置之前還是要先看一下前提。

前提

  • 在 Windows 上安裝了

    git

    用戶端,可以執行

    git

    指令(廢話!沒裝

    git

    怎麼産生沖突的)
  • 安裝了

    Beyond Compare 4

    這個軟體,下載下傳連結很多,自己找一個吧,實在找不到,那就放棄吧(找我要)

配置

首先找到

Beyond Compare

的安裝路徑,比如我的軟體安裝路徑是

D:\mybc4\BComp.exe

,然後在

git

指令行用戶端中執行下面指令:

git config --global merge.tool bc4
git config --global mergetool.bc4.cmd "\"D:\\mybc4\\BComp.exe\" \"\$LOCAL\" \"\$REMOTE\" \"\$BASE\" \"\$MERGED\""
git config --global mergetool.bc4.trustExitCode true
git config --global mergetool.keepBackup false
           

至此,

git mergetool

就配置完了,當下次沖突的時候,直接使用

git mergetool

指令就可以調用

Beyond Compare

解決沖突檔案了,但是你不好奇,這些設定指令都是什麼意思嗎?為什麼執行完這些指令就能調用

Beyond Compare 4

這個軟體了,如果你感興趣可以接下往下看一看。

Beyond Compare

這是一款強大的比較工具,前面提到它可以比較文本、比較表格、比較檔案夾,但是它的能力不僅限于此,它甚至可以比較MP3、比較圖檔、比較系統資料庫,我們的目的是調用它的比較功能,但是前提是這款軟體允許你調用,如果它不給你提供接口,你就是想調用也得繞上八百個圈才可以。

這一點我們可以查詢文檔确定,文檔是安裝軟體時自帶的,名字為

BCompare.chm

,如果找不到,安利你一個叫做

Everything

的軟體,裝上它以後,電腦中的一切東西都能搜尋找到。

這個文檔應該很容易找到的,與軟體的可執行檔案在同一目錄,其實我們使用的比較工具應該是

BCompare.exe

,但是為什麼在配置

git mergetool

的是後用的是

BComp.exe

呢?這一點文檔中有寫:

BCompare.exe: This is the main application. Only one copy will run at a time, regardless of how many windows you have open. If you launch a second copy it will tell the existing copy to start a comparison and exit immediately.

BComp.exe: This is a Win32 GUI program. If launched from a version control system, it should work just fine. If launched from a console window, the console (or batch file) will not wait for it.

文檔是英文的,但是比較容易了解,總的來說

BCompare.exe

是主程式,

BComp.exe

用在版本控制工具中更加優秀,至于文檔中提到的主程式隻能啟動一個副本的說明,我試了一下并不是這樣的,但是這不是重點,根據文檔建議,我們應該調用

BComp.exe

程式。

關于調用參數,文檔中對于每種形式的比較也給出了說明,我們這裡隻列舉兩個檔案和四個檔案這兩種參數,兩個檔案作為參數時常用來對比,我直接使用主程式對比檔案就是這種形式,參數格式為

BCompare.exe "C:\Left File.ext" "C:\Right File.ext"

,但是使用時我常把檔案直接拖拽到軟體上進行比較。四個檔案作為參數時常用來處理檔案沖突,參數類型為

BCompare.exe C:\Left.ext C:\Right.ext C:\Center.ext C:\Output.ext

,參數中檔案的名字表明處理時的位置和作用,看下面這個圖就明白了。

配置Beyond Compare 4作為git mergetool來解決git merge指令導緻的檔案沖突前言解決方案Beyond Compare檔案沖突及處理工具配置的參數含義思考總結

從紅框圈定的位置就可以發現和檔案的對應關系了,最下面是最終的輸出檔案,也是我們可以手動修改的檔案。

檔案沖突及處理

産生沖突

先看一下

git

倉庫的原始情況

[email protected] MINGW64 /d/gitstart (dev)
$ git status
On branch dev
Your branch is up to date with 'origin/dev'.

nothing to commit, working tree clean

[email protected] MINGW64 /d/gitstart (dev)
$ ls
README.md

[email protected] MINGW64 /d/gitstart (dev)
$ cat README.md
learn git branch command
m2
test checkout
           

在此基礎上建立兩個分支

dev1

dev2

[email protected] MINGW64 /d/gitstart (dev)
$ git checkout -b dev1
Switched to a new branch 'dev1'

[email protected] MINGW64 /d/gitstart (dev1)
$ git checkout -b dev2
Switched to a new branch 'dev2'

[email protected] MINGW64 /d/gitstart (dev2)
$ git branch | grep dev
  dev
  dev1
* dev2
           

dev2

分支上修改

README.md

檔案後送出

[email protected] MINGW64 /d/gitstart (dev2)
$ echo "this is dev2 test">>README.md

[email protected] MINGW64 /d/gitstart (dev2)
$ git add README.md
warning: LF will be replaced by CRLF in README.md.
The file will have its original line endings in your working directory

[email protected] MINGW64 /d/gitstart (dev2)
$ git commit -m"update readme at dev2"
[dev2 d8d80b7] update readme at dev2
 1 file changed, 1 insertion(+)

[email protected] MINGW64 /d/gitstart (dev2)
$ cat README.md
learn git branch command
m2
test checkout
this is dev2 test
           

切換回

dev1

分支修改

README.md

檔案後送出

[email protected] MINGW64 /d/gitstart (dev2)
$ git checkout dev1
Switched to branch 'dev1'

[email protected] MINGW64 /d/gitstart (dev1)
$ echo "this is dev1 test">>README.md

[email protected] MINGW64 /d/gitstart (dev1)
$ git add README.md
warning: LF will be replaced by CRLF in README.md.
The file will have its original line endings in your working directory
git com -
[email protected] MINGW64 /d/gitstart (dev1)
$ git commit -m"update readme at dev1"
[dev1 3136341] update readme at dev1
 1 file changed, 1 insertion(+)

[email protected] MINGW64 /d/gitstart (dev1)
$ cat README.md
learn git branch command
m2
test checkout
this is dev1 test
           

這時在

dev1

分支上合并

dev2

分支上的修改就會産生沖突

[email protected] MINGW64 /d/gitstart (dev1)
$ git merge dev2
Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
Automatic merge failed; fix conflicts and then commit the result.

[email protected] MINGW64 /d/gitstart (dev1|MERGING)
$ cat README.md
learn git branch command
m2
test checkout
<<<<<<< HEAD
this is dev1 test
=======
this is dev2 test
>>>>>>> dev2

[email protected] MINGW64 /d/gitstart (dev1|MERGING)
$ ls
README.md
           

沖突産生了,文檔中同一位置被兩個分支修改後合并導緻的,内容裡出現了

<<<

===

>>>

,包裹的内容被分成了兩部分,上面一部分是目前分支修改的,下面一部分是從

dev2

分支合并過來的,還要注意雖然産生了産生了沖突,但是目錄中并沒有産生其他多餘的檔案。

解決沖突

這樣的沖突比較簡單,我們隻要使用文本工具删除不想要的内容,儲存後

git add README.md

,然後再

git commit

就完成了沖突的解決,但是因為配置了

git mergetool

,我們可以用它來解決沖突,直接在指令行敲指令

git mergetool

就可以:

[email protected] MINGW64 /d/gitstart (dev1|MERGING)
$ git mergetool
Merging:
README.md

Normal merge conflict for 'README.md':
  {local}: modified file
  {remote}: modified file

           

這時光标不會退出,一閃一閃并且打開

BComp.exe

工具,截圖如下:

配置Beyond Compare 4作為git mergetool來解決git merge指令導緻的檔案沖突前言解決方案Beyond Compare檔案沖突及處理工具配置的參數含義思考總結

這時如果你打開

git

庫所在目錄會發現除了

README.md

還多了下面4個檔案:

README.md
README_BACKUP_584.md
README_BASE_584.md
README_LOCAL_584.md
README_REMOTE_584.md
           

按照自己的實際情況修改最下面的檔案,然後點選箭頭所指的儲存按鈕,關閉

Beyond Compare

,查詢一下倉庫狀态

[email protected] MINGW64 /d/gitstart (dev1|MERGING)
$ git status
On branch dev1
All conflicts fixed but you are still merging.
  (use "git commit" to conclude merge)

Changes to be committed:
        modified:   README.md

[email protected] MINGW64 /d/gitstart (dev1|MERGING)
$ ls
README.md
           

不但沖突檔案沒有了,還給我們自動執行

git add README.md

指令,我們隻需要執行

git commit

就解決完了沖突。

[email protected] MINGW64 /d/gitstart (dev1|MERGING)
$ git commit
[dev1 b348ae6] Merge branch 'dev2' into dev1

[email protected] MINGW64 /d/gitstart (dev1)
$ git adog
*   b348ae6 (HEAD -> dev1) Merge branch 'dev2' into dev1
|\
| * d8d80b7 (dev2) update readme at dev2
* | 3136341 update readme at dev1
|/
* 5f4181e (origin/dev, dev) add comments
           

工具配置的參數含義

回過頭來再看看

git mergetool

的4句配置到底有什麼用

git config --global merge.tool bc4
git config --global mergetool.bc4.cmd "\"D:\\mybc4\\BComp.exe\" \"\$LOCAL\" \"\$REMOTE\" \"\$BASE\" \"\$MERGED\""
git config --global mergetool.bc4.trustExitCode true
git config --global mergetool.keepBackup false
           

git config

首先你需要知道

git config

的作用,就是用來配置

git

的,加上了

--global

表示調整全局

git

配置,不加的話就是調整目前庫的

git

配置。windows上的全局配置一般在

C:\Users\使用者名\.gitconfig

,如果你之前用過

git

,一般會執行過

git config --global user.name xxx

對吧,這些指令都是來調整

git

配置的,打開這個

.gitconfig

你會看到

[user]
    name = albert
    email = [email protected]
[core]
    autocrlf = true
[alias]
    st = status
    adog = "log --all --decorate --oneline --graph"
[merge]
    tool = bc4
[mergetool "bc4"]
    cmd = \"D:\\mybc4\\BComp.exe\" \"$LOCAL\" \"$REMOTE\" \"$BASE\" \"$MERGED\"
    trustExitCode = true
[mergetool]
    keepBackup = false
           

看看最後幾行就是我們添加的4項配置,隻不過到檔案中變成了鍵值對的形式,經過測試後發現,這些屬性最少兩級,比如

user.name

core.autocrlf

,最多三級比如

mergetool.bc4.cmd

mergetool.bc4.trustExitCode

,如果級數再多會怎麼辦,你可以試試

git config --global a.b.c.d.e test

,它最終也會被拆成三級如下

[a "b.c.d"]
    e = test
           

git mergetool

這個需要查一下官方文檔了,

git mergetool --help

就能打開git官方文檔,文檔寫得真不錯,排版格式看着就很舒服。

文檔提到添加

--tool-help

選項可以列舉可以的合并工具,展示如下

[email protected] MINGW64 /d/gitstart (dev1)
$ git mergetool --tool-help
'git mergetool --tool=<tool>' may be set to one of the following:
                vimdiff
                vimdiff2
                vimdiff3

        user-defined:
                bc4.cmd "D:\Program Files\Beyond Compare 4\BComp.exe" "$LOCAL" "$REMOTE" "$BASE" "$MERGED"

The following tools are valid, but not currently available:
                araxis
                bc
                bc3
                codecompare
                deltawalker
                diffmerge
                diffuse
                ecmerge
                emerge
                examdiff
                guiffy
                gvimdiff
                gvimdiff2
                gvimdiff3
                kdiff3
                meld
                opendiff
                p4merge
                smerge
                tkdiff
                tortoisemerge
                winmerge
                xxdiff

Some of the tools listed above only work in a windowed
environment. If run in a terminal-only session, they will fail.
           

這一查才發現,原來

git mergetool

支援的工具有這麼多,不過下面這些我都沒安裝,用一下上面列舉的3個,試試

git mergetool --tool=vimdiff

,果然打開了一個界面

配置Beyond Compare 4作為git mergetool來解決git merge指令導緻的檔案沖突前言解決方案Beyond Compare檔案沖突及處理工具配置的參數含義思考總結

幸虧不如

Beyond Compare

好用,不然我不是白配置了,不過這些工具确實友善,都不需要配置,隻要安裝了參數中指定一下就可以用了,比如這個

bc3

,我猜它是

Beyond Compare 3

,隻不過我安裝的是

Beyond Compare 4

這個版本。

這些内置工具使用的前提是已經安裝了,并且安裝軟體的目錄放在了環境變量

Path

中,如果沒有放在這個變量中需要通過

mergetool.<tool>.path

參數來配置,比如我把

Beyond Compare 3

安裝在了

D

盤根目錄,就可以設定

git config --global mergetool.bc3.path "D:\\"

我們在可用工具中沒有找到

Beyond Compare 4

為什麼我們可以用呢?因為

git mergetool

指令還支援自定義合并解決沖突的工具,隻要指定

mergetool.<tool>.cmd

就可以調用了,就像

git mergetool --tool-help

查詢結果中提到的

user-defined: bc4.cmd "D:\Program Files\Beyond Compare 4\BComp.exe" "$LOCAL" "$REMOTE" "$BASE" "$MERGED"

git mergetool

bc4

作為了一個等同于内置合并工具的軟體。

再來看看這4句配置的含義:

git config --global merge.tool bc4
git config --global mergetool.bc4.cmd "\"D:\\mybc4\\BComp.exe\" \"\$LOCAL\" \"\$REMOTE\" \"\$BASE\" \"\$MERGED\""
git config --global mergetool.bc4.trustExitCode true
git config --global mergetool.keepBackup false
           

第一句

git config --global merge.tool bc4

是說把

git mergetool

的預設工具配置成

bc4

,如果不指定預設工具在使用時就需要寫成

git mergetool --tool=bc4

或者

git mergetool -t bc4

了,可是

bc4

是我們自己起的名字,根本就沒有這個名字啊,接着往下看。

第二句

git config --global mergetool.bc4.cmd "\"D:\\mybc4\\BComp.exe\" \"\$LOCAL\" \"\$REMOTE\" \"\$BASE\" \"\$MERGED\""

指定了工具

bc4

的調用路徑和參數,後面的這4個參數都是

git mergetool

指令提供的,依次代表本地修改,被合并分支修改,兩端未修改前版本檔案,最終合并導出的文本檔案。

第三句

git config --global mergetool.bc4.trustExitCode true

, 設定為

true

表示信任軟體的傳回碼,并依據傳回碼确定合并是否成功,如果設定成

false

就會在合并完成後問你是否解決完沖突,設定成

true

會友善很多。

第四句

git config --global mergetool.keepBackup false

, 是指定在合并完成後删除備份檔案

*.orig

,這個檔案會在調用

git mergetool

是産生

*.orig

備份檔案,成功合并後自動删除就可以了。

思考

至此終于弄明白這個

git mergetool

是怎麼工作的了,但是想這樣一個問題,這個

<tool>.cmd

一定得調用沖突解決工具嗎?如果你從頭看到這裡應該會明白,這裡隻是給使用者提供了一個調用自定義工具的方式,至于你調用什麼它是不關心的,你完全可以在

git mergetool

的時候讓電腦關機,這些都是可以的,在你明白了原理以後,一切都變得簡單了。

總結

  • Beyond Compare

    是一款強大的比較工具,合理的使用可以有效的提升工作效率
  • git mergetool

    内置了很多可以使用的合并工具,并且支援調用自定義的合并工具
  • git

    的官方文檔寫得真的挺詳細,有時間可以多看一看,你會發現很多有意思的功能
  • 急于解決問題時可以不求甚解,解決問題後最好可以明白其中的緣由,這其實就是一種進步
盡管科技很發達,但有些人一旦分開可能真的就是一生不見了