git提交最佳实践

时间:2011-07-01 05:26:29

标签: git

我正在使用git来管理C ++项目。当我在处理这些项目时,我发现在更改与许多地方相关的内容时,很难将更改组织到提交中。

例如,我可能会更改.h文件中的类接口,这将影响相应的.cpp文件,以及使用它的其他文件。我不确定将所有内容都放到一个大的提交中是否合理。

直观地说,我认为提交应该是模块化的,每个提交对应一个功能更新/更改,以便协作者可以相应地选择事物。但似乎有时不可避免地要包含大量文件和更改以使功能更改实际起作用。

搜索没有给我任何好的建议或提示。因此,我想知道在做提交时是否有人可以给我一些最佳实践。

PS。我一直在使用git,我知道如何以交互方式添加/ rebase / split / amend / ...我要问的是哲学部分。

更新:感谢您的所有建议。也许这应该从练习中学到。我会将问题保持一段时间,以确定是否有更多建议。

7 个答案:

答案 0 :(得分:20)

我倾向于按照您的建议提交:提交是逻辑上连接的更改集。我的提交可以是从单行到所有文件中的更改(例如,在源文件中添加/更改版权声明)。改变的原因不一定是我正在实施的完整任务,但它通常是任务中的里程碑。

如果我修改了与当前提交无关的内容,我倾向于进行交互式添加以分离出不相关的更改 - 即使它是一个空白的整理空间。

我发现只是简单地将工作状态转储到存储库的提交使它们变得不那么有用:我不能将错误修复向后移植到早期版本,或者如果提交到处都很容易在另一个分支中包含实用程序功能。

此方法的一种替代方法是在功能分支内部使用大量微小提交,并且一旦完成整个功能,请执行大量历史记录重写以将提交整理为逻辑结构。但我发现这种做法浪费时间。

答案 1 :(得分:16)

这正是用例,git中引入了index,暂存区域。

您可以随意尽可能多地进行相互关联的更改。 然后你选择所有相关的东西,然后一次性地进行几次原子提交。

我一直这样做。如果您使用git-gui或任何其他GUI客户端,您不仅可以选择要提交的文件,还可以选择hunks within the files,因此您的提交是原子的尽可能。

答案 2 :(得分:14)

我尝试按顺序遵循这些做法......

  1. 提交不得使构建失败。最重要的!

  2. 它应该由一个逻辑变更单元组成 - 无论是单行/字符还是整个文件/类,其他代码部分都有相应的变化,仍然遵循#1。

    什么是变革的逻辑单位?就git而言,如果您可以在一个句子中指定最少数量的字符的提交消息中的更改(没有当然的AND),并且您不能将该描述进一步分解为更小的单位,那么我叫一个单位。

  3. 提交消息应明确指出提交的本质。

  4. 提交消息应该很小,通常不超过80个字符。任何更详细的说明都应该是description

  5. 的一部分

答案 3 :(得分:10)

免责声明:我也正在努力弄清楚应该提交什么,以及最终历史应该如何结束。但是,我想分享一些我在自己的研究中遇到的资源。

首先,Linux内核项目在Merge Strategies上有一个很棒的页面,用于将代码合并到上游。他们谈论制作一口大小的提交;在你想要的实际添加之前做一个或多个重构提交(重构应该使你的功能更加清晰;)和其他东西。

我最喜欢的页面是Seth Robertson的Git Best Practices。这不仅是关于使用git的许多最佳实践的页面,而且它也是一个巨大的资源,包含有关各种git主题的足够信息,以便在Google上搜索更深入的信息。

答案 4 :(得分:4)

  

我要问的是哲学部分。

我想我可以回答这个问题,因为我最近参与了一些个人研究。

应该专注于创建atomic commit。这意味着有必要在一些事情上采取一些额外的关注来提交:

  • 如果部分完成则不应该有任何价值
  • 它不应该破坏构建
  • 它应该包含一个好的消息和正文以供追溯(尽可能使用票证参考)
  • 它不应该包含很多差异噪声(空格和样式更改,除非提交是特定的)

提交应该集中在one change, and one change only。除此之外的任何事情都会产生不良副作用。

有些人可能认为这太过分了,不实用。但是支持它的最好的论据,即使对于小公司来说,最大的原因是大量的原子提交将迫使你的设计更加分离和一致,因为实现完全最佳原子提交的一个要求是拥有一个健康的代码库,而不是一团糟。

如果您持续强制执行良好的提交实践,您将能够将工程文化和代码本身推向更好的状态。

答案 5 :(得分:3)

有时当你进行大量重构时,你不可避免地会在一次提交中更改许多文件。当您更改类的接口时,您必须在一次提交中更改标头,实现和所有使用该接口的位置,因为没有中间状态可以工作。

但是,建议的做法是更改界面而不先实际引入任何新功能,测试您没有破坏现有功能并提交。比实现需要更新接口的实际功能并单独提交。您最终可能会对使用交互式rebase压缩到第一次提交的过程中的重构进行一些调整。

这种方式有一个很大的提交,但它没有做任何努力,只是随机播放代码,所以它应该很容易理解,即使它很大而不是第二次提交(或更多,如果功能很大)那不算太大。

答案 6 :(得分:1)

非常有助于我弄清楚我提交的内容以及为什么将我们的存储库组织转移到'{3}}推广的'feature branch'模型。

通过分支描述正在处理的每个功能(或更新,错误修复等),提交对功能的关注度降低,更多地关于如何实现该功能。例如,我最近在其自己的bugfix分支中修复了一个时区错误(例如bugfixes / gh-87),并且提交被分成了已完成的内容或服务器端和前端,以及测试内部。因为所有这些都发生在致力于该错误的分支上(Git Flow extension),我的提交被视为解决该问题的渐进步骤,因此需要更少解释为什么我这样做。