什么时候应该首次提交源代码控制?


118

我从不知道什么时候项目足够远,可以首先提交到源代码管理。我倾向于推迟提交,直到项目“框架完成”为止,然后我主要提交功能。(我还没有做过足够大的个人项目,以至于没有一个太大的核心框架。)我觉得这不是最佳实践,尽管我不确定会出什么问题。

例如,假设我有一个包含单个代码文件的项目。要使该项目具有极其基本的功能(1个或2个功能),将需要大约10行样板代码和100行。我应该首先签入:

  1. 空文件?
  2. 样板代码?
  3. 第一个功能?
  4. 在其他时候?

另外,在特定地点办理登机手续的原因是什么?


10
在回家之前,您需要先提交自己的工作分支。
Reactgular 2012年

59
在创建Sourceforge项目,设置网站,配置邮件列表以及对该项目进行博客撰写多年之后,应该始终进行第一次提交。:)
Kaz 2012年

15
太早或经常承诺的不利之处是什么?
艾萨克·拉比诺维奇

13
mkdir myproj; cd myproj; git init; 开始工作。
Eddie B

10
我通过视频游戏中的“快速保存”按钮了解了如何管理进度保存。规则是这样的:Will I mind having to redo that part ? Save : SaveAnyway;我采用相同的方法进行源代码控制,我不等待某项工作正常进行或接近完成,我只是等到发现某件事或进行了我不想要的足够的更改不得不再次尝试找出或再次进行更改,然后我签入。这就是为什么人们建议在项目创建后进行保存;创建项目很烦人,请签入,这样就绝对不必再次执行此操作。
Jimmy Hoffa

Answers:


103

您应该在明智的“单位”完成后立即提交。

什么是单位?这取决于你在做什么。例如,如果要创建Visual Studio项目,则即使解决方案中没有任何内容,也要在其创建后立即提交解决方案。

从那里开始,尽可能多地提交,但仍仅提交完成的“单元”(例如,类,配置等);这样可以在发生问题时使您的生活更轻松(您可以还原少量更改),并减少发生冲突的可能性。


27
我该死的不断靠近一个工作分支,然后将该分支合并到主线单元中。它提供了两全其美的优势,因为主线由具有少量要还原的更改集的单元组成,但是主题分支可以让我一次只备份一点。
杰夫·费兰德

16
提交永远不会太小!不要克制自己所做的更改!
莱昂纳多·埃雷拉

1
我想对许多小的,频繁的提交+1,具体取决于您的工作流程以及有多少人对您的回购感兴趣以完成他们的工作。Git可以稍微重写历史记录的功能,这样FooSerializer在您进行推送之前这15次提交就可以成为一件事。
蒂姆·波斯特

1
@loldop:这取决于您使用的版本控制软件。假设您使用的是Git:您可以存储所做的工作,进行修复,提交,重新应用隐藏的更改并重新开始进行处理。在Subversion中,您可以在另一个文件夹中对存储库进行另一次签出,修复错误并提交到该存储库中,而不会影响重构。或创建补丁文件,恢复您的编辑,修复错误,提交,重新应用补丁。有很多方法可以做到这一点。
Albireo 2012年

1
也许这是对第二次,第三次提交等的好答案。但是第一个应该是空的。
费利佩2012年

143

就我而言,您的源代码控制存储库是基本项目设置的一部分,因此我在生成空项目后立即提交。


29
提早提交,经常提交。
莱昂纳多·埃雷拉

11
我比接受的答案更同意这一点。如果我将事情搞砸了,我还将源代码控制(我的意思是DVCS)视为一个很大的撤消按钮。我也强烈建议您使用semver(通过标签),并从版本0开始
Antony Scott,

2
谢谢@AntonyScott我100%同意接受的答案,但是当我写这篇文章时,我有这样的愿景:用1500字的文章来混淆我如何管理源代码控制以及为什么。因此,我决定保持简洁明了。
约翰·麦金太尔

2
是的,+ 1。如果您对空的提交感到不满意,请从Xion在另一个答案[ programmers.stackexchange.com/a/176845/5405]中编写的.gitignore(或等效名称)开始。这是非常自然的第一次提交。
Hanno Fietz

