我目前正在调查如何将subversion repo移动到git(bitbucket)。对我来说最大的阻碍是理解如何将我们当前基于SVN的分支/合并策略转换为git。
我们练习的东西类似于"后备箱里没有垃圾。"具体来说,我们有两个分支(一个用于主动开发,一个用于分段/ QA)和主干(生产):
dev ______________
\ \ \ (selective merges)
staging ___________
\ \ (selective merges)
trunk ________________________________
实际上说:
从颠覆的优势来看,它看起来像这样:
svn checkout .../branches/dev
(即:在开发部门工作)svn commit -m "re ticket #1234"
(可以进行多次提交,在示例中它们是修订版100,102和105)svn checkout .../branches/staging
(即:在分期分支工作)svn merge .../branches/dev -c 100,102,105
svn commit -m "re #1234 revs 100,102,105"
(这可以创建修订版110)svn checkout .../trunk
(即:在主干中工作)svn merge .../branches/staging -c 110
(假设在暂存期间此功能只有一个版本......可能会有更多版本)svn commit -m "re #1234 revs 110"
这种结构使我们能够实现以下目标:
对于所有关于git分支/合并策略的Google搜索,我见过的最佳解决方案涉及主题/功能分支,然后将其合并到主代码行中。这似乎涉及合并全部或全部过程。
在大多数情况下,我并不关心这个过程在功能上是否与git相同,但该策略的功能具有可比性。
git newbie的任何指针?
谢谢,
麦克
PS - 经过更多的挖掘,我遇到了skullcandy工作流outlined here似乎最接近我想做的事情。我最好的猜测是它会通过git(有大量的bitbucket pull请求)来完成(假设有两个现有的分支 - 主和分段):
git checkout master
git branch feature-001
git commit -a
git push -u origin feature-001
这似乎是一个很好的过程。最佳实践?我不知道。
这个过程完成后,会出现一个副作用"我不明白bitbucket是否报告了升级分支正在受到惊吓并领先于主人?
答案 0 :(得分:1)
您在帖子末尾概述的工作流程是基本的Github工作流程,但它有一个缺陷。您的功能分支不在master
范围内,但会合并到staging
和master
。这是第一次双重合并后的结果。
- - - - - 5 [staging]
/ /
| Z - Y - X
|/ \
1 - 2 - 3 - - - - - 4 [master]
请注意,虽然staging
和master
具有相同的内容,但它们具有不同的提交ID和历史记录。这会使事情变得复杂。您不仅要解决任何合并冲突两次(并且可能不同),而且它会杀死Git的一个主要特性:相同的提交具有相同的ID。
等等,情况变得更糟。由于您在QA之后立即合并到staging
,然后QA合并到master
,因此可以将要素合并到master
和staging
以不同的顺序。这不仅会产生重要的历史,它还会产生不同分辨率的不同合并冲突。现在,您确实不知道master
和staging
是否相同。您可以查看git diff master staging
,但很难找出差异泄露的位置以及原因。
- - - - - 5 - - - - 6 - 7 [staging]
/ / / /
/ / E - F - G -+-
/ / / / \
| Z - Y - X / J - K - L \
|/ \|/ \ \
1 - 2 - 3 - - - - - 4 - - - - - - 8 - 9 [master]
在此示例中,EFG
和JKL
都来自master
上的同一提交。在EFG
之前,JKL
已合并到暂存,但JKL
首先完成QA并在master
之前合并回EFG
。 master
和staging
现在可能不同了。您的历史图表也很粗糙,很难理解。
我猜你是否正在使用this Skullcandy workflow?我从未在实践中看到过这样的工作流程,你习惯性地合并到两个分支。看起来过于复杂。你是Git的新手,保持简单。只需从master分支并合并回master。这会生成一个带有所需"特征气泡的图表。
Z - Y - X J - K - L
/ \ / \
1 - 2 - 3 - - - - - 4 - - - - - 8 - 9 [master]
\ /
E - F - G - -
现在只有一个合并功能的订单。
此工作流程中不需要暂存。在合并回主数据之前,可以直接从功能分支进行单独更改。
看起来像这样......
git fetch origin; git checkout -b feature/1234 origin/master
git fetch origin
git rebase origin/master
。git merge origin/master
。git push -u origin feature/1234
。
feature/1234
运行自动化测试。feature/1234
到master
的拉取请求。feature/1234
。
master
。
git merge --no-ff master
(或使用Bitbucket内置的合并功能)git push origin :feature/1234
。git branch -d feature/1234
。关键区别在于在合并之前,直接从功能分支进行QA&#d。没有必要维护单独的分段分支和重复合并。没有未经测试的分支会合并到任何内容中。
值得注意的是,通过将master
合并(或重新定位)到其中来更新要素分支具有与将要素分支合并到master
中相同的内容。这就是您可以直接从功能分支进行QA的原因。
应该使用staging
分支来跟踪您为下一个候选版本测试的内容。它被用作QA的稳定点,以保护候选版本免于master
的更改。它只不过是正常历史上的一个地方。在上面的示例中,staging
可能指向提交2。
另请注意,在完成功能后,您可以进行小型提交,而不是执行一次大git commit -a
。修正错字?测试&承诺。添加新方法?测试&承诺。进行重构?测试&承诺。这会将您的工作分解为易于理解的块,更容易映射每一行,并解释其原因。结合测试,它使调试更容易。它是在最后一次提交时传递的,所以从那时起它必须改变。如果git diff
很小,则更容易发现导致错误的更改。如果你认为改变是一个坏主意,那么更容易抛出这种改变。
我的核心理念是,在正常操作下,功能工作应该是孤立的,合并应该简单和开发分支应该随时为QA做好准备即可。开发人员不应该合并到多个分支(如Skullcandy)。分支之间的樱桃采摘变化应该是一种特殊的操作。开发分支应该进行CI测试。在合并到开发之前,应该完成功能分支。暂存和生产应该只是开发分支上的旧提交。
Git比SVN更灵活,特殊情况可以在发生时进行处理。如果需要热修复和樱桃采摘,则应尽快回滚开发。您甚至可以使用rebase
重写历史记录并平滑所有内容以使正常流程更好地工作。我知道重写历史的这个想法可能会让你现在感到烦恼,你会习惯它。
这使得分支机构的开发更快更简单,并且增加了可以查看和合并更改的人数。