7

我正在与一个不熟悉 git 的开发人员合作,我想设置一个 git 工作流程,让我可以审核该开发人员所做的提交(并可能拒绝它们),而不会强迫他重新调整他的工作(这很容易出错对于新用户)。

这是场景:

  • master分支仅包含经过审核的代码
  • devel分支是通过分叉master分支创建的
  • 开发人员正在devel分支上工作并推送他的代码供我审核
  • 我发现他的代码存在一些问题,所以我要求他在devel分支上进行更多提交以解决问题
  • 一旦我对代码感到满意,我就会挑选(或与 squash 合并)开发人员在master分支上提交,添加我自己的评论并将提交标记为由开发人员编写
  • 开发人员将分支合并回master他的devel分支

这是此场景的可视化说明:

视觉场景

在这个序列之后,当开发人员在其他一些提交后再次推送他的分支时,我怎么能100% 确定开发人员在“犯错误/重做”序列中犯的错误不会再次出现?devel

最好的解决方案是要求开发人员将他的devel分支重新设置为基础master,但这对于新的 git 用户来说是一项艰巨的任务。

如果此工作流程有任何错误,请建议我另一个可以在将提交合并到主分支之前审核提交的地方。

编辑

一位朋友向我推荐了一个看起来很有希望的方向:提交时的--fixup 选项

--fixup=<commit>

构造一个提交消息以用于rebase --autosquash. 提交消息将是来自指定提交的主题行,前缀为“fixup!”。有关详细信息,请参阅git-rebase

开发人员可以使用此选项将他的第二次和第三次提交正确标记为对其第一次提交的修复。一个很好的解决方案来探索......

4

7 回答 7

8

备注 1:通过尝试将单独的提交打开devel为单个提交master,您正在重写历史记录。我认为尝试保持干净、线性的历史记录master很重要,但是使用合并的线性较少的历史记录将更容易与 git 基本命令集成。

备注 2:如果您的工作流程明确包含不熟悉您用于共享代码的基本工具的成员,您应该承担后果。在某些时候,我认为开发人员应该学习 git。

这里有两个建议:

  1. 删除 master 上的线性历史记录,并通过从 master 运行“验证”更改:

    git merge --no-ff devel
    

    这是通知 git 上的修改devel被考虑在master.

  2. 与您自己进行合并devel,并让您的开发人员从origin/devel.
    如果 master 上的单个提交真的只包括压缩 上的提交devel,这不应该触发任何冲突——合并提交master->devel应该引入 0 修改。
    如果你真的修改了被压扁的提交,开发者可以有他自己的本地修改,你无论如何都要面对在他这边触发冲突的可能性......

于 2014-04-15T14:42:17.710 回答
2

只需使用gerrit。使用 gerrit,您将拥有您的评论、提交等的历史记录。您也可以放弃更改。我作为开发人员使用的工作流程:

准备

将 gerrit 提交消息挂钩复制到您的repo/.git/hooks. 确保它是可执行的并且不包含 crlf。

如果您在 *nix 上工作,请进行远程审查以进行推送,或者更好的 shell 别名。

