git git提交最佳实践

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6543913/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-19 05:38:44  来源:igfitidea点击:

git commit best practices

git

提问by Ivan Z. Siu

I am using git to manage a C++ project. When I am working on the projects, I find it hard to organize the changes into commits when changing things that are related to many places.

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

For example, I may change a class interface in a .hfile, which will affect the corresponding .cppfile, and also other files using it. I am not sure whether it is reasonable to put all the stuff into one big commit.

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

Intuitively, I think the commits should be modular, each one of them corresponds to a functional update/change, so that the collaborators could pick things accordingly. But seems that sometimes it is inevitable to include lots of files and changes to make a functional change actually work.

直觉上,我认为提交应该是模块化的,每个提交对应一个功能更新/更改,以便合作者可以相应地选择内容。但似乎有时不可避免地要包含大量文件和更改以使功能更改真正起作用。

Searching did not yield me any good suggestion or tips. Hence I wonder if anyone could give me some best practices when doing commits.

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

PS. I've been using git for a while and I know how to interactively add/rebase/split/amend/... What I am asking is the PHILOSOPHY part.

附注。我已经使用 git 一段时间了,我知道如何以交互方式添加/rebase/split/amend/...我要问的是 PHILOSOPHY 部分。

Update: Thanks for all the advices. Maybe this should be learned from practicing. I will keep the problem open for some time to see if there is more suggestions.

更新:感谢您的所有建议。也许这应该从实践中学到。我将问题保持开放一段时间,看看是否有更多建议。

回答by vhallac

I tend to commit as you propose: a commit is a logically connected change set. My commits can be anything from a one-liner to a change in all files (for example add/change a copyright notice in the source files). The reason for change need not be a full task that I am implementing, but it is usually a milestone in the task.

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

If I have modified something that is not related to my current commit, I tend to do an interactive add to separate out the unrelated changes, too - even when it is a whitespace tidy up.

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

I have found that commits that simply dump the working state to repository makes them a lot less useful: I cannot backport a bugfix to an earlier version or include a utility functionality in another branch easily if the commits are all over the place.

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

One alternative to this approach is using a lot of tiny commits inside a feature branch, and once the whole feature is done, do heavy history rewriting to tidy up the commits into a logical structure. But I find this approach to be a time waster.

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

回答by Lakshman Prasad

This is exactly the use case, for which the index, the staging area, was introduced in git.

这正是indexgit 中引入的暂存区的用例。

You can feel free to do as many changes unrelated to each other as possible. Then you choosewhat all are related and then make several atomic commits in one shot.

您可以随意进行尽可能多的彼此无关的更改。然后您选择所有相关的内容,然后一次性进行多次原子提交。

I do it all the time. If you use git-guior any of the other GUI clients, you can choose not only the filethat you want to commit, but also hunks within the files, so your commits are as atomic as possible.

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

回答by Sailesh

I try and follow these practices in the order...

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

  1. A commit must not fail a build. Most important!

  2. It should be made of one logical unit of change - whether a single line/character or a whole file/class with corresponding changes in other parts of code, still following #1.

    What is a logical unit of change? In terms of git, if you can specify the changes in the commit message in least number of characters, in one sentence (without ANDs of-course), and you can not break that description further into smaller units, that I call one unit.

  3. Commit message should clearly specify the essence of the commit.

  4. Commit message should be small, typically no greater than 80 chars. Any more elaboration should be part of the description.

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

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

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

  3. 提交消息应该清楚地说明提交的本质。

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

回答by Geoff

Disclaimer: I too am in the process of trying to work out what commits should be, and how the final history should end up looking. However, I wanted to share some of the resources that I've come across during my own research.

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

First off, the Linux Kernel project has a great page on Merge Strategiesfor getting your code merged upstream. They talk about making bite-sized commits; doing one or more refactoring commits before the actual additions you want (the refactorings are supposed to make your feature cleaner of course ;) and other things.

首先,Linux Kernel 项目在Merge Strategies上有一个很棒的页面,可以让你的代码在上游合并。他们谈论进行一口大小的提交;在你想要的实际添加之前做一个或多个重构提交(重构当然应该让你的功能更干净;)和其他事情。

My other favorite page is Git Best Practicesby Seth Robertson. This is not only a page on a lot of best practices for using git, but it also is a tremendous resource, containing enough information about a broad variety of git topics to make googling for more in-depth information trivial.

