代码之家  ›  专栏  ›  技术社区  ›  ericP

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

git
  •  0
  • ericP  · 技术社区  · 7 年前

    我基本上希望将分支B中的提交标记为在master中合并,这样当我(最终)从B合并回master时,就不必反转这些编辑。我试过樱桃采摘和合并 --strategy=ours . ( How to avoid pushing 'branch-specific' files to master branch? 不会问这个问题。)

    取一个简单的代码repo,它有一个对应的…/tests repo用于测试。 travis.yml 克隆用于运行测试的…/tests repo。它在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"
    

    现在我想要 特拉维斯 从测试报告中的并行分支获取测试。 在单独的提交中,我更新 特拉维斯 要在测试报告中签出B:

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

    现在我要将此提交标记为在主控形状中合并。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上的最后一次提交添加到master历史的预期效果,因为cherry picks只有一个父级:

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

    当我们准备合并b时,这个问题稍后会显现出来,它将用自己的travis.yml来踩我们的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并将其合并为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"
    

    校长现在有两个父母:

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

    但是下一次我把大师合并回B时,它会踩坏 特拉维斯 :

    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
    

    我有效地将问题从记忆转移到了更新 特拉维斯 一次(当B被合并回master时),每次我都必须更新它,使B与master保持最新。

    完成这项任务的优雅方式是什么(除了在我的显示器上贴一个帖子)?

    [[ 编辑 : 鉴于“Git不这么做”的答案,我补充道 .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 回复  |  直到 7 年前
        1
  •  1
  •   torek    7 年前

    完成这项任务的优雅方式是什么(除了在我的显示器上贴一个帖子)?

    一般来说,没有一个。可能有一个针对您的特定问题。

    处理不同分支提示下不同提交中应该相似但不相同的文件的“git方法”是使用多个文件。这真的很有效,避免了所有的头痛… 除了 当文件 名称 必须是一个特定的名称,所有分支提示都通用,以满足某些外部软件的要求。

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

    然而, build 在里面 特拉维斯 可以包括创建和使用未跟踪文件的命令,以及 可以 以各种方式检查存储库。因此,您可以编写一个构建脚本,查看“将要构建什么”,然后从中选择依赖于所构建内容的文件。

    总之,不要 尝试 把一整套规则 特拉维斯 直接。相反,有 特拉维斯 从中获取附加规则 依赖分支 文件夹。这可能意味着放弃一些方便的travis特性,转而自己重新编码。