git - 使用子树 merge 将 Bootstrap merge 到一个 git 仓库中

标签 git twitter-bootstrap merge git-subtree

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

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

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

有重大缺陷的方法

simplest approach对于子树 merge ,来自子树(即 Bootstrap)的所有提交都被 merge 到项目的 master 分支中。缺点是 Bootstrap 有太多的提交,我们的提交在噪音中迷失了。我们想让他们的提交远离我们的 master 分支。

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

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

计划

我们的计划是使用一个分支,merge-from-bootstrap,将 Bootstrap 提交 pull 入我们的存储库。当 merge 更改 in 到 merge-from-bootstrap(我们对 master 的更改,或 Bootstrap 的更改)时,始终记录 merge 。当 merge out from merge-from-bootstrapmaster 时,使用 git merge --squash 以便 merge 没有记录。

我们的希望是:

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

概念验证

在接下来的步骤中,我们获取 Bootstrap v3.1.0,进行一些更改,然后升级到 v3.1.1。 POC 似乎运行良好(就像我对真实存储库的测试一样),但我想知道我们是否正在为自己设置麻烦。

从一个新的 repo 开始,其中唯一的文件是 README.md(即 GitHub 为您提供的新 repo)。

# 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

最佳答案

采用 Pro Git book 中描述的方法:

在 Bootstrap 分支上, merge 上游更改:

$ git checkout bootstrap-upstream
$ git pull

然后,在您的主分支上,子树 merge Bootstrap 子树使用--squash 选项:

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

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

提交并写下你的提交信息:

$ git commit

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

关于git - 使用子树 merge 将 Bootstrap merge 到一个 git 仓库中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23095230/

相关文章:

git - 如何解决与 Git 的冲突?

git - 在 AWS Amplify Build 中获取私有(private)子模块

git - 我如何找出 merge 提交 parent 的编号?

git - 如何将非标准 svn 存储库克隆到 git?

javascript - 无法将 ui.bootstrap 注入(inject)我的模块

merge - 融合:使一部分只读

git - 高效检索包含提交的版本

javascript - 使用 anchor 标记打开 Bootstrap Modal

html - Bootstrap 列居中

c# - 合并从不同表投影到一个实体的两个可查询对象