如何将非快进git合并到未检出的分支?

Ram*_*hum 11 git

我在树枝上a.我想将分支合并b到分支c.合并不是快进,但也不需要手动解决.(即,它不是简单的情况下,但它也不是最困难的,所以这是一个融合了Git是能够对自己做,而无需人.)

有没有办法让我做这个合并b从而c无需检查任何分支?怎么样?

更新:如果您知道可以执行的替代Git实现,那么这也是一个有效的解决方案.但编写一个以编程方式执行检查的脚本不是一个好的解决方案,因为它仍然需要我有一个干净的工作目录.

jth*_*ill 8

如果合并不涉及两个分支上的文件,那么我认为你想要git read-treegit write-tree使用边带GIT_INDEX_FILE.这应该这样做:

#!/bin/sh
export GIT_INDEX_FILE=.git/aux-merge-index
trap 'rm -f '"'$GIT_INDEX_FILE'" 0 1 2 3 15
set -e
git read-tree -im `git merge-base $2 $1` $2 $1
git write-tree \
| xargs -i@ git commit-tree @ -p $2 -p $1 -m "Merge $1 into $2" \
| xargs git update-ref -m"Merge $1 into $2" refs/heads/$2
Run Code Online (Sandbox Code Playgroud)

您也可以使用git mktree </dev/null而不是merge-base处理bc完全不相关的分支,并使得结果合并组合每个中的文件,而不是将缺少的文件视为删除.

你说你的合并不是一个快进,所以你需要阅读read-tree文档,使上面的序列完全符合你的要求. --aggressive看起来它可能是正确的,这取决于你的分支之间的实际差异.

编辑添加了空树基地来处理不相关的树 编辑2提升我说的一些有效载荷或隐含在评论中


Rya*_*art 5

鉴于您不需要清理工作目录,我认为您的意思是您不希望必须清理工作树或索引,即使是通过某些脚本.在这种情况下,您将无法在当前本地仓库的范围内找到解决方案.Git在合并时广泛使用索引.如果没有冲突,我不确定工作树,但一般来说,合并与当前检出的分支密不可分.

不过,还有另外一种方法,不需要你改变当前仓库中的任何东西.但是,它确实要求您拥有或创建回购的克隆.基本上,只需克隆您的仓库,然后在克隆中进行合并,然后将其推回到原始仓库.这是一个如何工作的简短示例.

首先,我们需要一个样本仓库来处理.以下命令序列将创建一个.您将最终master作为当前分支和其他两个分支,其中的更改已准备好合并命名change-foochange-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
Run Code Online (Sandbox Code Playgroud)

现在,想象一下你正在努力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
Run Code Online (Sandbox Code Playgroud)

以下序列将完成合并而不会干扰当前主分支.把它打包成一个脚本,你有一个很好的"后台合并"命令:

# 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
Run Code Online (Sandbox Code Playgroud)

简而言之,这会将当前仓库克隆到子目录,输入该目录,执行合并,然后将其推回到原始仓库.它在完成后删除子目录.在一个大型项目中,您可能希望拥有一个专门的克隆,它只是保持最新,而不是每次都进行新的克隆.合并推后,我们最终:

$ 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
Run Code Online (Sandbox Code Playgroud)

有问题吗?

  • 3种类型:浅,裸,"正常".在这种情况下,不建议使用git存储库的浅拷贝(克隆时使用--depth选项).我不会证明您将能够使用浅拷贝执行2个分支的合并,特别是如果您错过了2个分支的共同父级.但是,是的,git允许在浅克隆(而不是裸存储库)上进行合并,因为你可以使用`git pull`.在这种情况下,我会做一个完整/简单的克隆. (2认同)