在 ~/.gitconfig 中为 rebase 创建别名(关于fork-point

[alias]
        reb = !"git rebase -i $(git merge-base --fork-point origin/master HEAD)"

工作流程

while unapproved do
    git commit -a --amend
    git push review
    # reviewers comment, reject, approve etc.
    # If rejected, I change commit as required, then
end

挤压

当推送到 gerrit 时,应该(可能)只有一次提交。

因此,要将分支上的提交压缩为一个:

git reb

编辑器将打开。更改picksquash除第一行(最旧的提交)之外的每一行。保存并退出。编辑器将打开提交消息。删除除最旧的提交消息和带有 Commit-ID 的行(gerrit 需要它)之外的所有内容。

变基

如果在 gerrit 中合并您的分支失败,您可以将其变基到 origin/master

git rebase origin/master

如果有很多冲突,你可以避免仅仅通过使用cherry-pick来解决许多冲突的痛苦

git checkout -b topic2 origin/master
git cherry-pick topic
git branch -D topic
git branch -m topic

git 审查

使用gerrit 时也可以使用git review来简化一些操作。

于 2014-04-15T14:54:51.563 回答
2

如果你只是dev压缩分支而不是正常合并它,那么将压缩的提交合并回dev分支不是一个好主意,因为那样你会得到大量令人困惑的冲突,因为 git 认为你是应用新代码,而实际上它实际上是相同的代码。

最好是简单地合并到master,然后简单地合并回devel,或者丢弃devel分支并从最近提交的master. 根据您的说法,只要您合并的代码master是“好”的,那么您可能不会得到任何回归。

另一方面,如果您按照最初的计划将压缩的提交合并回,由于混乱的冲突devel,这将增加您发生回归的机会。

更新

我删除了上面的部分答案,因为我实际上只是测试了 squash commit onmaster然后立即将其合并回devel,并且没有引起任何冲突,因此我的部分答案不正确。

我把它变成了一个社区 wiki 的答案,因为它仍然包含很多关于评论中问题的信息。

于 2014-04-08T16:33:16.267 回答
0

好吧,如果你有一个初学者开发者并且你是唯一的审阅者,我建议这个工作流程:

  1. 开发人员从 master 创建一个本地分支以实现某些功能(分支名称:i-123)
  2. 开发人员将一些代码添加到分支 i-123
  3. 开发人员创建合并请求以合并主分支上的 i-123
  4. 审稿人发现一些错误并将问题通知给开发人员
  5. 开发人员添加提交以解决问题并通知审阅者检查 i-123 分支的更改
  6. 审阅者验证源代码并接受合并请求(在主分支上合并 i-123,因为结果 i-123 被破坏)
  7. 开发人员同步本地存储库(结果:主分支包含与 i-123 相关的更改,并且 i-123 已被销毁)
  8. 开发人员可以继续第 1 步

这种方法允许一个开发人员同时处理一个或多个功能,并消除有关 mantein 更新开发分支的复杂逻辑。对于初学者开发人员来说,这是一种简单的方法。

于 2014-04-17T17:59:19.673 回答
0

我将测试以下工作流程,并让您知道事情是否进展顺利。

先决条件

  • 开发人员必须能够从命令行提交
  • 开发人员应该始终留在同一个分支上,这样他就不必担心当前签出哪个分支
  • 开发人员永远不必解决影响他未编写的代码的冲突
  • 开发人员永远不会处于可能丢失对其工作树的本地修改的情况

工具

git commit使用--fixup 选项

--fixup=<commit>

构造一个提交消息以用于rebase --autosquash. 提交消息将是来自指定提交的主题行,前缀为“fixup!”。

git rebase带有--autosquash、--autostash 和 --interactive 选项

--interactive

列出即将被重新设置的提交。让用户在变基之前编辑该列表。此模式也可用于拆分提交。

--autosquash

当提交日志消息以“squash!...”(或“fixup!...”)开头,并且有一个标题以相同...开头的提交时,自动修改 rebase -i 的 todo 列表所以标记为 squashing 的提交紧跟在要修改的提交之后,并将移动提交的操作从 更改picksquash(或fixup)。在第一个之后忽略后续的“fixup!”或“squash!”,以防您使用git commit --fixup/--squash.

此选项仅在使用--interactive选项时有效。

如果使用配置变量默认启用--autosquashrebase.autosquash选项,则此选项可用于覆盖和禁用此设置。

--autostash

在操作开始之前自动创建一个临时存储,并在操作结束后应用它。这意味着您可以在脏工作树上运行 rebase。但是,请谨慎使用:成功变基后的最终存储应用程序可能会导致重大冲突。

工作流程

  1. 开发人员将master分支分叉成一个devel分支。分叉点标有标签(例如version_1.1
  2. devel开发人员在分支上工作并提交。工作完成后,他将他的分支推送到远程存储库,以便审计员可以查看和验证它。
  3. 审计员获取devel分支并查看代码。如果某些地方不正确,他会要求开发人员进行一些修改。
  4. 对于开发人员所做的每项修改,应使用以下命令提交更正: git commit --fixup <commit that was not OK>. 然后再次推送分支。
  5. 一旦审核员对所做的修改感到满意,开发人员必须重新调整他的分支,以便将所有修复提交压缩为一个漂亮且无错误的提交(其他不相关的工作可能同时提交)。

GIT_EDITOR=: git rebase tags/version_1.1 --interactive --autosquash --autostash.

这是为了避免显示由于该选项GIT_EDITOR=: 而显示提交列表的编辑器。--interactive需要此选项才能使fixup提交自动重新排序。

最后一步是devel再次推送分支(带有--force选项),以便审核员可以将其合并到master分支中。下一次开发修复的变基基础可以是主分支或开发人员在合并主分支后放置在其开发分支上的新标签。

这是生成的 git 树:

修复工作流程的 gitk 插图

于 2014-04-17T15:52:31.567 回答
0

最简单、最简单的方法就是将来自 devel 分支的更改合并到 master 中。您只需要定期使用 master 更新分支,这样您的分支就不会过于分散(取决于其他人正在处理的功能)。

如果您想对 master 的修改进行一次提交。您可以将开发人员的提交重新设置为一个提交,然后将该提交挑选到 master 上。这会导致复杂性,因为您只能git push -f更新远程devel分支,如果您的开发人员不熟悉 git,更新他们的devel分支会很复杂。或者您会要求他们删除该分支,然后将新分支用于任何未来的工作。

您需要根据是否希望将开发人员的所有提交都显示在日志中来决定继续使用哪个选项。最简单、最省事的方法就是简单地合并 devel 和 master。

于 2014-04-15T15:26:07.363 回答
0

如果您确保您的其他开发人员始终从某个分支创建更改,例如开发,您可以拥有始终存在的主分支设置,例如:

掌握,发展

如果您的开发人员仅从开发分支创建功能分支,他可以创建他想要的所有提交。然后,当您认为它已准备好时,您可以挑选/变基并用它做您的事情。功能分支被删除,确保重写的历史记录消失。

您的开发人员需要记住的就是每次他想启动一个新功能时从远程开发分支创建一个分支,并且当您说要将一些东西合并到您的开发中时不要触及他的本地功能分支。

然后,当它准备好时,他会在本地删除他的 myfeature 分支,而当您将他的好更改合并/重新定位/樱桃挑选到您的开发中时,您会远程删除它。

只有好的提交才会进入开发分支。您的开发人员像以前一样从开发创建新分支。

我认为一些基本的分支是你的开发人员至少应该知道的。如果他不能变基/清理他的分支/提交,我认为你必须同意遵循一定的工作流程。

也许并不完美,但也许仍然是一个可能的工作流程。希望能帮助到你。

于 2014-04-11T07:48:37.957 回答