使用子树合并将Bootstrap合并到git仓库中

时间:2014-04-15 21:52:54

标签: git twitter-bootstrap merge git-subtree

我正在开发一个项目,我们想要编辑Twitter Bootstrap附带的LESS文件。 standard advice是保持这些文件不变,以便更容易升级Bootstrap。但这个建议不适合我们;我们的代码变得脆弱且难以维护。

似乎应该可以通过git子树合并来解决这个问题:我们可以编辑Bootstrap的LESS文件以获得清晰,可维护的代码,然后使用git的合并工具引入新版本的Bootstrap。

我们已经提出了使用子树合并的计划。但在我们将计划付诸行动之前,我想得到一些反馈:我们忽略了哪些重大缺陷?是否有更好/更简单的方法?

具有显着缺点的方法

simplest approach到子树合并中,来自子树的所有提交(即Bootstrap)都会合并到项目的master分支中。缺点是Bootstrap有很多提交,我们的提交会在噪声中丢失。我们希望将他们的提交保留在master分支机构之外。

理论上,我们可以使用git rebase -i将所有Bootstrap提交压缩​​到一个提交中,然后我们将其合并到master中。但是rebase -i does not work well with merges

@Sigi helpfully suggested我们使用壁球合并从bootstrap-upstream转到master。抓住Bootstrap(v3.1.0)的初始版本可以正常工作。但是当我们在下一个版本(v3.1.1)中合并时,我们有超过100个合并冲突。 3.1.0和3.1.1之间的每个Bootstrap更改都被标记为冲突。 (我们的确切步骤在this gist。)

计划

我们的计划是使用分支merge-from-bootstrap将Bootstrap提交提取到我们的存储库中。将更改合并到 merge-from-bootstrap(我们对master的更改或Bootstrap的更改)时,始终记录合并。将 merge-from-bootstrap合并到master时,请使用git merge --squash以便不记录合并。

我们的希望是:

  1. master保持可管理状态,因为Bootstrap提交永远不会成为该分支的一部分。
  2. Git在新版本的Bootstrap中合并时拥有尽可能多的信息,因为merge-from-bootstrap分支具有我们更改的完整历史记录和Bootstrap团队的更改。
  3. 概念证明

    在以下步骤中,我们获取Bootstrap v3.1.0,进行一些更改,然后升级到v3.1.1。 POC似乎运作良好(我的真实回购测试也是如此),但我想知道我们是否正在努力解决问题。

    从一个新的仓库开始,其中唯一的文件是README.md(即GitHub给你的新仓库)。

    # Add bootstrap as a remote
    git remote add bootstrap https://github.com/twbs/bootstrap.git
    # Only fetch the master branch; don't fetch tags
    git config remote.bootstrap.fetch +refs/heads/master:refs/remotes/bootstrap/master
    git config remote.bootstrap.tagopt --no-tags
    git fetch bootstrap
    
    # Start with Bootstrap v3.1.0
    git checkout -b merge-from-bootstrap
    # SHA is the commit tagged v3.1.0 from the bootstrap repo
    git merge -s ours --no-commit 1409cde7e800ca83fd761f87e5ad8f0d259e38d1
    git read-tree -u --prefix=bootstrap/ 1409cde7e800ca83fd761f87e5ad8f0d259e38d1
    git commit -am "Bootstrap v3.1.0"
    
    # Merge Bootstrap 3.1.0 to master
    git checkout master
    git merge --squash merge-from-bootstrap
    git commit -am "Merge bootstrap v3.1.0 to master"
    
    # Make some changes on master, so that we have something to
    # be merged
    sed -e 's/= space/= force-merge-conflict/g' -i '' bootstrap/.editorconfig
    git commit -am "Force a merge conflict"
    sed -e 's/"Helvetica Neue"/"Comic Sans"/g' -i '' bootstrap/less/variables.less 
    git commit -am "Comic Sans"
    
    # Get ready to upgrade to the new version of Bootstrap
    git checkout merge-from-bootstrap
    git merge -s recursive -Xtheirs master
    
    # Merge in Bootstrap v3.1.1 from bootstrap/master to
    # merge-to-bootstrap. (SHA is for v3.1.1 from the bootstrap repo)
    git merge -s recursive -X subtree=bootstrap --no-commit a365d8689c3f3cee7f1acf86b61270ecca8e106d
    
    # Fix the merge conflict, then do:
    git commit -am "Merged in Bootstrap v3.1.1"
    
    # Merge back to master
    git checkout master
    git merge --squash merge-from-bootstrap
    

1 个答案:

答案 0 :(得分:1)

采用Pro Git book

中描述的方法

在Bootstrap分支上,合并上游更改:

$ git checkout bootstrap-upstream
$ git pull

然后,在您的主分支上,子树合并 Bootstrap子树--squash选项

$ git checkout master
$ git merge --squash -s subtree --no-commit bootstrap-upstream

这里的关键是使用subtree合并策略,该策略从Bootstrap批发中获取所有更改并将其置于其位置(子目录)。

提交并编写提交消息:

$ git commit

这样可以避免bootstrap-upstream分支中包含master的所有历史记录,并且您不必使用git rebase

相关问题