特别说明:要在个人随笔后写评论的小伙伴们请注意了,个人博客开启了 MathJax 数学公式支持,MathJax 使用
$
标记数学公式的开始和结束。若是某条评论中出现了两个$
,MathJax 会将两个$
之间的内容按照数学公式进行排版,从而致使评论区格式混乱。若是你们的评论中用到了$
,可是又不是为了使用数学公式,就请使用\$
转义一下,谢谢。html
想从头阅读该系列吗?下面是传送门:git
我是经过阅读《Pro Git》这本书学习 Git 的,我读的时候仍是初版的英文版,如今已经出第二版了,并且英文版和中文版都有。英文第二版的地址是 https://git-scm.com/book/en/v2,中文第二版的地址是https://git-scm.com/book/zh/v2。想看初版的话把地址中的v2
改为v1
就能够了。若是哪天忽然连接打不开了,也别着急,记住《Pro Git》这个招牌,使用搜索引擎很快就能找到它。github
Git 是一个版本控制系统,它能够保存工做文件的全部修订版本。有了它你就能够将某个文件回溯到以前的状态,甚至将整个项目都回退到过去某个时间点的状态,你能够比较文件的变化细节,查出最后是谁修改了哪一个地方,从而找出致使怪异问题出现的缘由,又是谁在什么时候报告了某个功能缺陷等等。使用版本控制系统一般还意味着,就算你乱来一气把整个项目中的文件改的改删的删,你也照样能够轻松恢复到原先的样子。但额外增长的工做量却微乎其微。数据库
Git 的特色:编程
下面是我简化了的 Git 使用小结,图片都来源于《Pro Git》初版。安全
每个项目都应该有一个工做目录(Working directory),咱们能够本身建一个目录,而后把这个目录里面的代码用 Git 管理起来(使用git init
命令和git add
命令),也能够经过git clone
命令从别的地方克隆一个项目过来自动生成一个工做目录。在工做目录中的文件就是当前编辑和修改的文件,若是是新创建的目录或新克隆来的目录,工做目录中的文件就是该项目最新的状态。Git 是在本地保存有全部的历史记录和分支记录的,这些内容都在工做目录的.git
目录中,称之为本地仓库(local repository)。当切换分支或查看之前的历史版本时,工做目录中的文件自动改变(这才是重点,工做无需切换目录,目录中的文件会自动切换)。工做目录中的文件有三种状态:已修改(modified)、已暂存(staged)、已提交(committed)。修改后的文件能够先加入暂存区域,一次工做结束后一块儿提交。服务器
Git是分布式的,没有中心服务器的概念,但实际工做中仍然能够把代码仓库放到一台你们均可以访问的服务器上,作实际的中心服务器使用(仅在小团队时使用此工做流程,缘由后面详述)。在本地机器上工做完后,使用git push
命令把仓库推送到服务器上,换一个地方换一台机器后,只须要git clone
一下,又能够得到全部的代码(包含全部的历史记录及分支)继续工做。服务器故障也没问题,由于每个工做的机器上都保存有完整的代码仓库,因此从不用担忧代码丢失。没有网络也没有关系,在本地机器上照样能够提交(git commit
),由于整个仓库就在本身的机器上,当有网络时,git push
一下就能够了。网络
Git有远程仓库(remote repository)的概念,并且能够管理不少个远程仓库,远程仓库能够是服务器,也能够是别人的我的计算机(但通常没有人这么用),每个远程仓库都有一个简短的名字和一个地址,最开始用git clone
克隆代码的那个远程仓库别名每每默认为 origin,本身添加的远程仓库能够随意指定别名,固然全部的远程仓库均可以随意修改别名。能够从远程仓库获取代码(git fetch
命令或git pull
命令),也能够把本身的代码推送到远程仓库(git push
命令,须要写权限)。eclipse
既然 Git 便可以随便从远程仓库获取代码,又能够把本身的代码推送到远程仓库,那么当多人协做时,岂不会乱套吗?解决这个问题的,就是 Git 的必杀之技——建立分支及分支合并。编程语言
首先,随着一次次的提交,在本地代码库中造成一个主分支,以下图:
有时为了开发新特性,随时能够开一个新分支,以下图:
新分支和主分支之间能够随意切换,随着分支的发展,形式以下图:
主分支也能够向前发展,以下:
最终,当新分支代码很稳定之后,能够将其合并到主分支,以下图:
而可以防止多人协做时出现混乱的关键就在于,当从远程仓库 clone 代码库到本地或 fetch 代码库到本地时,远程分支的标记并不等于本地分支的标记。从远程 clone 一个代码库到本地后,其 master 分支有两个标记,一个标记为 origin/master 表示远程库中的 master 分支,一个标记为 master,表示本地的 master 分支。以下图:
能够想象,因为别人的工做,远程仓库中的 master 分支确定会向前继续移动,可是在下次联网以前,该 origin/master 标记不会移动。而本地的 master 标记继续向前移动。
直到下次联网,使用git fetch
命令将远程仓库的内容取回本地,origin/master 标记才会改变位置,这时,看起来就像是两个分支,以下图:
最后,将 origin/master 分支合并到 master 分支中(使用git merge
命令),本地代码库又一次变成了一个单一的 master 分支,继续向前开发,并能够将它 push 到远程仓库,供别人使用。
Git冲突的处理彻底靠人工完成。(从逻辑上讲,机器也不可能完美处理冲突。)好比一个小型团队一块儿工做,他们能够设置一个服务器用于保存远程 Git 仓库,而后每一个人工做以前先从该远程仓库 fetch 代码,接着工做,工做完成后,先在本地提交,最后 push 到远程仓库。可是当一我的 push 的时候,已经有人在他以前 push 了,若是他们工做在同一个分支,就会出现冲突。解决冲突的办法就是先把别人 push 的内容再次 fetch 下来,合并分支,而后再 push。
经过前面对git原理的了解,能够分析得出使用Git时有如下几种工做流程:
Git 服务器的建设也至关简单,由于 Git 支持以 SSH、HTTP 等协议传输数据,若是须要对服务器有写权限,就开通 SSH 服务吧,设一个帐户供全部人访问 Git 仓库便可。若是只须要读权限,使用任何一个 HTTP 服务器都可。关于 Git 服务器的建设,请自行参考官方文档。若是是我的的、开源的项目,可使用 Github 网站提供的服务,直接存储在互联网上。(Github 私人仓库是要收钱的。)
得益于 Eclipse 中的 EGit 插件,在 Eclipse 中使用 Git 很是简单。任何一个项目,均可以使用快捷菜单中的 "Team" -> "Share Project" 将文件交给版本控制软件管理,以下图:
如今最流行的版本控制软件固然是非 Git 莫属了。Eclipse 会提示咱们建立一个 Git 仓库(Repository)。Eclipse 中的项目(Project)是一个比较小的概念,它不能等同于 Git 中的工做目录(Working Directory),Git 中也没有项目的概念,可是在 Git 的工做目录中管理多个文件夹是没有什么问题的,而 Eclipse 中的项目就是一个文件夹,因此,在 Git 的一个工做目录中管理多个 Project 是没有问题的。所以,只有 Eclipse 的工做区(Workspace)才等同于 Git 中的工做目录(Working Directory)。而 Git 的仓库(Repository)通常是放在 Git 工做目录中的一个.git
目录,考虑到 Eclipse 的工做区(Workspace)中原本就已经包含了不少元数据,再在里面建立一个.git
目录,而且在里面存放 Git 的数据容易引发混乱,所以最好是把 Git 的工做目录和仓库建立在 Eclipse 的 Workspace 以外。幸亏,Eclipse 支持这样的功能。以下图,点击 "Create" 按钮,建立一个 Git 仓库,这里输入的路径/home/youxia/git/samples
实际上是一个工做目录:
从下图能够看出,工做目录为/home/youxia/git/samples
,Git 的仓库为/home/youxia/git/samples/.git
,本来在 Workspace 中的项目 JavaIODemo 被自动移到了/home/youxia/git/samples
目录中:
可使用 Navigator 视图查看项目中全部的文件,没有被 Git 跟踪的文件其图标中显示一个小问号。可使用 "Ignore" 菜单项让 Git 忽略对某些文件的跟踪,好比源代码编译后产生的类文件,以下图:
使用 "Add to Index" 菜单项让 Git 对那些须要进行版本控制的文件进行跟踪,以下图:
进行提交,以下图:
提交时需输入 Commit Message,并指定 Author 和 Committer,能够查看这次提交涉及哪些文件。以下图:
已提交的文件其图标又会发生变化,以下图:
再来看一下在一个仓库中管理多个项目。再建立两个项目,JaasDemo 和 SecurityDemo,点击菜单项 "Share Project",在弹出的对话框中,再也不选择建立仓库,而是选择现有的仓库,以下图:
操做完成后,这三个项目都被同一个 Git 仓库所管理。再有更多的项目均可以添加到这个仓库中。我在 Github 中注册了一个帐号,youxia 这个用户名已经被占用了,因此我只能用 youxia-cn,cn 表明中国,其实这个帐号挺好记的。而后,我又建立了一个 samples 仓库,用来存放我博客中写的源代码。之后你们须要参看个人源代码的时候,只须要访问 https://github.com/youxia-cn/samples 就能够了。
最后,把我本地的仓库推送(Push)到 Github 中,以下三图:
从远程仓库中获取数据的方法有多种。若是是第一次获取远程仓库,可使用git clone
命令。在 Eclipse 中,须要使用 "File" -> "Import" 功能。下面换一台电脑,这台电脑安装的是 Ubuntu 系统,启动 Eclipse,点击菜单 "File" -> "Import",获取刚才存放在 Github 中的项目,在弹出的对话框中输入正确的 URL 后,一路 Next,以下动图:
可使用 "Show in History" 和 "Show in Repositories View" 查看仓库的详细信息,以下两图:
从远程仓库获取数据还可使用git pull
命令,其对应的 GUI 操做界面以下:
能够看到,它会让你选择是将远程仓库中的分支 Merge 到本地的当前分支仍是将本地的当前分支 Rebase 到远程仓库中的分支。使用 Pull 功能时,分支的 Merge 和 Rebase 是自动进行的,因此若是没有准备好的话,不要轻易使用。
安全的作法是使用git fetch
命令从远程仓库获取数据。Fetch 过来的分支不会自动合并,你能够切换到这些分支进行查看,而后手工进行合并。其操做界面以下:
前面介绍过,随着 Git 一次次的提交,会造成一个主分支,除此以外,还能够建立新的分支。经过git branch
命令建立新分支,经过git checkout
命令切换分支。在 Git 中,有一个HEAD
指针老是指向当前正在工做的分支,以下图:
若是切换分支,HEAD
指针也会随着移动,以下图:
同时,还可使用git reset
命令改变HEAD
指针的指向,以达到撤销操做的目的。随意改变HEAD
指针的指向是危险的,特别是使用git reset
命令的--hard
选项的话,它会使咱们的部分工做丢失。在《Pro Git》的第二版中专门有一节“重置揭秘”对该命令及其涉及的原理进行了论述。在 GUI 中使用 Reset 也是很是简单的,以下图:
而分支的合并又有两种方式,Merge 和 Rebase。Merge 比较简单,以下图:
在图中有两个分支 origin 和 mywork,origin 作了提交 C3 和 C4,mywork 作了提交 C5 和 C6。若是将这两个分支合并的话,就会产生提交 C7,以下图:
可是若是使用 Rebase 就不同了,若是把 mywork 分支 Rebase 到 origin 上,就至关于把 C5 和 C6 中针对 C2 所作的修改在 C4 上重演一次,产生了 C5' 和 C6' 两次提交,而原有的 C5 和 C6 会被丢弃,以下图:
因此,Reset 和 Rebase 都是比较危险的命令,有引发数据丢失的风险。可是在 Git 中,只要是曾经 Commit 过的数据,都是能够找回来的,能够参考《Pro Git》中“维护与数据恢复”这一节(初版位于第 9 章,第二版位于第 10 章)。另外,《Pro Git》提到,对于已经公开发布到远程仓库中的代码,不要使用 Rebase,不然会引发版本库的混乱。
GUI 界面的使用没有什么困难的,难的是理解 Git 中的概念,好比 Push、Pull、Clone、Fetch、Checkout、Reset、Merge、Rebase 什么的。学习 Git 最好的办法,固然是认真阅读《Pro Git》这本宝典。除了使用 GUI,最好也能多敲一下命令行,这样对 Git 会有更加深刻的了解。
我对此次写的这个系列要求是很是高的:首先内容要有意义、够充实,信息量要足够丰富;其次是每个知识点要讲透彻,不能模棱两可含糊不清;最后是包含丰富的截图,让那些不想装 Linux 系统的朋友们也能够领略到 Linux 桌面的风采。若是个人努力获得你们的承认,能够扫下面的二维码打赏一下:
该随笔由京山游侠在2018年11月15日发布于博客园,引用请注明出处,转载或出版请联系博主。QQ邮箱:1841079@qq.com