如何避免将分支特定的更改合并回master?

时间:2019-01-20 17:30:45

标签: git

我本质上想将分支B中的提交标记为已与master合并,因此当我(最终)从B合并回master时,我不必撤消那些编辑。我已经尝试了摘樱桃和合并--strategy=ours。 (How to avoid pushing 'branch-specific' files to master branch?不会问这个问题。)

使用一个简单的代码仓库,该仓库具有一个对应的... / tests测试仓库。 travis.yml克隆... / tests存储库以运行测试。在master和B上有一些随机提交:

git init
echo '... git clone --branch=master .../tests' > travis.yml
echo a > a.txt
git add . && git commit -m "master has a.txt and a travis.yml"
git checkout -b B
echo b > b.txt && git add . && git commit -m "B has b.txt"

现在,我希望travis.yml从测试存储库中的并行分支中获取测试。 在单独的提交中,我将travis.yml更新为在测试存储库中结帐B:

echo '... git clone --branch=B .../tests' > travis.yml
git add . && git commit -m "B tests on .../tests branch B"

现在,我想将此提交标记为已合并到master中。 cherry-pick不起作用,因为它只有一个父母:

git checkout master
git cherry-pick --no-commit --strategy=ours B
git commit --allow-empty -m "cherry-pick B's tests but keep ours"

这确实没有,但由于樱桃签只有一个父母,所以没有将B的最后一次提交添加到主人的历史上的预期效果:

git log --abbrev-commit --parents --oneline -1
ee71621 46bf9bb (HEAD -> master) cherry-pick B's tests but keep ours

稍后,当我们准备合并B时,此问题就会显现,这将使我们的travis.yml具有自己的优势:

git merge B -m "absorb B's wisdom"
cat travis.yml 
... git clone --branch=B .../tests

对于挑选樱桃来说,太多了​​,让我们尝试使用一个临时分支。在我熟悉B的travis.yml之前,先将master和B倒回:

git reset --hard master~2
git branch -f B B~1

使用所需的编辑创建一个临时分支:

git checkout -b B-tmp
echo '... git clone --branch=B .../tests' > travis.yml
git add . && git commit -m "B tests on .../tests branch B"

将B-tmp合并为B,然后将其与--strategy=ours合并为master:

git checkout B
git merge B-tmp -m "merge B's branch-specific changes"
git checkout master
git merge --strategy=ours B-tmp -m "keep master's changes"

HEAD现在有两个父母:

git log --abbrev-commit --parents --oneline -1
a8c0375 166af70 3f661f8 (HEAD -> master) keep --branch=master on master

但是下次我将母版合并回B时,它会加注travis.yml

echo aa > a.txt && git add . && git commit -m "aa"
git checkout B
git merge master -m "fetch changes to a.txt"
cat travis.yml
... git clone --branch=master .../tests

我已经有效地将问题从记住一次更新travis.yml(当B合并回master时)转移到每次我必须使B与master保持最新时都必须更新。

完成此操作的一种优雅方法是什么(除了在我的显示器上贴便利贴)?

[[编辑: 鉴于“ git not that that”的答案,我添加了.git/hooks/pre-commit来告诉我何时将不适当的内容合并到master:

if [ $(git rev-parse --abbrev-ref HEAD) = "master" ] && test $(grep git\ clone travis.yml | grep branch=master | wc -l) != 1
then echo "should be testing on master" ; exit -1
fi

]]

1 个答案:

答案 0 :(得分:1)

  

完成此操作的一种优雅方法是什么(除了在我的显示器上贴便利贴)?

通常没有一个。您的特定问题可能有一个。

在不同分支提示的不同提交中处理应该相似但不相同的文件的“ Git方式”是使用多个文件。这样非常有效,并且避免了所有这些麻烦事... 除了,当文件 name 必须是所有分支提示都通用的一个特定名称才能满足某些外部软件时

通过在检出后和/或合并后运行Git挂钩来创建其他软件所需的特定名称(作为未跟踪文件),您可以经常但不总是解决此问题。这显然不适用于travis.yml,因为该文件必须存在于Travis-CI正在使用的提交中。

但是,buildtravis.yml步骤 中可以包含创建并使用未跟踪文件的命令,并且可以检查以下位置的存储库各种方式。因此,您可以编写一个构建脚本,查看“要构建的内容”,然后从中选择取决于构建内容的文件。

简而言之,甚至不要尝试直接将整个规则集放入travis.yml本身。而是让travis.yml与分支相关的文件中获取其他规则。这可能意味着放弃了一些方便的Travis功能,希望自己重新编码。