为什么要用 Git

一、git 解决的问题

1. 版本控制

没有 git 的时候......假如你写了一篇文章,要删除某一个段落,为了防止以后需要找回这个段落,你需要为这个文件备份。

如果你第一次删除了段落1,第二次修改了段落2,第三次添加了段落4,则需要为每一个版本都建立一个备份。(还有一个办法是注释掉修改的代码,在下面写添加的代码,但是时间久了就弄不清楚了)你的文件可能看上去是这个样子:

image

版本多了,你想恢复修改前的段落2,却不记得是那个备份,所以你需要一个一个文件去翻阅查找,非常麻烦。

这时你可能会写一个说明文档,文档中记录了:副本(1)——删除段落1;副本(2)——修改段落2;副本(3)添加段落3...... 有了这些摘要你能很快定位到需要的文件。

可是修改了第112行,或者是修改了114、118和119行呢?你不可能有耐心记录下每个版本修改了哪几行,所以这些修改很难定位,找起来特别费神。

版本管理可以解决以上述所有麻烦(这些麻烦是我在未接触版本管理时写代码真实遇到的)。每次有新的修改,添加版本说明并提交。从 git log 信息中你可以看到所有版本和版本摘要,看起来就像下面这样(这就不用手动备份文件和写摘要文档了):

版本 用户 说明 日期
1 张三 删除段落1 2017.1.1
2 李四 添加段落4 2017.1.3

对于任意两个版本,用 git diff 命令,可以比较两个文件的不同,这样就解决了修改定位的问题。完全自动化,Cool!

2. 代码同步

我曾经和同学 H 合作写一个小插件,刚开始没有使用 git 或者 svn,一度觉得自己没办法干活了。比如我编辑MainServlet.java,他编辑 index.jsp,现在需要运行看效果,我们就要通过 qq 把自己修改的文件传给对方,然后手动覆盖。有时我和他同时修改 index.jsp,就得让他把他的文件发给我,我合并两人的修改后,再把合并后的文件发给他。后来改动多了,我们也不记得我们修改了哪些东西,完全混乱,于是就在同一台机器上你敲一会儿,我嗑瓜子,再我敲一会儿,你嗑瓜子,严重影响了效率。有时老板要检查我们的进度,或者要帮助我们解决bug,我们就得将最新的版本打成压缩包 qq 传给总监。

后来我们用了 SVN,这些麻烦就全没有了。要同步两人的进度,只需要一人commit,另一人checkout,根本不需要自己记改了哪些东西。解决冲突同样是相对麻烦的事情,但是先 checkout,修改冲突的地方再提交,步骤清晰且有详细记录,比之前好了不知道多少。老板需要最新的代码时,也无需找我们要,直接从仓库里下载下来就好啦!

3. 分支管理

分支在实际中有什么用呢?假设你准备开发一个新功能,但是需要两周才能完成,第一周你写了50%的代码,如果立刻提交,由于代码还没写完,不完整的代码库会导致别人不能干活了。如果等代码全部写完再一次提交,又存在丢失每天进度的巨大风险。现在有了分支,就不用怕了。

二、Git 与 SVN比较

1. 分布式与集中式

git 是分布式版本管理系统,SVN 是集中式版本管理系统。

集中式:

在没有联网的情况下不能 commit 操作。只有中央服务器拥有完整仓库。

image
分布式:

每台机器上安装了同一套 git 程序,所以都能持有完整的仓库。可以方便的克隆仓库,仓库与仓库之间可以互相同步。

svn 并不能克隆仓库,只能从仓库中下载文件,即使你用 TortoiseSVN 创建了一个本地仓库,你和中央服务器的仓库也无法进行关联。

image
git 分布式为什么比 svn 集中式好?
  1. svn 不联网就不能 commit。假设小明公司的中央服务器部署在内网,回家了便无法访问,但小明周末仍然勤奋地在家写代码。周六晚他想将这一天写的东西 commit,但是并不能够。周天他将代码改出bug来了,想回退到周六晚的版本,事实残忍地拒绝了他,并让他手撕bug。

  2. 集中式中,中央服务器挂了,仓库就挂了。分布式中,挂了一台机器,还能从另一台机器恢复仓库。不过据最新消息证实,有些 svn 的客户端现在也搞分布式技术,一个仓库同时存在几台服务器上,一个服务器提交了修改,几个服务器自动同步,但是这仍改不了我们工作的笔记本上没有仓库的事实。如果我们笔记本上仓库也能和远程同步,等等,那不就和 git 的模式一模一样了吗?瞎折腾啥呢少年,不如一开始就用 git。

  3. git 中我们可以 commit 到本地仓库而不 push 到远程仓库。假设我的 getDataService.java 只写了一半,仍然会报错,这时候用 svn 将修改提交,就会影响到队友(队友更新代码 了以后说卧槽怎么 run 不起来了)。更可怕的是我修改的是已有的文件。但是不提交,我又面临着和小明一样丢失进度的风险。在 git 中只 commit 不 push 就能解决这个问题。在我的第一个实习公司,那时想自己改一改代码玩,就自己在本地创建了一个分支,随便瞎折腾,只要不提交,别人完全不知道我干了啥,不会影响到任何人。