我最喜欢的另一个页面是Seth Robertson 的Git 最佳实践。这不仅是关于使用 git 的许多最佳实践的页面,而且还是一个巨大的资源,包含有关各种 git 主题的足够信息,使谷歌搜索更深入的信息变得微不足道。

回答by Fagner Brack

What I am asking is the PHILOSOPHY part.

我要问的是哲学部分。

I think I can answer this because I have been involved in some personal research recently.

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

One should focus in creating an atomic commit. Which means that it's necessary to take some extra care in a few things for a commit:

人们应该专注于创建一个原子提交。这意味着有必要在提交时特别注意以下几点:

  • It shouldn't have any value if done partly
  • It shouldn't break the build
  • It should contain a good message and body for traceability (with tickets reference whenever possible)
  • It shouldn't contain a lot of diff noise (whitespace and style changes, unless the commit is specific for that)
  • 如果部分完成,它应该没有任何价值
  • 它不应该破坏构建
  • 它应该包含一个良好的消息和可追溯性的正文(尽可能提供票证参考)
  • 它不应该包含很多差异噪声(空白和样式更改,除非提交是特定的)

Commits should be focused in one change, and one change only. Anything more than that can have bad side-effects.

提交应该专注于一项更改,并且只关注一项更改。除此之外的任何事情都会产生不良的副作用。

Some people might argue that this is too much, that it is not practical. But the best argument in favor of it, even for small companies, is the fact that bulding atomic commits will force your design to be more decoupled and consistent, because one requirement to achieve full optimal atomic commits is to have a healthy codebase that is not a mess.

有些人可能会争辩说这太过分了,不切实际。但支持它的最佳论点,即使对于小公司,也是这样一个事实,即构建原子提交将迫使您的设计更加解耦和一致,因为实现完全最佳原子提交的一个要求是拥有一个健康的代码库,而不是一团糟。

If you force good commit practices consistently, you will be able to drive the engineering culture and the code itself to a better state.

如果您始终如一地强制执行良好的提交实践,您将能够推动工程文化和代码本身达到更好的状态。

回答by Jan Hudec

Sometimes when you do big refactoring, it's inevitable that you change many files in one commit. When you change interface of a class, you have to change the header, the implementation and all places that use the interface in one commit, because no intermediate state would work.

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

However, the recommended practice is to change the interface without actually introducing any new functionality first, test that you didn't break existing functionality and commit that. Than implement the actual feature that needed the updated interface and commit that separately. You will probably end up doing some adjustments to the refactoring in the process that you'll squash to the first commit using interactive rebase.

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

That way there is a big commit, but it does not do anything hard, just shuffles code around, so it should be mostly easy to understand even though it's big and than second commit (or more, if the feature is big) that is not too big.

这样有一个很大的提交,但它不会做任何困难的事情,只是将代码混在一起,所以它应该很容易理解,即使它很大而且比第二次提交(或更多,如果功能很大)不是太大。

回答by beseku

Something that very much helped me in working out what I was committing, and why, was moving our repository organisation over to the 'feature branch' model, as popularised by the Git Flow extension.

非常有助于我确定我正在提交的内容以及为什么将我们的存储库组织转移到“功能分支”模型的事情,正如Git Flow 扩展所流行的那样。

By having branches describing each feature (or update, bugfix etc) that is being worked on, commits become less about the feature and more about how you are going about implementing that feature. For example, I was recently fixing a timezone bug within its own bugfix branch (bugfixes/gh-87 for example), and the commits were split up into what was done or the server side and the front end, and within the tests. Because all of this was happening on a branch dedicated to that bug, (with a GitHub issue number too, for clarity and auto closing), my commits were seen as the incremental steps in solving that problem, and so required less explanation as to why I was doing them.

通过让分支描述正在处理的每个功能(或更新、错误修复等),提交变得与功能无关,而更多地与您将如何实现该功能有关。例如,我最近在自己的 bugfix 分支(例如 bugfixes/gh-87)中修复了一个时区错误,并且提交被分成做了什么或服务器端和前端,以及在测试中。因为所有这一切都发生在一个专门针对该错误的分支上(为了清晰和自动关闭,我的提交也有一个 GitHub 问题编号),所以我的提交被视为解决该问题的增量步骤,因此不需要解释为什么我在做他们。