目录
介绍
您需要版本控制吗?
- 我以前从未使用过版本控制
- 我想我可能想尝试版本控制
- 我希望版本控制为我工作
- 我不想使用它工作
如果这描述了你,那么请继续阅读,希望这将帮助你为自己选择一个版本控制系统,虽然我不能保证它会让你的生活变得更好,但如果你找到一个确实“适合你”的系统,那么它不会让它变得更难,我敢打赌,你会找到你甚至没有寻找的好处!
作为一个初学者,我猜在你开始(或者在我的情况下,重新开始)很长一段时间内甚至不考虑版本控制是很常见的,但在某些时候,它可能会出现在你身上——突然意识到,如果你能跟踪代码中发生的各种变化,你的生活会更轻松。希望这不是灾难的结果(这几乎是发生在我身上的事情,幸运的是我发现它来得及时),从那以后我发现了一大堆其他使用版本控制的好理由。
因此,我花了一些时间尝试选择一个版本控制系统(VCS),并认为我会分享我的经验,因为对于初学者来说,选择一个并运行它可能是一个非常令人生畏的想法——毕竟你已经处于陡峭的学习曲线上,为什么你想在学习VCS的同时加倍头疼?虽然这通常是你得到的建议类型:
使用这个[插入你能想到的几乎所有系统的名称],学习命令行,它很棒
不是我的乐趣。我想要它简单。
如果您只想直接跳转到比较,那么请这样做。
如果你对我对所有术语的含义感兴趣,那么我试图在已经存在的数百万个解释中加入我的两便士。为什么?它们中的大多数都是由专家编写的,虽然第一句话是以傻瓜模式写的,但紧随其后的是爱因斯坦模式的几句话。我不可能进入爱因斯坦模式,我才刚刚开始。因此,如果您拥有与几周前相同的知识水平,希望我的版本更有用。
背景
一些基本假设:
- 你希望使用一个分布式版本控制系统,而不是像 Subversion 这样历来流行的工具方法。
- 你想要一个GUI,但不想学习命令行。
为什么要做出这些假设?相反,如果你是命令行专家,那么你可能不需要我帮忙选择VCS。分布式VCS风靡一时,大多数事情似乎都在朝着这个方向发展,所以如果你想参与一个开源项目,或者让你的项目作为开源项目向世界开放,那么它现在可能是一个更好的选择。
概念
如果您了解基础知识或只想直接进行比较,那么您可以这样做。
首先,关于版本控制的一些基本概念,我通过尝试、犯错、找出我做错了什么以及通过纠正错误来学习这些概念。如果通过阅读学习对你有用,那么这可能有助于更好地理解选择VCS的部分,否则选择一个并开始犯错误,很难完全&*%^事情。我试图按逻辑对它们进行排序,但有时会变得有点循环。
这是我的理解,从初学者到初学者。如果它从根本上是错误的,那么请告诉我,如果它看起来有点过于简单,那么考虑到目标受众,这可能是可以的。我怀疑我会在几个月/几年后回顾这一点,并想知道我的知识水平微不足道,希望我不会回头想知道我怎么弄错了!
请记住,我在这里关注的是分布式版本控制,这些术语在历史上的VCS中可能意味着不同的东西,比如Subversion。
在这一点上,我认为所有不同的VCS和DVCS有时可以对完全相同的事情使用不同的术语,或者至少是非常相似的事情;您可能还会发现同一个术语用于两种不同的事情——哦,太好了,这让它变得更容易!
存储库
构成项目的文件集合(带或不带版本控制)以及由VCS维护的数据库。VCS只是允许您轻松跟踪更改、创建新版本、创建分支等,并在它们之间轻松切换。
存储库可以是本地的,也可以是硬盘上的本地存储库,也可以是某个服务器上的远程存储库。在分布式VCS世界中,即使使用远程托管的项目,您的本地副本也是远程副本的完整副本,也就是说,它是一个完整的存储库,而不仅仅是您碰巧正在处理的部分。
分布式
如果您独自工作,尤其是如果您只在本地工作,则完全无需担心这一点。
由于我没有使用过远程存储库,因此我在这里需要纠正。
分布式VCS系统的关键在于不必有一个主存储库,每个贡献者都有整个存储库的完整副本。因此,您正在点对点工作,而不是客户端服务器。中央存储库可以充当主存储库,但同样可以只是一个有用的保存点,所有开发人员都可以将其更新发送到其他人并从中获取更新。开发团队在定义代码的主版本方面的行为方式取决于他们。
因此,在接受每个人的更改进入中央代码库之前,不需要有一个看门人来审查它们。通常有人扮演这个角色,但由于每个开发人员都有存储库的完整副本,因此不需要VCS工作,只需要理智。
每个开发人员都拥有存储库的完整副本会带来各种好处,但本文不是关于这个的,所以如果你需要知道(或只是想知道),那么很容易通过谷歌找到大量的评论。
工作目录
如果没有版本控制,您的工作目录就是您的项目文件夹(以及任何子文件夹)。对于分布式版本控制,情况是一样的,只有您能够非常快速、轻松地将工作目录更新到您想要处理的任何版本的代码。
分支和尖端
分支实质上采用代码的单个版本并创建它的两个副本。然后,您可以相互独立地更改这两个副本,对其中一个副本的更改不会影响另一个副本。
两个分支,主干和例如功能分支
在上图中,蓝色矩形表示项目的特定版本,即给定时刻的快照。而箭头表示您对代码进行更改、添加和删除文件等。从A1到B1的深橙色箭头表示分支的创建以及进行代码更改。
因此,分支在概念上听起来非常容易,而且确实如此,但是它变得复杂了,有许多不同的方式,特定的个人和不同的项目决定处理他们希望在项目中进行的不同更改(新功能,错误修复等)。在单个VCS中分支也有不同的方法,当您查看多个VCS时,还有更多方法。
为了简单起见,我将定义一个简单的工作模型,其中有一个中心或主分支,我们称之为主干(您还会听到基线或默认等术语)。我们很少会直接对中继进行更改。大多数情况下,我们将创建一个分支,对其进行更改,然后在完成后将其合并回主干中。
尖端只是一条支线的末端,在它被合并到主干或另一个分支之前。
更改集
表示提交与先前提交(项目的两个版本)之间差异的所有更改。假设您对项目中的某个文件进行了一些更改,然后提交了该更改,则更改集是您刚刚进行的提交与前一个提交之间的差值,即您对该文件所做的更改。
如果回头看上图,则在A1和A2之间所做的更改是针对您所做的提交和创建A2的更改集。
因此,当你进行提交时,你基本上定义了一个起点(先前的提交)、一组更改和终点(新的提交)。
树干(Trunk)
另一个我需要纠正的地方。
作为一个术语,我认为它是预分发时代的遗留物,在预分发时代(我认为)总是有一个主干充当中央存储库中的主分支(一个分支统治所有分支)。在分布式世界中,它并没有消失,但没有必要拥有一个,你可以用你的分支模型变得时髦和复杂。然而,据我所知,大多数人似乎已经在他们选择使用的分支模型中加入了一个替代品(用于树干的概念)。我的是我之前描述的工作模型,我基本上有一个名称的主干,我从不直接更改它,只是通过将分支合并到其中,但我不必以这种方式工作。
如果你仔细想想,如果没有某种过程来连接在一起,对一个项目所做的所有不同的更改,可能是由不同的人(甚至只是由你)进行的,那么你就会陷入无政府状态。我认为像Subversion这样的历史VCS通过层次结构实现了这种控制,主干是层次结构的顶部。在分布式世界中,人员和项目决定如何去做,而不是由VCS告诉如何去做,也就是说,他们定义了一个工作模型,其中必须有一些东西,从概念上讲,就像一个树干。
合并
使树枝呈圆形,或将它们连接回树干,或将它们与另一根树枝连接。无论如何,这是不同分支连接的过程。从本质上讲,它与分支相反。因此,如果分支创建代码的单个版本的两个独立副本,则合并将采用两个独立版本,并创建一个包含这两个版本的新单个版本。假设您从版本1(分支A)开始,其中包含一个文件(index.php)。然后,创建一个新分支B,并将第二个文件添加到分支B(menu.php),并将其他文件添加到分支A(footer.php)。这两个分支现在完全不同了。如果现在合并这两个分支,则会创建一个包含所有三个文件的新版本。
如果您喜欢图片,请尝试按照下图进行操作。如果你喜欢文字,那么我还添加了图片的口头描述。和以前一样,蓝色矩形表示快照,箭头表示您正在进行更改。其中一种类型的更改不是实际编码,而是合并两个快照以创建一个新快照,即B2和C2合并以生成B3。此外,A3和B4也被合并以创建A4。
两个要素分支向主干合并
- 从分支A(中继)中的版本A1开始。
- 从A1创建分支C,进行一些更改以创建C1。
- 进行更多更改以创建C2。
- 切换回A1,进行一些更改以创建A2。
- 从A2创建分支B,进行一些更改以创建B1。
- 进行更多更改以创建B2。
- 不要对B2进行更改,而是将C2合并到B2中以创建B3。
- 再进行一些更改以创建B4。
- 切换回A2,进行一些更改以创建A3。
- 不要对A3进行更改,而是将B4合并到A3中以创建A4。
例如,与B1到B2或B3到B4不同,没有对B2进行任何更改以创建B3。B3的更改集是通过将C2合并到B2中创建的。合并A3和B4时也是如此
提交/修订
进行提交会创建一个新的修订版(版本),即当时代码的快照。该快照不像完整备份,它更像是一组重新创建该版本、起点和更改集的指令。
因此,您正在开发一个名为FootBook的新产品,并且想要添加一个名为ToeCracker的功能。因此,您将该过程分为三个步骤,Load,Aim和Fire。完成第一步(Load)的开发后,您决定保留到目前为止的进度的永久记录。你做了一个提交。这将修复版本控制数据库中项目在该时间点的状态记录。然后,您可以开始处理该ToeCracker功能的Aim部分。如果在Aim的第一次努力完全失败,您可以通过拒绝到目前为止所做的所有更改(或仅拒绝其中的一部分)来快速恢复到良好状态,您不必去寻找3周前所做的备份并手动取消所有备份。
成功完成该Fire功能(并且ToeCracker完成)后,您可以将当时所做的提交合并回主干中。ToeCracker现在是您中继的一部分,即您FTP到实时服务器的一部分,因此下次您更新FootBook网站时,每个人都可以试用该ToeCracker功能。
创建ToeCracker功能
它还允许您暂时停止ToeCracker上的工作并开始在不同的分支中处理不同的功能,然后切换回ToeCracker而不会丢失您所做的任何更改,即,提交不一定是某事的结束,它们可能只是一个方便的停止点,如果你愿意,你可以每天晚上睡觉前做一个, 没人在乎。他们只关心该分支末尾的最终提交。
暂存
完成Load后,您开始在Aim上工作并更改三个文件,A、B和C。你已经准备好进行提交,但对C的更改与Aim并不真正相关,它们应该是Fire的一部分,所以你不希望它们被包括在内,你想在Fire完成后将它们保存到下一次提交时。
很简单,在每次提交之前,您必须暂存要包含在提交中的文件(已更改的文件)。如果你没有暂存其中之一,它会保留其更改,但提交会忽略它们,即提交使用未更改的C版本(来自以前的版本),但你没有丢失更改,你只是延迟了提交它们;因此,他们不会进入数据库中的那个版本,他们会进入以后的版本。
只是不要忘记在提交之前接受更改,即使它们没有暂存,否则你会丢失它们,尽管你经常会收到警告,并有机会取消提交。
推送和拉取
如果您独自工作,尤其是如果您只在本地工作,您可能根本不需要担心这一点。除非使用克隆作为分支的一种方式。
由于我没有使用过远程存储库,因此我在这里需要纠正。
因此,假设Sam想帮助FootBook。因此,您现在需要使用远程存储库,以便您和Sam可以相互共享更新,并在GitHub上启动一个项目。当您在本地存储库中完成新功能时,您可以将该更改推送到远程存储库。然后,Sam可以将其从远程存储库拉取到本地存储库中。现在,你们俩都拥有了该项目的完整最新副本(以及它如何更改的所有历史记录),而无需在帖子中相互发送U盘。
在存储库之间推送和拉取
您只能在不同的存储库之间推送和拉取。
分叉(Fork)
分叉本质上是一个永久分支,通常移动到不同的存储库中。你可以去掉术语分支,只称之为临时分叉。
所以你和你的伴侣Sam正在FootBook上工作。你们俩都在开发FootBook的功能,将您完成的功能(在本地存储库中制作)推送到远程存储库,正如我们在上面讨论的那样。
然后Sam喝得酩酊大醉,把啤酒扔到你身上,和你的伴侣上床,告诉你你们再也不会做朋友了。FootBook死了。
因此,您将所有更改从远程存储库拉取到本地存储库中(这样您就拥有了一个完全最新的副本,包括Sam的所有工作)。您可以使用它创建一个名为AnkleBook的新项目。当历史书写到AnkleBook (及其亿万富翁创始人)的巨大商业成功时,会注意到它最初是FootBook的一个分支,而最初的项目在一个花花公子的手中挣扎,并成为任何值得注意的东西。
克隆
在对FootBook的代码的新副本进行任何更改之前,AnkleBook存储库是FootBook的克隆,用于创建新AnkleBook存储库的机制是克隆FootBook存储库。克隆是在单独的存储库中创建分支的方式。
通过克隆对项目进行分叉
还可以将克隆用作分支模型(重量级分支模型)。创建克隆,进行更改,提交更改,然后将克隆拉取到原始存储库中。它被称为重量级,因为您创建了同一事物的两个大副本,两组文件夹和两个数据库。
这也是你如何获得你想要参与的现有项目(例如,Linux内核)的第一个副本。因此,使用我们的例子,在失去Sam后,您要求 George 参与其中,George克隆了远程AnkleBook存储库并开始在他的新本地存储库中工作。
合并冲突
因此,您和George已经在AnkleBook上工作了一段时间,并且开发了一个名为FootLinker的新功能。在FootLinker开发过程中,您对ligament.cs文件进行了更改。不幸的是,Sam在开发该ShinLinker功能时也是如此。当Sam将您的FootLinker功能拉入他的本地存储库并尝试将其与他的ShinLinker功能合并时,VCS会产生冲突,因为对同一文件有不同的更改。谁赢了?
当它非常容易时,因为您对ligament.cs文件的不同部分进行了更改,VCS通常可以自动为您解决。但是,如果你们俩对同一行代码进行了不同的更改,该怎么办?在这一点上,你通常必须介入并帮助VCS选择做什么,有时事后会收拾残局。
即使自己工作,也会发生同样的事情。如果您的存储库中有两个分支,该怎么办?由于您同时处理两个新功能(因此,您可以对同一代码进行冲突的编辑),因此可以为自己创建合并冲突。这没有什么不同,同样的过程,只是你必须与自己争论,而不是让山姆再次向你扔啤酒。
差异(Diff)
Diff,不出所料,意味着差异,通常是指工具或该工具的输出,通常内置于VCS本身或作为外部插件提供。VCS使用它来准确发现文件的旧版本和当前版本之间的更改,甚至是两个不同分支中的同一文件之间的更改。而且他们非常聪明,即使你在接近开始时进行了更改,例如额外的一两行代码,它也不会认为下面的所有内容也都是更改,它会解决它。因此,它实际上只识别实际更改,编辑的行、删除的行和添加的行都会被发现并被视为如此。
我认为差异工具的输出也是VCS记录更改的方式——即制作更改集,因此更改集远小于项目的总备份。它被用来自动处理冲突,可能还有我还没有发现的各种其他令人兴奋的东西。很棒的小东西。
Labels、Tags、书签等。
我们现在开始进入细节,这些术语在不同的VCS选项之间肯定会有不同的解释。它们提供了进行轻量级分支、记录主要里程碑(次要和主要版本)等的方法。现在可能没那么重要。
我的用例
值得指出的是,我的经验是基于开发基于PHP的网站,而不是将VCS与Visual Studio项目一起使用,所以我不能保证这些原则是正确的,但感觉好像它们应该成立。
特别是,我面临的问题,促使我开始研究版本控制的问题是,我的版本控制手动模型如下:
- 保存整个源代码的两个副本,一个位于名为 prod(生产)的文件夹中,另一个位于名为 dev(开发)的文件夹中
- Prod应该始终表示实时服务器上的内容,并且dev是我工作的地方,直到它准备好上线
- 每次更新准备上线时,我都会将prod文件夹压缩为版本并将其存储在archive中,然后将dev复制到prod中,然后将FTP prod复制到实时服务器
在我需要进行内容更改和功能添加之前,这工作得很好,如果我正在开发功能添加,我如何使用我的手动版本控制模型来添加一些新内容?我即将遇到一个主要障碍,以保持网站最新状态,因为我正在进行一个相当大的功能增强。
最后,值得注意的是,我没有测试(在任何程度上)他们的存储库托管选项,我已经尝试过它们,但不是真正的愤怒——只有我,我真的不需要分布式部分,只需要版本控制部分。因此,Subversion可能没问题,但它似乎不像是未来,所有DVCS都声称适合单用户场景,就像分布式、多开发人员环境一样。
比较VCS选项
我在互联网上做了很多阅读,你很快就会意识到你的主要选择可能是Bazaar、Git和Mercurial。当然,还有其他的。然而,对于版本控制的新手来说,没有太多的指南,大多数文章都是从你已经使用并熟悉VCS的前提开始的,几乎总是Subversion,这使得找到对我有用的指南非常困难。让我选择Bazaar作为我第一选择的特定页面是Smashing Magazine的这个页面。我没有理由相信这个特定的网站而不是其他任何网站,除了写作风格似乎比其他大多数网站更针对我的知识水平和需求。
所以,我从Bazaar开始,因为描述听起来更符合我。文章特别指出:
- 'Mercurial是为大型项目设计的,很可能超出了设计师和独立Web开发人员的范围,所以暂时忽略Mercurial
- '然而,Git并不像CVS或SVN那样容易上手,所以对于初学者来说更难使用,我们暂时忽略Git。
- 而对于Bazaar,关键台词(对我来说)是“如工作流程所示,您可以使用它来适应几乎任何用户和设置场景”,听起来更像是这样。
我现在对如何描述它们有自己和完全不同的看法,请继续阅读......
集市是那时。
由于我习惯于使用两个不同的副本(prod和dev),所以我希望有两个克隆并且没有使用分支(很遗憾)。
Bazaar和Launchpad
Bazaar是由Canonical赞助的开源项目。许多知名的开源项目都使用Bazaar及其相关的远程服务器Launchpad,即Ubuntu、Debian、MySQL、Bugzilla等,因此它显然有一些很好的支持,因此可能非常有能力,但对于新手来说呢?
Bazaar Explorer:看起来足够友好
在Windows中,有完全合理的GUI客户端,即Bazaar Explorer。独立的Windows安装程序还提供了添加TortoiseBzr(Shell扩展——想想资源管理器右键单击)、Git集成和Subversion集成的选项,以及一些对更严肃(专业)用户可能很重要的选项。
我的主要测试是用Bazaar Explorer完成的,虽然我在上面说完全合理,但这是从“感觉像一个友好的地方吗?”的角度来看。一旦我开始尝试使用它,我很快就解开了。只是想知道如何将我想做的事情(在我的脑海中)翻译成Bazaar语言,以便我可以按下正确的按钮,这很困难。我像溜溜球世界冠军手中的溜溜球一样来回看文档。哦,文档有点稀疏。总而言之,非常令人沮丧。
例如,创建一个新项目呢?Project似乎是Bazaar所说的存储库,但我不太确定。
Bazaar Create Project:有人知道我想要什么类型的工作空间模型吗?
说真的,如果这些提示说“如果你让你的flobble变动,那么你可以创建一个floble”,那么我会更好地了解发生了什么。我是否要移动现有文件?或者创建工作结帐?完全不知道。
到目前为止,这是一个公平的评估吗?好吧,可能不是,Bazaar是我第一次尝试版本控制,所以我应该会有点挣扎,但对于一个被描述为“你可以用它来适应几乎任何用户和设置场景”的工具,我不应该这么努力。单独工作的文档,Solo Workflow是这样说的:
- 创建项目。
- 记录更改(在此过程中进行提交)。
- 浏览历史记录(查看提交的注释或两个提交之间的更改,即更改集)。
- 包发布。
真的吗?你让我震惊!我该怎么做?无情的沉默。即使是非规范的指南和文档也没有多大帮助。我挣扎了一段时间,以为是我(现在可能仍然是),但最终放弃了。我需要更多的帮助,无论是通过工具直观还是非常好的文档,Bazaar都无法管理。
关于Bazaar的另一个注意事项是Launchpad集成,这不是我的主要需求,但我确实尝试过。一旦在Launchpad上创建了一个项目,它就会永远存在,即使它里面什么都没有,因为他们不希望人们删除其他人可能依赖的项目。我明白,在开源世界中,这是一件需要担心的关键事情,但我的项目什么都没有!非常令人沮丧。因此,在沙盒模式下使用Launchpad是很困难的,同时你习惯了它并尝试了它的功能,学习了绳索等。
公平地说,我之前说过一些相当大的公司和项目使用Bazaar和Launchpad,所以它肯定比我发现的要多,但这是关于为初学者选择VCS,对我来说,Bazaar不是。也许一旦我对DVCS更加熟悉,然后可以将一般知识应用于使用Bazaar,也许会更容易,有一天我可能会冒险。
Git和GitHub
好的,接下来是 Git。Git 得到了如此多的关注,它必须值得一试,无论如何,Mercurial不适合独立的Web开发人员,所以我只有一个选择。
Git的历史到处都是,最初由Linus Torvalds开发(显然是在与BitKeeper发生了一些争吵之后,不知道,没有读过它)。现在由一支庞大的军队维护,并被一些相当大的名字使用,Microsoft、谷歌、Android、Facebook、Rails,名单还在继续。所以再一次,它一定有一些东西,但对于一个新人来说呢?
在Windows上安装Git提供了shell集成(就像TortoiseBzr为Bazaar所做的那样)和一个GUI,富有想象力地命名为GitGUI。它肯定是整洁的,在任何 给定时间都尽可能少的信息,并且看不到右键单击菜单。这种训练方式可能对空手道小子有用,但我没有宫城先生的帮助。显然是为那些已经确切知道自己在做什么的人设计的。那不是我。
GitGui:呃,现在怎么办?我需要重新粉刷围栏吗?
修订历史(图形日志)的可视化也好不到哪里去。这本身并不坏,只是用户友好在优先级列表中并不高(似乎),考虑功能而不是形式。所以GitGui很快就被装箱了。
也许它实际上并没有那么糟糕
在互联网上搜索后,我找到了SmartGit,这是一个免费用于非商业用途的商业Git客户端。显然,您也可以将它与Mercurial和Subversion一起使用。
SmartGit:好的,这感觉更受欢迎。
SmartGit的工作环境比GitGUI更愉快,因此您一开始不会完全畏惧。营销简介甚至说“SmartGit帮助Git和Mercurial初学者快速入门”。我非常愿意相信他们。然后我遇到了一个很大的绊脚石,如何做我想要的工作模型,即克隆。再多的Git手册或广受赞誉的在线 Pro Git 书籍也无法帮助我摆脱困境。
但是,我并没有那么容易屈服,所以我想我会玩一会儿,看看提交是如何工作的,并尝试与GitHub集成。是的,很快又战斗了。在提交之前,您必须担心暂存和取消暂存 - 这感觉没有很好地集成到SmartGit中——所以我会一直忘记。在Git和SmartGit的辩护中,这在概念上非常明显,但它感觉不像是工作流程的自然组成部分,也就是说,该工具并没有帮助一个白痴做正确的事情,尽管他自己!
修订历史(graphlog)窗口也比GitGui的更吸引人。
SmartGit修订可视化窗口(Graphlog)
这公平吗?好吧,也许如果我早点改用分支,那么我会在Git和SmartGit上取得更大的成功,但有点像Bazaar,学习曲线,即使只是在语言方面,也很陡峭,真的很陡峭。正如我上面提到的,我对PHP、VB和.NET的学习曲线已经足够多了,以至于我想再挑战一个,所以它被放弃了。
Mercurial和BitBucket
Mercurial是另一个开源项目,它的创建原因与Git相同(我还没有阅读其详细信息),显然它在Git的几天内就开始了(一种或另一种方式),虽然Linux内核开发转移到了Git而不是Mercurial,但Mercurial仍然可以声称一些大牌, 虽然这次作为赞助商(很难说谁在将Mercurial用于大牌项目),但赞助商包括谷歌、Microsoft和Mozilla等等。
TortoiseHg:有很多事情要做,但要弄清楚该怎么做并不难。
因此,考虑到这应该比其他两个更难,我有些惶恐,我安装了Mercurial。作为标准的Windows安装,它带有TortoiseHg。现在这个版本的Tortoise与为Bazaar编写的版本不同,因为它也是一个GUI,而不仅仅是一个shell扩展(TortoiseGit也是一个shell扩展,而不是GUI)。
好的,所以TortoiseHg是一个非常愉快的工作场所,有点像SmartGit。我不要过分强调这一点,但对我来说,像GitGUI与SmartGit或TortoiseHg这样的东西就像今天基于DOS的旧文字处理器与MS Word(或LibreOffice)之间的区别。它真的那么大,对于初学者来说,它可以使世界变得不同,只是能够做一些事情并专注于你真正喜欢的事情——编码,这很可能是初学者的爱好,而不是一份工作,我想继续有趣的一点。
但是实际做某事呢?嗯,第一步是能够克隆并且很容易做到。宾果游戏,我在原版中做了一些内容更新,一路上进行了提交,准备就绪后,将FTP连接到实时服务器和宾果游戏,进行排序。同时,我正忙于在克隆中开发该功能。功能完成后,我将更改从克隆存储库提取到原始存储库(我一直在进行内容更新的地方),瞧,功能变更集(包括其完整历史记录)只是我原始存储库的一部分,作为一个大的旧分支。现在只需将功能分支合并到代码中,并再次对内容更新和宾果游戏进行排序。
在我上面显示的图像中,您可以看到修订历史记录(graphlog)始终存在,我觉得这很方便。要在创建新提交(如图所示)和查看提交内容(如果现在执行)之间切换,只需单击顶部的工具栏按钮即可。然后屏幕的下半部分会相应地变化。然后布局在两个视图中保持不变,很漂亮,有人想到了这一点。布局(在下半部分)的工作方式是这样的,文件在左边,提交注释在右边(上),在右边(下)对所选文件中的详细更改。您可以看到:
- 修改后的蓝色文件,标有M
- 删除了红色文件,如果我尚未接受删除,则标有!,如果我已接受,则标记为 R
- 添加了我接受绿色添加的文件,标有A
- 添加了我尚未接受粉红色添加的文件,并带有?
- 暂存文件在复选框中打勾
- 当我提交时,可以对此版本发表评论的空间,显示在右上方
- 对所选文件(scoresmenu.php)的详细更改显示在右下角
比我迄今为止合作过的任何东西都要好得多。
看到从克隆拉取到原始存储库只是创建了一个分支,这让我更多地考虑了分支,我现在只这样做。因此,我可能有一个默认分支*、一个内容更新分支(当我需要一个时,它们往往是短暂的)和一个功能分支(或两个或更多)。我可以独立处理它们,轻松地在它们之间切换,轻松地将完成的内容更新或新功能合并到默认分支中,将其FTP到实时服务器,我就完成了。我还可以同时运行多个功能分支。
* 您在Mercurial中始终有一个默认分支,除非您使用书签或匿名分支(我不是)进行分支,否则对我来说,默认分支的尖端始终与实时服务器相同,这很方便,即我使用Mercurial的默认分支作为树干。
这公平吗?很难明确地说它比Git更好,因为我没有尝试过Git的分支,但我仍然有一种感觉,就学习曲线而言,Mercurial有一些东西更容易,也许如果我今天回到Git,我会发现它要容易得多。它会比Mercurial更容易或更好吗?不确定。你可以说Git可能更常见,任何你参与开源多贡献者开发的愿望都更有可能用Git而不是Mercurial来完成,但对我来说,我猜这是一个相当平均的选择,双方都有利有弊。也许使用Mercurial开始,我想你会发现迁移到Git很简单,反向移动可能也很容易,但也许Mercurial更适合“学习绳索”。
同样值得注意的是,我正在辩论的大部分内容可能归结为GUI而不是底层VCS,但我确实认为这是初学者的经验和学习曲线中非常重要的一部分,所以我确实相信(在本次讨论的背景下)将其用作判断的一个组成部分是相关的。在这方面,TortoiseHg对我来说是一个真正的赢家。
最后关于Mercurial:我提到了Git的暂存和取消暂存,我发现它感觉不像是工作流程的自然部分(无论是基于GUI还是基于VCS),Mercurial本质上具有相同的东西,与先前提交的更改被突出显示(在TortoiseHg中)并且您接受或拒绝它们,然后每个更改的文件都有一个复选框,几乎可以复制Git的暂存和取消暂存, 但它只是使用起来更明显、更自然。想要接受所有更改但只提交其中的一些更改,检查要提交的更改,进行提交然后继续工作,接受但未提交的更改只会成为您下一次提交的一部分(如果您愿意,或进一步延迟)。就我而言,我主要提交所有更改,所以我只需勾选所有更改(只需单击即可完成)。
哎呀,这还不是最后,你还得到了TortoiseHg Overlay Icon Server,它在标准资源管理器图标上提供了一个可视化图标叠加,这些图标代表存储库中文件的状态,未更改、添加、更改等,非常好(我认为TortoiseGit也有类似的东西)。我还将存储库上传到BitBucket(它同时托管Git和Mercurial存储库),很简单,据我所知,并不比GitHub好或差。
我写的关于Mercurial的文章比其他两个多得多,我用得更多。这是有原因的。
总结比较
很明显,我更喜欢Mercurial,我感到更有信心并且发现它很容易使用,它并没有分散我开发网站的注意力,当我犯错误时(无论是版本控制错误还是编码错误),它很容易撤消,如果你意识到足够快,你甚至可以回滚提交(你也可以在其他方面做到这一点, 我没有走那么远)。
在我的判断中,GUI可能会产生过多的影响,但对我来说,这很重要,我认为这对于许多没有命令行背景或没有版本控制经验的初学者来说很重要。这可能是我更喜欢Mercurial的最大原因,因为TortoiseHg更适合我和我摇摇欲坠的脑袋。
我的思维方式也可能有很大的影响,也许Mercurial/TortoiseHg比其他人更适合我的头脑,谁知道呢?
我强烈建议初学者尝试一下Mercurial,特别是将它与TortoiseHg一起使用。也尝试一下其他人,你可能会发现它们更适合你。
对于Bazaar,我无法说出Bazaar Explorer的难点,现在回想起来,它似乎似乎太简单了,几乎就像一个向导工具,而不是一些不显眼的东西,只是和你一起工作。男孩Launchpad惹恼了我。
对于Git,我确实认为它比我最初发现的要容易,特别是因为我现在对版本控制有了更好的了解(尤其是分布式、以分支为中心的DVCS的好处,即使是单独使用)、使用的术语和概念等,但我也认为学习曲线比Mercurial更陡峭,特别是如果你使用GitGUI(不寒而栗)。GitGUI与我刚才描述的Bazaar Explorer相反,但不是以一种好的方式。
从那以后,我又回到了Git(创建上面的一些屏幕截图),我确实发现分支比以前容易得多,我相信我最终会记得暂存和取消暂存。然而,我无法克服学习曲线更陡峭的想法,它不像我发现的Mercurial(使用TortoiseHg)那样直观。
试一试,即使你的项目没有对你大喊大叫,说它会从版本控制中受益(也许你认为它太小太简单了),你可能会发现它以你可能意想不到的方式变得有用。即使你只在本地工作,从来没有打算使用BitBucket或GitHub或参与开源项目,这也不是必需的,能够追溯你的更改,分支不同的功能并分开内容和功能(无论如何对于网站)真的很方便,比我开始时意识到的要多。
其他说明
可以说,我现在跑题了,因为这应该是关于选择你的第一个VCS,但我认为这些笔记已经足够接近目的——帮助一个从未使用过版本控制的人开始——我不介意,希望你能原谅我。
分支
这是一个最初令人困惑的领域,也是我开始想要克隆的部分原因——我只是不想尝试学习分支以及其他所有东西。这个概念听起来很简单,但是在每个VCS中有许多分支模型和不同的分支方式——不仅仅是两个VC之间的不同,实际上是VCS中的不同方式——我到底想使用哪一个?这个 Mercurial分支指南非常有帮助,但是当你从未做过任何类型的VCS时,它会把你推离分支,因为你突然有太多的选择,无论如何你都不完全理解,至少没有任何深度。
我能给出的唯一指导是简单开始,在Mercurial中,您只需创建一个命名分支(易于操作),忽略其他分支方式————在Mercurial中,这就是Steve Losh所描述的“使用命名分支进行分支”。对我来说,它还有一个优点,即树干的尖端(默认分支)始终代表实时服务器,我从不直接在它上面工作,我总是在一个命名的分支中工作,并在我准备推出该功能或内容更新时将其合并到主干中——尽管这已经成为我自己的个人分支模型的细节, 我之所以提到它,只是因为我发现以这种方式工作时,我很容易遵循我正在做的事情!
话虽如此,我真的很想了解其他分支方式,包括Steve没有提到的Mercurial的补丁队列功能,但命名分支真的很容易让你上手和使用。试一试。
Bug修复和分支
关于分支的更多内容,以及我仍在尝试弄清楚该怎么做的事情。
好的,假设你有你的主干和一个命名的功能分支,你有几个更改集(但还没有完成)。然后,您在实时服务器上发现了一个错误。从主干的顶端创建一个用于bug修复的新命名分支,整理bug,将该分支合并到主干中,然后通过FTP将其输出到实时服务器。工作完成。只有我如何将该错误修复到我的功能分支中?我可能希望通过现在将错误修复引入命名功能分支来避免以后发生合并冲突,而不是在功能完成时解决合并冲突(当我愿意时,我想将该冲突与主干合并)。
如何将该错误修复到功能分支中?
我还不知道该怎么做,我认为如果我以“适当”的DVCS方式与多个开发人员一起工作,那么我可以将相关的更改集从错误修复分支拉取到我的本地存储库中并将其与我的代码合并,边走边对合并冲突进行排序。然后,当我将功能分支推送到远程存储库时,错误修复已经在那里,我不会遇到合并冲突。只是我不知道在本地工作时如何复制它。我有一种感觉,Mercurial的补丁队列可能会帮助我,但我不知道,也无法得到这个问题的答案。嘿嘿!
也许这是Mercurial和Git之间的另一个区别,我怀疑Git的支持和知识略多一些,因为社区可能大一个数量级,因此在论坛等中有更多的建议(我确实说过更多/更好,而不仅仅是更多,但我没有根据假设更多=更好!
分支和合并——冲突
在分支时,我担心的一件事是合并冲突,即当你在两个不同的分支中对相同的代码进行冲突的编辑时,这些代码后来需要合并。幸运的是Mercurial有一个非常易于使用的回滚功能,嘿,presto,我在尝试合并之前回到了状态,然后我可以弄清楚如何管理它,这是我在第一种情况下手动完成的,然后再次尝试合并, 即,我手动编辑了每个版本中的相关文件,使它们相同,因此没有合并冲突。
后来我用内置的 diff 工具处理了合并冲突,它不像TortoiseHg(或SmartGit)那样对用户友好,但一旦你开始习惯它,它就不会那么糟糕。我最初的沉默部分也来自于我在凌晨2点第一次尝试使用合并工具时有点醉了(实际上喝醉了很多)——不聪明!您还可以插入一堆替代的差异工具,这样您就可以尝试几种,直到找到一个“适合您的头脑”。可以肯定的是,大多数VCS都是这种情况,而不仅仅是Mercurial/TortoiseHg。
在本地工作
正如我之前所指出的,我的大部分工作都是在本地完成的,而不是通过托管在GitHub、BitBucket等上的远程存储库完成的,虽然DVCS的一件大事是分布式位,而不仅仅是版本控制位,但我发现它对本地版本控制完全有用,你不会因为不从远程存储库工作而丢失或损害任何东西(到目前为止我发现的)。唯一可能的例外是我上面提出的关于在分支之间移动特定更改的观点,但我怀疑在本地工作时也有办法做到这一点,我只是还没有弄清楚。
如果您家里有NAS设备,另一种选择是在其上安装Git服务器或Mercurial服务器。然后,您可以将其托管在自己的服务器上,将服务器存储库克隆到本地驱动器并将本地更改推送到服务器,而不是将项目放在本地驱动器上。如果您随后通过防火墙公开该服务器,则可以从世界任何地方访问您的“远程”项目存储库。
IDE集成
由于我们中的许多人都使用IDE,这是一个不错的选择,并不是每个人都想要——我目前不使用它——但很高兴知道您有选择。Git似乎与Visual Studio、NetBeans和Eclipse集成。Mercurial看起来类似,VS、Eclipse和NetBeans。
我不使用Eclipse和NetBeans,但从VS中快速搜索扩展库会发现Git和Mercurial的选项。虽然这两个VCS的Google结果的第一页与我上面列出的相同。不过,我还没有测试过它们中的任何一个;我可以很容易地用TortoiseHg进行管理。
Bazaar在其Wiki上有一个专门列出 IDE集成选项的页面,它似乎有很多(包括 VS),但VS扩展搜索总共没有——同样,我还没有测试过它们中的任何一个。
最初,我以为我真的会从IDE集成中受益,但仔细想想(至少对于业余爱好者规模的项目来说),这是没有必要的,而且由于VCS GUI工具(如TortoiseHg)专用于这项任务,它比试图将其挂接到IDE中要好得多,因为信息呈现给您的方式不可避免地会带来后果(即使只是在屏幕空间的基础上)。
让我知道,(或写你自己的文章),如果你测试其中的一些。
跨DVCS互操作性
我还没有测试过互操作性位,但确实记得在我的阅读阶段有一些评论,其中讨论了所有这些DVCS工具相互互操作的能力以及Subversion——每个工具在管理这一点方面存在很大差异,从糟糕到出色(这句话就像黑魔法一样工作在我的记忆中突出)。但是,很高兴知道,如果您选择一种工具,然后参与在不同VCS上运行的项目,您不会完全迷失方向,您也许可以将首选的GUI与使用不同VCS管理的项目一起使用。将SmartGit与Git一起使用?想参与使用Mercurial的项目吗?SmartGit应该能够应对,因此您可以最大限度地减少头痛,在参与之前无需“学习”Mercurial。
John Szakmeister有一篇有趣的博客文章。他谈到了每个工具如何设法应对访问和很好地使用来自其他工具之一的存储库以及颠覆,除此之外,我无法添加任何内容,毫无疑问,您会发现其他博客和文章关于同一主题。然而,对于一个初学者来说,只有当你决定参与一个多开发人员项目时,它才真正重要,这个项目托管在与你自己选择的VCS不同的VCS上,因此我无法想象它相对于我提到的其他一些元素有那么重要,至少在你不需要我的建议之前。
如果你读过那篇文章,那么我会注意到这一点:他对Mercurial 分支的评论与我的评论形成了鲜明的对比,我不确定我是否理解他的推理,他的推理是沿着位于不同文件夹中的分支进行的。我完全不明白(尽管他可能比我更有可信度和知识),我有很多命名的分支,只有一组文件夹和存储库数据库。当我想切换分支时,我只需Update切换到该分支,神奇的是,我的一组文件夹在其中获取了所有正确的文件(根据需要删除、添加和更改)。也许这与专业开发或多开发人员项目有关,我只是看不到它,但即便如此,我认为分布式 VCS的意义在于每个开发人员都有一个本地副本,进行更改和提交,然后与服务器同步,因此每个开发人员都可以在他们需要的任何分支上工作。也许有一天我会发现的。
相关链接
这些只是我找到的体面建议、评论和指导的几个地方。
- 关于选择VCS的StackExchange讨论,请阅读dukeofgaming提供的热门答案,以及一些可能对您有所帮助的有趣图片
- 乔尔·斯波尔斯基(Joel Spolsky)在Mercurial上,首先与Subversion进行了比较(就像许多人一样),但您可以跳过它
- Steve Bennet不喜欢Git。可能有助于解释为什么我发现Git很难掌握。一个有趣的评论(2012年8 月3日更新中的#5)说:请改用Mercurial! 当然,如果你是一个幸运的人,可以选择你的项目使用的VCS。Mercurial似乎得到了很多爱,但没有多大用处,很奇怪。
兴趣点
仅仅阅读这类内容并不能让你得到答案,你必须亲自动手处理每个选项,找出适合你的选项。玩得开心。
https://www.codeproject.com/Articles/431125/Choosing-a-Version-Control-System-A-Beginners-Tour