我注意到问题上的“长答案”标志,不禁认为它是在指这个答案。AFAIC我回答了“为什么?” 问题与“源代码控制存储库是基本项目设置的一部分”的答案相同。就像我说的那样,我可以写一篇关于我如何使用源代码控制的完整哲学的文章,但这只会减损这个答案。如果有人对我的答案有特定的疑问,我会很乐意回答,但否则我不想为了age语而把这个答案弄虚作假。如果要删除它,请继续。
约翰·麦金太尔

77

昨天

...或者,如果您无法进行时间旅行...
(也许您的汽车无法达到88mph的速度,或者您的磁通电容器刚被卡住)

现在

新项目应该在流血的地方进行,这是疯狂的,不要疯狂,当代DVCS系统只是删除了所有可能的借口以避免提交git init . ; git add * ; git commit -m initial-commit现在,在为时已晚之前,也许已经如此。

一个更明智,可争论的问题可能是:“我什么时候应该提交的内容合并到已建立项目的团队托管存储库上的共享源代码控制中?” (请注意形容词,形容词很重要)而且我觉得大多数其他答案实际上都是在试图回答这一问题。

您的个人分支应该承诺每天至少睡前疯狂一次。您可能只是在第二天早上醒来,却不知道前一天晚上到底要做什么。VCS应该可以解决这个问题,并且有机会回滚到一个最新的sub-sub-sub-version版本,该版本可以很好地编译,平稳运行和/或通过测试可能是您的最佳选择。


3
我不介意提交无法编译的更改,尤其是在一天结束时。第二天,您会遇到一些无法编译的内容,但是您仍然拥有提交历史记录-如果您不希望历史记录“肮脏”,则每个好的DVCS都有回滚选项(我认为我们都同意DVCS是唯一的方法
莱昂纳多·埃雷拉

@LeonardoHerrera我了解您的POV,尽管在具有多个入口点的解释语言项目中,您最终由于合理的原因(例如在不同的入口点上共享错误修复程序)提交了一些未编译的分支,但肯定可以做得更好并且更好,但后来却变成了一个品味的问题...和gust bus non est disandandum
ZJR 2014年

20

我会说尽快提交。源代码控制的主要目的是允许您在出现问题时返回,这与“尽早提交并经常”实践产生共鸣。

就个人而言,我的第一次提交通常只包含.gitignore文件(或等效文件),其中包含我知道几乎不需要的过滤器,例如Python代码的* .py [co]。通常会遵循基本的项目设置和/或第一个最简单的原型。


我做类似的事情。由于我使用的是GitHub,所以我也始终有一个基本的README文件,即使它仅包含项目的名称。我发现从一开始就拥有该文件,这使我将来很有可能会更新它的可能性更大:)。
迪洪

16

第一次提交可以是一个README文件,其中包含项目的一行摘要,或者有关该项目的第一个里程碑的足够信息。广泛的主题还可以包括:

  • 介绍
  • 项目描述
  • 项目结构
  • 编码约定
  • 有关如何执行以下操作的说明:
    • 建立
    • 测试
    • 部署
  • 已知问题和解决方法
  • 待办事项清单
  • 使用条款

在对项目进行更改之前更新自述文件的做法也称为自述驱动开发,它使您可以在花费时间进行更改之前仔细考虑更改。

任何想要为该软件做出贡献或使用该软件的人都将从README开始。


12

如果您完成了不想丢失的工作,那么它应该在源代码控制系统中。

这当然适用于像Git这样的分布式系统。如果您使用的是集中式系统,那么签入某项内容的唯一方法就是使所有人都可以看到它,那么您可能希望暂缓执行-或者您可以考虑建立自己的本地git存储库,然后提交给集中式系统系统准备就绪时。


3
我的规则是这样,此外,我还希望它成为“代码编译的时间点”。如果您必须找出什么时候弄坏了东西,那么提交那些不能编译和平分的东西会变得更加烦人。
沃伦·P

至少对于git来说,临时分支不会地址吗?我没用git bisect太多。
基思·汤普森

我使用Mercurial时无需重新设置基准,因此我将所有提交都视为永久提交
Warren P

7

