我正在开发一个项目,我们想要编辑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
以便不记录合并。
我们的希望是:
master
保持可管理状态,因为Bootstrap提交永远不会成为该分支的一部分。merge-from-bootstrap
分支具有我们更改的完整历史记录和Bootstrap团队的更改。在以下步骤中,我们获取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
答案 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
。