Meld 合并工具使用指南(Ubuntu)

一、安装

1.1 常规安装

sudo apt update
sudo apt install meld

1.2 安装时遇到 dpkg 中断

# 先修复 dpkg
sudo dpkg --configure -a
 
# 再安装
sudo apt install meld

1.3 安装时遇到某个包损坏(无法找到安装文件)

# 强制移除损坏的包(替换 <package-name> 为实际包名)
sudo dpkg --remove --force-remove-reinstreq <package-name>
 
# 修复依赖后安装
sudo apt update && sudo apt install -f && sudo apt install meld

1.4 验证安装

meld --version

二、配置 Git 使用 Meld

2.1 设为默认合并工具

git config --global merge.tool meld
git config --global mergetool.keepBackup false

2.2 设为默认 diff 工具

git config --global diff.tool meld
git config --global difftool.prompt false

2.3 验证配置

git config --global --list | grep -E "merge|diff"

三、使用场景

3.1 解决 merge 冲突

# 合并分支产生冲突
git merge feature-branch
# 输出: CONFLICT (content): Merge conflict in src/foo.cc
 
# 打开 Meld 逐个解决冲突文件
git mergetool

Meld 三栏界面说明:

位置内容说明
左栏LOCAL当前分支的版本
中栏MERGED最终结果(在这里编辑)
右栏REMOTE要合并进来的版本

操作方式:点击箭头选择保留哪边的代码,或直接在中栏手动编辑。保存并关闭窗口即完成该文件的冲突解决。

3.2 解决 rebase 冲突

git rebase main
# 出现冲突
 
git mergetool
# 解决后继续 rebase
git rebase --continue

3.3 解决 stash pop 冲突

git stash pop
# CONFLICT (content): Merge conflict in xxx
 
git mergetool
# 解决后
git add .

3.4 解决 cherry-pick 冲突

git cherry-pick <commit-hash>
# 出现冲突
 
git mergetool
git cherry-pick --continue

3.5 查看当前工作区改动

# 查看所有未提交的改动(逐文件打开 Meld)
git difftool
 
# 查看某个具体文件的改动
git difftool -- src/foo.cc

3.6 对比两个分支的差异

git difftool main..feature-branch
git difftool main..feature-branch -- src/specific_file.cc

3.7 对比某次 commit 的改动

git difftool HEAD~1..HEAD
git difftool <commit-hash>^..<commit-hash>

3.8 直接对比文件/目录(不依赖 Git)

# 对比两个文件
meld file_a.txt file_b.txt
 
# 对比两个目录
meld dir_a/ dir_b/
 
# 三路对比
meld file_local file_base file_remote

四、冲突解决策略速查

当你不想手动逐个解决,可以批量选择一边的代码:

# 全部采用当前分支的版本(丢弃对方改动)
git checkout --ours -- <file>
 
# 全部采用对方分支的版本(丢弃自己改动)
git checkout --theirs -- <file>
 
# 批量处理所有冲突文件(采用对方版本)
git diff --name-only --diff-filter=U | xargs git checkout --theirs --
 
# 批量处理所有冲突文件(采用自己版本)
git diff --name-only --diff-filter=U | xargs git checkout --ours --

五、Git 日常命令速查

5.1 分支管理

# 查看所有分支
git branch -a
 
# 创建并切换分支
git checkout -b <branch-name>
 
# 删除本地分支
git branch -d <branch-name>
 
# 删除远程分支
git push origin --delete <branch-name>
 
# 重命名当前分支
git branch -m <new-name>

5.2 暂存与恢复(stash)

# 暂存当前改动
git stash
 
# 暂存并附带说明
git stash push -m "描述信息"
 
# 查看 stash 列表
git stash list
 
# 恢复最近的 stash(保留 stash 记录)
git stash apply
 
# 恢复最近的 stash(删除 stash 记录)
git stash pop
 
# 恢复指定的 stash
git stash apply stash@{2}
 
# 删除某个 stash
git stash drop stash@{0}
 
# 清空所有 stash
git stash clear

5.3 撤销与回退

# 撤销工作区某文件的修改(未 add)
git checkout -- <file>
 
# 取消暂存(已 add,未 commit)
git reset HEAD <file>
 
# 撤销上次 commit(保留改动在工作区)
git reset --soft HEAD~1
 
# 撤销上次 commit(保留改动在暂存区)
git reset --mixed HEAD~1
 
# 彻底回退到某个 commit(丢弃所有改动,慎用)
git reset --hard <commit-hash>
 
# 生成一个反向 commit 来撤销某次提交(安全方式)
git revert <commit-hash>

5.4 查看历史

# 简洁日志
git log --oneline -20
 
# 图形化分支历史
git log --oneline --graph --all
 
# 查看某文件的修改历史
git log --oneline -- <file>
 
# 查看某文件每一行的最后修改者
git blame <file>
 
# 查看某次 commit 的具体改动
git show <commit-hash>

5.5 远程操作

# 查看远程仓库
git remote -v
 
# 拉取远程最新代码(不合并)
git fetch origin
 
# 拉取并合并
git pull origin <branch>
 
# 推送到远程
git push origin <branch>
 
# 强制推送(慎用,会覆盖远程历史)
git push --force-with-lease origin <branch>

5.6 合并与变基

# 合并分支
git merge <branch>
 
# 变基(将当前分支的 commit 移到目标分支最新之后)
git rebase <branch>
 
# 交互式变基(修改/合并/删除 commit)
git rebase -i HEAD~3
 
# 中止合并/变基
git merge --abort
git rebase --abort

5.7 清理

# 查看哪些文件会被清理(预览)
git clean -nd
 
# 删除未跟踪的文件
git clean -fd
 
# 删除未跟踪的文件和目录(包括 .gitignore 中的)
git clean -fdx

六、推荐的额外配置

# 开启 rerere(记住冲突解决方式,下次自动应用)
git config --global rerere.enabled true
git config --global rerere.autoupdate true
 
# 设置默认推送行为
git config --global push.default current
 
# 设置中文文件名正常显示
git config --global core.quotepath false
 
# 设置默认编辑器
git config --global core.editor vim

七、常见问题

Q: git mergetool 提示 “No files need merging”

说明当前没有冲突状态。需要先执行产生冲突的操作(merge/rebase/stash pop),出现 CONFLICT 提示后再运行 git mergetool

Q: Meld 打开后只看到两栏而非三栏

确认配置正确:

git config --global mergetool.meld.cmd 'meld "$LOCAL" "$MERGED" "$REMOTE" --output "$MERGED"'

Q: 解决完冲突后多出 .orig 文件

# 删除 .orig 文件
find . -name "*.orig" -delete
 
# 配置不生成备份文件
git config --global mergetool.keepBackup false

Q: 想放弃本次合并,回到合并前的状态

git merge --abort   # 放弃 merge
git rebase --abort  # 放弃 rebase
git stash           # 放弃 stash pop 后的状态(重新存回去)