鉴于您不必清理工作目录的要求,我假设您的意思是您不想清理工作树或索引,即使通过一些脚本也是如此。在这种情况下,您将无法在当前本地存储库的范围内找到解决方案。 Git 在合并时广泛使用索引。如果没有冲突,我不确定工作树,但总的来说,合并与当前签出的分支密不可分。
不过,还有另一种方法,它不需要您更改当前存储库中的任何内容。但是,它确实要求您拥有或创建您的 repo 的克隆。基本上,只需克隆您的存储库,然后在克隆中进行合并,然后将其推回原始存储库。下面是一个简短的例子来说明它是如何工作的。
首先,我们需要一个示例代码库。以下命令序列将创建一个。你最终会得到master 作为你当前的分支,另外两个分支已经准备好被合并,分别命名为change-foo 和change-bar。
mkdir background-merge-example
cd background-merge-example
git init
echo 'from master' > foo
echo 'from master' > bar
git add .
git commit -m "add foo and bar in master"
git checkout -b change-foo
echo 'from foo branch' >> foo
git commit -am "update foo in foo branch"
git checkout -b change-bar master
echo 'from bar branch' >> bar
git commit -am "update bar in bar branch"
git checkout master
现在,假设您正在处理master,并且想要将change-bar 合并到change-foo。这是我们所处位置的半图形描述:
$ git log --oneline --graph --all
* c60fd41 update bar in bar branch
| * e007aff update foo in foo branch
|/
* 77484e1 add foo and bar in master
下面的顺序将完成合并而不干扰当前的 master 分支。把它打包成一个脚本,你就有了一个不错的“背景合并”命令:
# clone with absolute instead of relative path, or the remote in the clone will
# be wrong
git clone file://`realpath .` tmp
cd tmp
# this checkout auto-creates a remote-tracking branch in newer versions of git
# older versions will have to do it manually
git checkout change-foo
# creating a tracking branch for the other remote branch is optional
# it just makes the commit message look nicer
git branch --track change-bar origin/change-bar
git merge change-bar
git push origin change-foo
cd ..
rm -rf tmp
简而言之,这会将当前 repo 克隆到一个子目录,进入该目录,进行合并,然后将其推送回原始 repo。完成后它会删除子目录。在大型项目中,您可能希望拥有一个保持最新状态的专用克隆,而不是每次都制作新的克隆。在合并和推送之后,我们最终得到:
$ git log --oneline --graph --all
* 24f1916 Merge branch 'change-bar' into change-foo
|\
| * d7375ac update bar in bar branch
* | fed4757 update foo in foo branch
|/
* 6880cd8 add foo and bar in master
问题?