我的经验法则是,一旦解决方案文件(或其他构建脚本段)完成,则签入,即使其中包含一些空文件也是如此。对于一个以上的人从事该项目的情况,这是一个好习惯。最初,该文件往往存在最严重的合并问题,因为人们正在向项目中添加内容,因此需要尽早且经常提交。

即使您是唯一从事该项目的人,并且只有一个文件,我发现遵循相同的工作流程并省去对当前问题的思考也变得更加容易。


6

知道它是否被提及。

但是请确保您提交的内容可以运行/编译!因此没有语法错误等。

没有什么比结帐已损坏的代码更令人沮丧的了。


确实有道理!
Aquarius_Girl 2012年

我不同意。如果我的代码在提交时无法编译,则在提交消息中的某处写入WIP。然后,当我需要最新版本的编译时,我就可以忽略这些提交。
Minthos

5

一旦有了绿色的新测试用例,便会提交与软件测试(TDD方法)更相关的其他观点。这意味着您已经完成了一个新的“单元”代码。


要覆盖一个方法,您可能(通常)需要对其进行几个单元测试。说您通过了测试合格并不是真的,这意味着您要完成一个工作单元。说完成该方法也是一项工作单元,这甚至都不是真的。
Behnam Rasooli '17

5

在您做一些愚蠢的事情之前。

对于我们这些没有魔力的人来说,这意味着很少而且经常如此。

如果您是一个人工作,请在每次喝一杯或其他任何东西时进行。

如果您在团队中工作,则可能需要确保该事物能够编译,以便其他人获取最新信息时,他们不会遇到很多错误。但是除此之外,您还可以做到。


4

大约2到3个小时进入项目。

开玩笑吧 没有一个适合所有情况的好答案。首先,如果您具有分布式版本控制系统(如git或Mercurial),则在发生灾难性故障的情况下,提交给本地存储库将不会保留您的数据。但是一个私有的远程仓库可能会花你钱,例如在github上。您将保留提交历史记录,但是根据我的经验,直到您的项目进行了一些高级操作之前,您将不需要它。

另外,一开始您可能不需要太多的改动,尤其是当您移动文件时。如果只是很小的一部分,那么进行更改将是一个负担。您甚至可能决定扔掉东西。但是,如果您丢失了难以复制的更改,那么您将错过制作备份副本的机会,而版本控制系统将为您带来极为宝贵的备份系统。

如今有些人使用DropBox或类似的东西来存储他们的代码。在项目开始时,这可能是一个很好的折衷方案,因为它的建立工作量为零。但是,在认真的软件开发中,这是一种野蛮的习惯,尤其是当几个人同时接触代码时。

因此,我倾向于在有有价值的东西(即不容易复制的东西)时设置版本控制。价值是主观的(取决于个人的能力),因此您将必须做出自己的判断。那时,我将第二个存储库存储在外部磁盘上,或者存储在github上(如果它是公共项目),或者我的付费帐户将存储它。


3

许多人已经回答“马上”,我100%同意。我也喜欢Xion的建议,以VCS的忽略模式(即.gitignore等效模式)开始。

我猜已经很早就达成共识了。我想补充一点:

  • 您不太可能提交您选择丢弃的东西,但是仍然存在。当我开始一个新的开发时,我将快速编码并散布东西,而当我稍后提交时,当已经有很多文件时,我意外地提交了东西,只是在下一次提交中将其删除。与小的甚至是空的提交相反,这是历史上的真实声音。
  • 如果您是系统的类型,并且在项目中具有典型的第一步,那么将这些作为提交点可能对您或其他人有指导意义,甚至可能提供在特定点分支并创建可重复使用的项目存根的机会。我已经在基于Maven的项目中,这是非常有用的(因为在建立Maven项目,一些小的第一步已经可以定义一个相当可观的基础工作,虽然这些步骤都没有太大的,他们可能需要足够的思考,以保证可重用性)。

2

这可能取决于您所使用的VCS。

使用Git,我提交了一个空目录(或几乎是空的README文件)。关键是,如果我仍要在开发过程的早期(在推向上游之前)完全重新开始,则可以返回并将分支重置为空状态。然后,我将提交“生成的”文件(例如,Visual Studio解决方案)。然后,当我实际编码时,我将像通常一样开始提交每个单元。

