Git 对于帮助小型团队管理其软件开发流程非常有用,但是您可以采取一些方法来使其更加有效。 我发现了一些对我的团队有帮助的最佳实践,特别是当新的团队成员加入并拥有不同级别的 Git 专业知识时。
为您的团队规范 Git 约定
每个人都应该遵循分支命名、标记和编码的标准约定。 每个组织都有标准或最佳实践,并且互联网上可以免费获得许多建议。 重要的是尽早选择合适的约定,并作为一个团队遵守它。
此外,不同的团队成员将具有不同级别的 Git 专业知识。 您应该创建并维护一套基本说明,用于执行遵循项目约定的常见 Git 操作。
正确合并更改
每个团队成员都应该在单独的功能分支上工作。 但是即使使用单独的分支,每个人最终也会修改一些公共文件。 将更改合并回master
分支时,合并通常不会自动进行。 可能需要人工干预来协调两位作者对同一文件所做的不同更改。 在这里,您必须学习处理 Git 合并技术。
现代编辑器具有帮助解决 Git 合并冲突的功能。 它们指示文件中每个部分的各种合并选项,例如是保留您的更改、另一个分支的更改还是两者都保留。 如果您的代码编辑器不支持此类功能,可能是时候选择另一个了。
经常 rebase 您的功能分支
在您继续开发功能分支时,经常将其 rebase 到master
。 这意味着定期执行以下步骤
git checkout master
git pull
git checkout feature-xyz # name of your hypothetical feature branch
git rebase master # may need to fix merge conflicts in feature-xyz
这些步骤 重写历史记录 在您的功能分支中(这不是一件坏事)。 首先,它使您的功能分支看起来像master
,其中包含到目前为止对master
所做的所有更新。 然后,您对功能分支的所有提交都会在顶部重播,因此它们会按顺序显示在 Git 日志中。 您可能会遇到需要沿途解决的合并冲突,这可能是一个挑战。 但是,这是处理合并冲突的最佳时机,因为它只会影响您的功能分支。
如果您修复了任何冲突并执行了回归测试,如果您已准备好将您的功能合并回master
,请再次执行上述 rebase 步骤,然后执行合并
git checkout master
git pull
git merge feature-xyz
在此期间,如果其他人将更改推送到与您的更改冲突的master
,则 Git 合并将再次发生冲突。 您需要解决它们并重复回归测试。
还有其他的合并理念(例如,不进行 rebase 而只使用合并来避免重写历史记录),其中一些甚至可能更易于使用。 但是,我发现上述方法是一种干净且可靠的策略。 提交历史记录被堆叠为有意义的功能序列。
使用“纯合并”策略(如上所述,不定期进行 rebase),master
分支中的历史记录将与同时开发的所有功能的提交交织在一起。 这种混杂的历史记录更难审查。 确切的提交时间通常不是那么重要。 最好有一个更容易审查的历史记录。
在合并之前 squash 提交
在您的功能分支上工作时,即使对于很小的更改,也可以添加提交。 但是,如果每个功能分支都产生 50 个提交,则随着功能的添加,master
分支中的提交数量可能会不必要地增长。 通常,每个功能分支应该只向master
添加一个或几个提交。 为了实现这一点,squash 将多个提交合并为一个或少数几个提交,并为每个提交添加更详细的消息。 这通常使用如下命令完成
git rebase -i HEAD~20 # look at up to 20 commits to consider squashing
当执行此操作时,会弹出一个编辑器,其中包含您可以以多种方式操作的提交列表,包括 pick 或 squash。 选择提交意味着保留该提交消息。 Squashing 意味着将该提交的消息合并到上一个提交中。 使用这些和其他选项,您可以将提交消息合并为一个,并进行一些编辑和清理。 这也是摆脱不重要提交消息的机会(例如,关于修复拼写错误的提交消息)。
总而言之,保留与提交关联的所有操作,但在合并到master
之前,合并并编辑关联的消息文本以提高清晰度。 不要无意中在 rebase 过程中删除提交。
在执行这样的 rebase 之后,我喜欢最后一次查看git log
以进行最终编辑
git commit --amend
最后,强制更新您的远程功能分支是必要的,因为该分支的 Git 提交历史记录已被重写
git push -f
使用标签
在您完成测试并准备好从master
分支部署软件之后,或者如果您想出于任何其他原因将当前状态保留为重要的里程碑,请创建一个 Git 标签。 虽然分支会累积与提交相对应的更改历史记录,但标签是该分支在该时刻状态的快照。 标签可以被认为是无历史记录的分支,或者是指向创建标签之前特定提交的命名指针。
配置控制是关于在各个里程碑保留代码状态。 能够重现任何里程碑的软件源代码,以便在必要时可以重建,这是大多数项目中的一项要求。 Git 标签为此类代码里程碑提供了唯一的标识符。 标记很简单
git tag milestone-id -m "short message saying what this milestone is about"
git push --tags # don't forget to explicitly push the tag to the remote
考虑一种情况,其中与给定 Git 标签对应的软件分发给客户,并且客户报告了一个问题。 虽然存储库中的代码可能会继续发展,但通常需要返回到与 Git 标签对应的代码状态,以精确重现客户问题,从而创建错误修复。 有时,较新的代码可能已经修复了该问题,但并非总是如此。 通常,您会检出特定的标签并从该标签创建一个分支
git checkout milestone-id # checkout the tag that was distributed to the customer
git checkout -b new-branch-name # create new branch to reproduce the bug
除此之外,如果它们可能对您的项目有益,请考虑使用带注释的标签和签名标签。
使可执行软件打印标签
在大多数嵌入式项目中,从软件构建创建的生成的二进制文件具有固定的名称。 与软件二进制文件相对应的 Git 标签无法从其文件名中推断出来。 在构建时将“标签嵌入”到软件中,以便将任何将来的问题精确地关联到给定的构建非常有用。 嵌入标签可以在构建过程中自动完成。 通常,在代码编译之前,会将标签字符串git describe
生成的内容插入到代码中,以便生成的正在运行的可执行文件在启动时打印标签字符串。 当客户报告问题时,可以引导他们向您发送启动输出的副本。
结论
Git 是一个复杂的工具,需要时间才能掌握。 使用这些实践可以帮助团队使用 Git 成功协作,无论他们的专业知识水平如何。
5 条评论