2. 分支管理

git 的分支功能比 SVN 好用得多。

其他版本控制系统如SVN等都有分支管理,但是用过之后你会发现,这些版本控制系统创建和切换分支比蜗牛还慢,简直让人无法忍受,结果分支功能成了摆设,大家都不去用。

SVN 使用分支,一般来说是我们直接手动管理文件夹,见 trunk+-branches+-tags 目录结构的使用。举个例子,如果需要基于分支1新建一个分支2,我们就手动将分支1的文件夹拷贝一份命名为分支2。如果要切换分支,我们就切换文件夹。类似这些操作,实际上是将文件夹“视作”分支,用了 move、cd 等操作,至于合并分支的 merge 命令,大概没什么人敢用吧。

但Git的分支是与众不同的,无论创建、切换和删除分支,Git在1秒钟之内就能完成!无论你的版本库是1个文件还是1万个文件。

3. 权限控制

SVN 可以严格控制每个目录的访问权限(还有一套很变态的规则),git 只能控制每个仓库分支的权限。SVN 可以 checkout 任意子目录,而 git 只能 clone 某个分支。

实际上,SVN的目录权限控制和 checkout 子目录主要是为了方便了基于trunk+-branches+-tags 结构的开发。现在 git 既然已经有了好用的分支功能,目录权限控制就没有那么必要了。

补充:

  • 在任意目录checkout,意味着在任何位置都可能出现.svn的隐藏文件夹,这样对整个工程的代码产生了污染。
  • 也有非要像SVN那样进行目录权限管理的时候,见知乎的这个问题:https://www.zhihu.com/question/20216542 在上面 SVN 总算占据了一点优势。

4. .gitignore 文件

git 可以忽略某些文件的提交,而SVN没有这个功能。

5. 版本号

svn 的版本号是1、2、3......的自然数,git 的版本号是一堆哈希码,看起来非常反人类。 其实 git 这样设计和它的分布式结构有关,作用是防止版本号冲突。

反例如下:如果 git 用自然数作为版本号,小明在本地提交了版本1、2,小刚也在本地提交了版本1、2,两个仓库同事 push 到公司的 gitlab上时,版本号就发生了冲突。而 svn 仓库只有一个,不用与别的仓库同步,版本也一定有个提交的先后顺序,所以不会发生冲突。

工作区与暂存区

为什么要先 add 再 commit 呢?我觉得这是为了命令行的使用方便。有时一天的活儿干完,修复了两个bug,所以我要分两次提交。那么先把第一次要提交的文件 add 到暂存区,再将暂存区的所有文件进行commit。写命令行的时候,如果没有 add 只有commit,就要一口气写很多个文件,很不方便。但是图形界面不存在这样的不便,所以大多数 git 的图形化操作软件都把 add 和 commit 合二为一操作。

当然,暂存区还有一些更灵活的使用,只要理解下图,便可以依照你自己的喜好使用。

image
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1. 安装 Github 查看是否安装git: $ git config --global user.name "...
    Albert_Sun阅读 14,654评论 9 163
  • 1.git的安装 1.1 在Windows上安装Git msysgit是Windows版的Git,从https:/...
    落魂灬阅读 14,340评论 4 54
  • 没有经历过亲人突然而逝的人,是无法体会那种骤然而至的打击有多大,2004年十月一日的凌晨,在父亲去世两年多后,我的...
    远方的家园阅读 2,895评论 0 2
  • 查理是一个患有先天性弱智的35岁男子,从童年开始当父母发现他智力水平低下以后渐渐的失去了照顾他的耐心,后来辗转被叔...
    lunabird阅读 2,454评论 0 0
  • 写给十七岁的我,我很想像你,能坦率把梦提起。 亲爱的石头: 你好,我是十八岁的你,在六月中旬的凌晨,突然想起你,现...
    Petrichor_7阅读 3,177评论 0 0

友情链接更多精彩内容