使用SVN,每次提交都将您推向上游,因此您真的不会像使用Git那样获得重新开始的奢侈。在这种情况下,如果您认为要在此过程中尽早进行重大修改,那么尽早提交可能没有好处。不过,这将取决于编码人员。


2

当我开始一个新项目时,我通常会在添加任何代码之前先进行确认。我一直遵循的一般经验法则是:如果您的PC崩溃并擦除了所有数据,则您不希望从内存中写入什么代码。十年之前,在TDD和更好的编程实践之前,我对自己能记住的东西非常乐观。现在,我倾向于更加谨慎。正如许多其他发布者所说的那样,提早提交并经常提交。您这样做不会损失任何东西。

我大部分时间都是在自己工作,所以我必须承认自己越来越懒惰,但是我通常会在回家之前就下定决心。这样,如果我明天不去的话,那么我的同事们可以在我离开的地方接机。

我目前正在使用Tortoise / SVN。


2

立即提交空项目。您每小时花在项目上的时间要提交几次。即使代码没有编译也要提交。我在提交消息中用“ WIP”标记这些提交,以跟踪它们。

我还有一个脚本,可以每10分钟自动将我的所有项目提交到备份存储库,以防万一我忘记手动提交。我们称其为云支持的撤消缓冲区。

检查(亦称)项目的团队回购,当你需要你的团队,看看你的代码。如果您像我一样,那可能是在您的代码准备好供团队查看之前。

如果您想对团队友善,请先压缩提交内容,然后再将其提交给团队存储库。


1

我浏览了所有文章,我认为我们已经有了很多好的解决方案,但我想与您分享我的方法论。

在进行框架创建时(从头开始),每个模块都将进行很多更改,直到该模块完成或完成为止。因此,我始终有2个位置,其中一个被称为DYNAMIC,另一个被称为STATIC。当进行更改且尚未完成框架时,已在DYANMIC位置提交了框架,完成并完成后,我将其移至STATIC位置。所以我有一个完整的源代码管理。

谢谢


0

对于任何应用程序,您都将花费一些时间来设计组件。您应该大致或完整地了解您的名称空间,项目,外部引用,第三方库等。

如果您在团队中,我建议您带领或选择任何人来创建基础项目,获取依赖项集,并检查其骨架(将在其上构建项目的基础)。

您还希望确保在签入之前指定了您的任务,版本,主干等分支,以便您的流程稳定。

如果您正在为一个已经在进行中的项目处理新的“任务”,并且您在自己的任务分支中,请每晚进行检入,以保留工作。


0

通常,每当我添加新内容时,我都会签入,但尝试在离散提交中将内容分开。

这意味着,如果我添加了新的依赖项,我将进行更改,直到它们要么编译,要么它们足够大为止,这将浪费时间从头开始再次进行更改。如果我有更大的任务,则在有意义的情况下尝试进行多次提交(每个函数一次,每次使其编译并成功运行等)。

当我想要一个备份点时(例如,“如果我现在尝试的操作不起作用或变得太复杂,我想回到现在的代码中”,或者有人要求我放弃我的身份时,我也会提交)并解决一些紧急问题)。

如果使用集中式源代码控制系统,则不能随意提交备份点,因为不进行编译/工作的提交会影响团队中的每个人。

通常,当我开始添加样板代码(例如,在django网站中添加新的webapp)时,我会执行我所做的所有操作。

如果我按照教程来生成/编写代码,则在教程中将步骤名称用于提交消息。这样,我可以在以后的任何时候比较修订版本并查看教程步骤做了什么。

例如,假设我有一个包含单个代码文件的项目。要使该项目具有极其基本的功能(1个或2个功能),将需要大约10行样板代码和100行。

这取决于添加内容的难度:

  • 如果添加样板代码是微不足道的,那么我将添加它并在开始其他代码之前提交(这样,如果我犯了错误或以后引入了怪异的错误,我可以简单地恢复到样板代码并开始再次)。

  • 如果代码不平凡,那么每次添加新内容(每两行代码之间的任何地方更改到一百左右)时,我都会提交一次。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.