17

我有以下git工作流程:

  1. 创建新功能分支
  2. 在功能分支上工作
  3. 经常提交
  4. 一旦功能完成,合并到master分支
  5. 冲洗并重复

但是,有时,我需要从 master 恢复整个功能。这可能涉及很多内容revert。(需要恢复功能的原因是我有一个网站,它可以在一个仓库中运行。从那里,我们使用一个脚本将该站点部署到我们的生产站点或暂存站点。两者都是从我们的主分支完成的。唐不要问,这正是我被赋予的工作。有时,我正在做一些我准备好的事情,但是需要立即做出改变,所以我需要一些方法来拉动我的改变,以便清理回购。

我认为最简单的方法是每个功能分支只有一个提交。然后我可以revert提交。所以很自然,我正在考虑将功能分支的所有提交压缩为一个,然后再将其合并到master.

所以现在我的工作流程看起来像:

  1. 创建新功能分支
  2. 在功能分支上工作
  3. 经常提交
  4. 一旦功能完成git rebase -i HEAD~number_of_commits(或者如果远程分支可用,origin/feature_branch

这个逻辑有问题吗?它是否违反任何最佳实践?我自己做了一些测试,整个工作流程似乎运行顺利并解决了我的问题,但我想通过其他(更聪明的)Git-ers 来运行这个想法,看看它是否有任何问题。

谢谢!

4

2 回答 2

19

您应该考虑利用 git ie 的 squash 合并功能git merge --squash,这样您就不会不必要地重写历史记录。

两者git merge --squashgit rebase --interactive都可以用于生成具有相同结果工作树的压缩提交,但它们旨在服务于 2 个完全不同的目的。在这两种情况下,您的树最终看起来都不同。

初始树:

a -- b -- c -- d    master
      \
       \-- e -- f   feature1

之后git checkout master; git merge --squash feature1; git commit

a -- b -- c -- d -- F    master
      \
       \-- e -- f   feature1

之后git checkout master; git rebase -i feature1并选择pick csquash d

a -- b            /-- F  master
      \          /
       \-- e -- f   feature1

从差异中可以看出,使用时不会重写任何分支的历史记录,git merge --squash但最终会重写master使用时的历史记录git rebase -i

另请注意,在这两种情况下,实际提交(对于那些被压扁的提交)都会出现在你的 git 历史记录中,只要你有一些分支或标签引用可以通过这些提交访问。

换句话说,在上面的示例中,如果您feature1在执行后删除merge --squash,您将无法实际查看提交ef将来(尤其是在 90 天的 reflog 期之后)。这同样适用于提交c和示例。drebase

于 2013-05-08T21:59:22.220 回答
3

您的方法的一个特定缺点是它严重降低了git bisect跟踪代码中的错误的实用性。

也就是说,如果您发现自己经常将整个功能恢复到您正在寻找优化该过程的方法的位置,您可能想问自己是否合并master得太快了。您可能需要考虑使用多个长期运行的分支来设置更适合您的项目的工作流。

于 2013-05-08T20:03:42.043 回答