Git

CVS和Subversion有很多不同的地方。但如果将这两者和git比较,那么git看起来就像孙权的碧眼,有一些怪异。

git的作者是Linus Torvald。对,就是写Linux Kernel的那个Linus Torvald。Linus在贡献了最初的Linux Kernel源代码之后,一直领导着Linux Kernel的开发。Linus Torvald本人相当厌恶CVS(以及Subversion)。然而,操作系统内核是复杂而庞大的代码“怪兽” (2012年的Linux Kernel有1500万行代码,Windows的代码不公开,估计远远超过这一数目)。Linux内核小组最初使用.tar文件来管理内核代码,但这远远无法匹配Linux内核代码的增长速度。Linus转而使用BitKeeper作为开发的VCS工具。BitKeeper是一款分布式的VCS工具,它可以快速的进行分支和合并。然而由于使用证书方面的争议(BitKeeper是闭源软件,但给Linux内核开发人员发放免费的使用证书),Linus最终决定写一款开源的分布式VCS软件:git。

git在英文中比喻一个愚蠢或者不愉快的人(a stupid or unpleasant person)。Linus说这个比喻是在说自己:

I'm an egotistical bastard, and I name all my projects after myself. First "Linux", now "git".

(这里,Linus似乎并不是在贬低自己,见Linus和Eric S. Raymond的争论: The curse of the gifted)

对于一个开发项目,git会保存blob, tree, commit和tag四种对象。

  • 文件被保存为blob对象。
  • 文件夹被保存为tree对象。tree对象保存有指向文件或者其他tree对象指针。

上面两个对象类似于一个UNIX的文件系统,构成了一个文件系统树。

  • 一个commit对象代表了某次提交,它保存有修改人,修改时间和附加信息,并指向一个文件树。这一点与Subversion类似,即每次提交为一个文件系统树。
  • 一个tag对象包含有tag的名字,并指向一个commit对象。

虚线下面的对象构成了一个文件系统树。在git中,一次commit实际上就是一次对文件系统树的快照(snapshot)。

每个对象的内容的checksum校验(checksum校验可参阅IP头部的checksum)都经过SHA1算法的HASH转换。每个对象都对应一个40个字符的HASH值。每个对象对应一个HASH值。两个内容不同的对象不会有相同的HASH值(SHA1有可能发生碰撞,但概率非常非常非常低)。这样,git可以随时识别各个对象。通过HASH值,我们可以知道这个对象是否发生改变。

比如一个文件LOG,它包含一下内容:

aaa

这个文件的HASH码为72943a16fb2c8f38f9dde202b7a70ccc19c52f34

如果我们修改这个文件,成为

aaa

bbb

这个文件的HASH码变成dbee0265d31298531773537e6e37e4fd1ee71d62

所以,git只需看对象的HASH码,就可以知道该对象是否发生改变。

在整个开发过程中,可能会有许多次提交(commit)。每次commit的时候,git并不总是复制所有的对象。git会检验所有对象的HASH值。如果该对象的HASH值已经存在,说明该对象已经保存过,并且没有发生改变,所以git只需要调整新建tree或者commit中的指针,让它们指向已经保存过的对象就可以了。git在commit的时候,只会新建HASH值发生改变的对象。如下图所示,我们创建新的commit的时候,只需要新建一个commit对象,一个tree对象和一个blob对象就足够了,而不需要新建整个文件系统树。

可以看到,与CVS,Subversion保存改变(file delta)的方式形成对照,git保存的不是改变,而是此时的文件本身。由于不需要遵循改变路径来计算历史版本,所以git可以快速的查阅历史版本。git可以直接提取两个commit所保存的文件系统树,并迅速的算出两个commit之间的改变。

同样由于上面的数据结构,git可以很方便的创建分支(branch)。实际上,git的一个分支是一个指向某个commit的指针。合并时,git检查两个分支所指的两个commit,并找到它们共同的祖先commit。git会分别计算每个commit与祖先发生的改变,然后将两个改变合并(同样,针对同一行的两个改变可能发生冲突,需要手工解决冲突)。整个过程中,不需要复制和遵循路径计算总的改变,所以效率提高很多。

比如下面的图1中有两个分支,一个master和一个develop。我们先沿着develop分支工作,并进行了两次提交(比如修正bug1),而master分支保持不变。随后沿着master分支,进行了两次提交(比如增加输入功能),develop保持不变。在最终进行图4中的合并时,我们只需要将C4-C2和C6-C2的两个改变合并,并作用在C2上,就可以得到合并后的C7。合并之后,两个分支都指向C7。我们此时可以删除不需要的分支develop。

由于git创建、合并和删除分支的成本极为低廉,所以git鼓励根据需要创建多个分支。实际上,如果分支位于不同的站点(site),属于不同的开发者,那么就构成了分布式的多分支开发模式。每个开发者都在本地复制有自己的库,并可以基于本地库创建多个本地分支工作。开发者可以在需要的时候,选取某个本地分支与远程分支合并。git可以方便的建立一个分布式的小型开发团队。比如我和朋友两人各有一个库,各自开发,并相互拉对方的库到本地库合并(如果上面master,develop代表了两个属于不同用户的分支,就代表了这一情况)。当然,git也允许集中式的公共仓库存在,或者多层的公共仓库,每个仓库享有不同的优先级。git的优势不在于引进了某种开发模式,而是给了你设计开发模式的自由。

正如东吴门阀合作的政治模式,git非集中式的开发模式让git成为了后起之秀。生子当如孙仲谋,生子当如Git Torvald。

(需要注意的是,GitHub尽管以git为核心,但并不是Linus创建的。事实上,Linus不接收来自GitHub的Pull Request。Linus本人将此归罪于GitHub糟糕的Web UI。但有些搞笑的是,正是GitHub的Web页面让许多新手熟悉并开始使用git。好吧,Linus大婶是在鞭策GitHub。)

内容概要:该研究通过在黑龙江省某示范村进行24小时实地测试,比较了燃煤炉具与自动/手动进料生物质炉具的污染物排放特征。结果显示,生物质炉具相比燃煤炉具显著降低了PM2.5、CO和SO2的排放(自动进料分别降低41.2%、54.3%、40.0%;手动进料降低35.3%、22.1%、20.0%),但NOx排放未降低甚至有所增加。研究还发现,经济性和便利性是影响生物质炉具推广的重要因素。该研究不仅提供了实际排放数据支持,还通过Python代码详细复现了排放特征比较、减排效果计算和结果可视化,进一步探讨了燃料性质、动态排放特征、碳平衡计算以及政策建议。 适合人群:从事环境科学研究的学者、政府环保部门工作人员、能源政策制定者、关注农村能源转型的社会人士。 使用场景及目标:①评估生物质炉具在农村地区的推广潜力;②为政策制定者提供科学依据,优化补贴政策;③帮助研究人员深入了解生物质炉具的排放特征和技术改进方向;④为企业研发更高效的生物质炉具提供参考。 其他说明:该研究通过大量数据分析和模拟,揭示了生物质炉具在实际应用中的优点和挑战,特别是NOx排放增加的问题。研究还提出了多项具体的技术改进方向和政策建议,如优化进料方式、提高热效率、建设本地颗粒厂等,为生物质炉具的广泛推广提供了可行路径。此外,研究还开发了一个智能政策建议生成系统,可以根据不同地区的特征定制化生成政策建议,为农村能源转型提供了有力支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值