第一章 Git的基本操作方法
一.初始化仓库
git init
此时会在当前目录*假如为($WORK)生成一个.git的目录文件.这个.git目录就是Git仓库.其中存放的是我们所提交的文档索引内容,Git 可基于文档索引内容对其所管理的文档进行内容追踪,从而实现文档的版本控制。工作树是包含 .git 的目录$WORK.如图所示
git add .
git add a.txt b.java
在我们使用的过程中.有时候编码器产生的一些临时文件是没有必要提交git管理的,可以用以下方法来进行忽略.
echo 'zh/' >> .gitignore
git commit
git commit -m "这里是版本更新信息"
cp -R $WORK/.git /tmp/m2doc.git
cd /tmp
git clone m2doc.git m2doc-copy
这样就实现了通过git复制一份内容到m2doc-copy目录里了.如果省略工作树名,则会使用与工作树同名的工作树名.对于clone的源git也可以是各种协议网络地址,如https://github.com/joyent/node.git
说明: 在使用git之前,需要对进行个人信息登记一下,这样就可以划分相应的责任
git config --global user.name "Your Name Comes Here"
git config --global user.email you@yourdomain.example.com
上述过程即为建立 Git 仓库的一般过程,我将其总结为图1.1所示之流程:
四.查看版本历史
git log
如果想看一下每一次版本的大致变动情况,可以使用
git log --stat --summary
返回结果以下图所示:
上图中每行commit后面的那一串数字为项目版本号.这些都是唯一的.默认由git自动生成.用以标示项目的某一次更新.我们可以根据此版本号用git show命令查看.
$ git show dfb02e6e4f2f7b573337763e5c0013802e39281
此方法可能使用的时候感觉特别的麻烦,其实可以用另外一种方便的方法.
$ git show dfb02 # 一般只使用版本号的前几个字符即可
$ git show HEAD # 显示当前分支的最新版本的更新细
每一个项目版本号通常都对应存在一个父版本号,也就是项目的前一次版本状态。可使用如下命令查看当前项目版本的父版本更新细节:
$ git show HEAD^ # 查看 HEAD 的父版本更新细节
$ git show HEAD^^ # 查看 HEAD 的祖父版本更新细节
$ git show HEAD~4 # 查看 HEAD 的祖父之祖父的版本更新细节
你可以对项目版本号进行自定义,然后就可以使用自定义的版本号查看对应的项目版本更新细节:
$ git tag v0.1 dfb02
$ git show
实际上,上述命令并非是真正的进行版本号自定义,只是制造了一个 tag 对象而已,这在进行项目版本对外发布时比较有用。本文档后续章节会对 tag 的一些细节进行介绍。
撤销与恢复
git-reset 命令有三个选项:--mixed 、 --soft 和 --hard 。我们在日常使用中仅使用前两个选项;第三个选项由于杀伤力太大,容易损坏项目仓库,需谨慎使用。 --mixed 是 git-reset 的默认选项,它的作用是重置索引内容,将其定位到指定的项目版本,而不改变你的工作树中的所有内容,只是提示你有哪些文件还未更新 --soft 选项既不触动索引的位置,也不改变工作树中的任何内容,但是会要求它们处于一个良好的次序之内。该选项会保留你在工作树中的所有更新并使之处于待提交状态。 如果执行过上面的命令,想查看实际效果,可以使用命令
git log
git reset --hard SHA1_HASH
git-status
第2章 基于Git的团队协同开发
1.两人的协同开发
修改一个项目m2ge.原来由Lyr一个人开发,后来由于时间过于紧张,于是邀请他的地友Tzc来参与M2GE库. Lyr的M2GE工作树为/work/m2ge,Tzc可通过以下命令获取同Lyr同样的工作树
$cd work
$git clone lyr@192.168.0.7:~/work/m2ge m2ge
于是两个人各自在自己的机器上开始了项目的开发,这里于是用到了我们上面讲的内容了.等一段时间后,他们感觉着很有必要将各自所做的工作合并起来,然后再进行新的开发阶段.由于Lyr为主要开发者,对开发的项目比较的熟悉,这里我们将把Tzc的工作合并到Lyr的工作树中.执行以下操作
$cd ~/work/m2ge
$git pull tzc@192.168.0.5:~/work/m2ge
这里我们使用了git pull命令,可以将远程的项目信息拉取到本地工作树中 .在本机进行合并.与其相反的命令就是git push了.操作正好相反,是将本地的工作树内容传送到远程的工作树中,在远程工作树中进行合并操作. 在合并的过程中,如果两个人修改的是不同的文件的话,合并的比较的顺利的.如果他人共同对同一个文件进行了修改,在合并的时候,系统会提示修改冲突,这个时候需要人工手动进行合并一下,然后再将合并的结果提交到仓库中.
2.三人及更多人如何协同操作
实际工作中,许多大些的项目都是由三个人以上来完成的.在合并的过程上,如果我们仍然采取上面的合并方法.所有的合并工作交给一个人来处理的话,那可能需要很长的时间和精力的.那有没有办法将合并的工作减小呢,或者分解一下呢.答案是有的.那就是让每个人从远程工作树取的信息合并到自己本地的工作树中.下面我们来介绍一下这种方法. 利用 git-pull 与 git-push 命令,那么在一个协同周期之内,除了 Lyr 之外(因为其它人是从他这里取的工作树,所以他不用进行任何操作),其余三人的项目开发流程大致如下:
$ git clone lyr@192.168.0.7:~/work/m2ge ... 项目开发 ...
$ git add 改动的文件
$ git commit
$ git pull ... 解决版本合并问题 ...
$ git push
上一节所给出的三人及三人以上的协同工作模式有些不合理,譬如 Lyr 过于特殊,别人都要 git-pull 与 git-push,唯独他不需要。现在要剥夺他的这一特权,最有效的办法就是将 M2GE 仓库建立在实验室的服务器上。
首先, Lyr 通过 SSH 登录到服务器,寻找合适位置,建立 m2ge.git 目录,譬如/project/m2ge.git ,然后初始化一个空仓库,以此作为 M2GE 仓库:
$ mkdir -p ~/project/m2ge.git
$ cd ~/project/m2ge.git
$ git --bare init --shared
上述操作中, git-init 命令的 --bare 选项可以让 m2ge.git 目录等价于一个仓库。也就是说,m2ge.git 本来是一个工作树,但是 --bare 选项将本应当存放在m2ge.git/.git 中的仓库内容全部放置在 m2ge.git 目录下,就好像仓库完全的裸露在工作树中,所以称之为赤裸的仓库。
然后, Lyr 将自己机器上已经接受 Git 管理的 m2ge 仓库推送到服务器端的m2ge.git 仓库:
$ cd ~/work/m2ge
$ git push m2@192.168.0.2:~/project/m2ge.git master
上述 git-push 命令中出现的 master 参数的含义将在下一章讲述,此处可略过不谈。现在,大家已经得到了 M2GE 仓库的最初版本,并且可以使用 git-clone 命令在本地创建工作目录:
$ git clone m2@192.168.0.2:~/project/m2ge.git
之后,我们就可以开始一个又一个协同周期,服务器上的 m2ge.git 仓库将会逐次记录着每位协同开发者的版本更新提交,此基本过程可参考上一节所述内容来理解。
2.5 总结本章讲述了基于 Git 最基本的多人协同工作模式,并引入了三个新的 Git 命令: git-clone、git-pull 与 git-push。基于这三个命令并配合上一章所讲述 Git 基本操作,足以实现 M2GE 初级阶段的协同开发。
第 3 章 项目分支管理
Git 最为世人称道的就是它那强大的项目分支管理功能,现在较为流行的版本控制系统,诸如 CVS、SVN 等,虽然也提供了项目分支管理功能,但是可用性极低。对于 Git 而言,管理多个项目分支如探囊取物耳。本章主要讲述 Git 的项目分支管理的基本知识以及如何利用这一功能形成更有章法的项目协同开发模式。
1.如何创建项目分支
Git默认只有一个分支的,那就是master分支,此分支称为主分支.并由Git自动产生.我们在上面用的其实就是一个主分支的.
要产生一个分支,操作如下:
git branch local
默认初始化其它分支时,分支内容完全赞同于主分支的.但在local分支进行的所有操作都不会影响到主分析.所以可以在local分支进行任意操作.
要查看项目有多少个分支.使用命令:
$git branch
local
*master
其中master为当前分支,前面有一个*号.所谓的主分支其实相对于当前用户所在的分支来说,各分支之间是没有主次之分的.只是人们习惯上将默认的分支称作主分支而已.
上面我们虽然创建了local分支,但Git不会自动将当前分支切换到local分支,此时我们使用命令git checkout来实现,如下:
$git checkout local
2.分支的合并
当我们在一个分支下(如local)进行了一系统的添加,编辑,删除及版本的变更操作后.需要将此分支合并到master分支里.合并分支可以用git merge命令实现,如下:
$git checkout master # 将当前分支切换为master
$git merge local # 将local分支与当前分支合并
当一个分支与master合并后,此分支就没有什么用了,我们可以将其删除:
$git branch -d local
注意:上面的-d参数只能删除已经合并过的分支,对于未合并的分支是无法删除的.如果确实想实现删除未合并的分支的话,可以用-D参数
$git branch -D localtc
3.项目新的协同开发模式
这里我们还以上面的项目M2GE为例,在实验室服务器上已经建立了M2GE仓库,以供所有开成员同步本地使用.现在以Lyr为主,看看他在此项目上开发工作的一天中的工作过程.
首先,Lyr 需要更新自己机器上的工作树,并查看实验室其他成员的版本更新信息.
$git pull
$git log
然后,Lyr 开始建立一个新的项目分支,将其命名为 lyr(此分支内容与master完全一样,可以理解成复制了一份内容,但并不是真正的复制),并将当前分支切换为该分支.
$git branch lyr
$git checkout lyr
然后这一天中剩余的大部分时间,Lyr 都在自己所建立的项目分支lyr上工作,譬如增加了 3 个新的接口及相关测试程序,并对原有接口做了一些修改。一天的工作完成后,他有必要将这一天的工作与 本人机器上M2GE 仓库的 master 分支进行合并,然后删除 lyr 分支:
$git checkout master
$git merge lyr
$git branch -d lyr
现在,Lyr 已经将这一天的工作反映到自己机器上的 M2GE master 分支上了,他最后要做的是将其它开发成员的工作内容git pull到本地,与本地的master合并,然后将其master推送到服务器端的 M2GE 仓库,以使项目其他成员能够分享他的工作。(这里要注意,在推送版本更新之前,需要使用 git pull 命令将这一天中其他成员对服务器端的 M2GE 的更新拉过来合并到自己的 master 分支,然后才可以将自己的版本更新推送到服务器上的 M2GE 仓库,)具体操作如下:
1. 使用 git pull 命令将其它开发者对服务端的更新拉过来(由于其它成员都同时对服务端的M2GE的进行了更新,所以这里只需要从服务端拉取数据即可),与本地的master分支合并,更新本地工作树;
2. 若出现版本合并冲突,并且 Git 无法自动合并,需要手工合并,然后将合并结果提交到本地 master 分支;
3. 使用 git-push 命令将本地 master 分支更新推送到服务器 M2GE 仓库中。
上面这个操作,其实也可以直接push到服务端进行操作的.但现在是以Lyr主要开发者,所以一般情况下是由主开发者在本地更新,然后再提交到服务端的公共仓库.
目前,对于我们而言,在基于 Git 的 M2GE 协同开发过程中,引入分支管理功能,可有效防止因个人操作不当而导致向服务器 M2GE 仓库提交太多的脏数据。另外,也有效保持了本地项目主分支的干净,避免了频繁 git-clone 服务器端的M2GE 仓库来恢复本地的项目主分支。
常见问题:
warning: Your console font probably doesn't support Unicode. If you experience strange characters in the output, consider switching to a TrueType font such as Lucida Console!
解决办法:
$ git config --global core.autocrlf true