Git
git 简介
Git是什么?
Git是目前世界上最先进的分布式版本控制系统(没有之一)。
那什么是版本控制系统?
如果你用Microsoft Word写过长篇大论,那你一定有这样的经历:
想删除一个段落,又怕将来想恢复找不回来怎么办?有办法,先把当前文件“另存为……”一个新的Word文件,再接着改,改到一定程度,再“另存为……”一个新文件,这样一直改下去,最后你的Word文档变成了这样:
过了一周,你想找回被删除的文字,但是已经记不清删除前保存在哪个文件里了,只好一个一个文件去找,真麻烦。
看着一堆乱七八糟的文件,想保留最新的一个,然后把其他的删掉,又怕哪天会用上,还不敢删,真郁闷。
更要命的是,有些部分需要你的财务同事帮助填写,于是你把文件Copy到U盘里给她(也可能通过Email发送一份给她),然后,你继续修改Word文件。一天后,同事再把Word文件传给你,此时,你必须想想,发给她之后到你收到她的文件期间,你作了哪些改动,得把你的改动和她的部分合并,真困难。
于是你想,如果有一个软件,不但能自动帮我记录每次文件的改动,还可以让同事协作编辑,这样就不用自己管理一堆类似的文件了,也不需要把文件传来传去。如果想查看某次改动,只需要在软件里瞄一眼就可以,岂不是很方便?
这个软件用起来就应该像这个样子,能记录每次文件的改动:
| 版本 | 文件名 | 用户 | 说明 | 日期 |
|---|---|---|---|---|
| 1 | service.doc | 张三 | 删除了软件服务条款5 | 7/12 10:38 |
| 2 | service.doc | 张三 | 增加了License人数限制 | 7/12 18:09 |
| 3 | service.doc | 李四 | 财务部门调整了合同金额 | 7/13 9:51 |
| 4 | service.doc | 张三 | 延长了免费升级周期 | 7/14 15:17 |
Git工作原理
工作区(Working Directory)
工作区就是电脑上的一个目录,一般就是项目所在的目录。
版本库(Repository)
工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。
Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD。
第一步是用git add把文件添加进去,实际上就是把文件修改添加到暂存区;
第二步是用git commit提交更改,实际上就是把暂存区的所有内容提交到当前分支。
git 常用命令及作用
- 任何人在使用git之前,都要提交简单的个人信息,以便git区分不同的提交者身份。
git config –global user.name “your name”git config –global user.email yourname@example.com - 想新开启一个项目,应该先建立一个目录,然后所有的项目开发内容都在此目录下进行。
cd workdirgit init //产生.git文件夹git add . //将目录下的所有文件都加入到暂存(index)区git commit -m "提交信息" //将当前的暂存(index)区提交到版本库的Head所指向的分支git commit -a //这是一个偷懒的命令,相当于git add .; git commit; 但是不会将新建立的文件add进去 只管修改过的已存在的文件 - 查看修改
git diff --cached //查看index file和仓库之间代码的区别的git diff //如果省略–cached选项的话,就是比较working tree和index file(暂存区)的区别git status //这个命令在git commit之前有效,表示都有哪些文件发生了改动 - 查看日志
git log //查看commit简要日志
git log -p //会输出非常详细的日志内容,包括了每次都做了哪些源码的修改
只显示了部分详细信息git show $commit_id //显示某个提交提与上一个提交相比的详细信息 包括改了哪里
显示某个分支的详细信息git show 分支名
git show HEAD^ //查看HEAD的父母的信息git show HEAD^^ //查看HEAD的父母的父母的信息git show HEAD~4 //查看HEAD上溯4代的信息 - 分支
git branch //显示当前都有哪些分支,其中标注*为当前所在分支git branch experimental //创建一个试验分支,名称叫experimentalgit checkout experimental //转移到experimental分支
如果分支开发成功:修改代码git commit -a //在experimental分支改进完代码之后用commit在此分支中进行提交git checkout master //转移回master分支git merge experimental //经证实分支开发成功,将exerimental分支合并到主分支

如果冲突需要人为修改冲突的部分,修改后
git commit -a //彻底完成此次分支合并,即提交master分支
如果合并后没问题可以将experimental分支删除git branch -d experimental //因为experimental分支已提交,所以可安全删除此
如果分支开发失败:
git checkout master
git branch -D experimental //由于分支被证明失败,因此使用-D来放弃并删除该分支 - 图形化界面
gitk
在5中gitk的效果
gitk –since=”2 weeks ago” drivers/将在GUI中显示自2周前到现在为止的且位于drivers目录下的分支记录信息 - 拉取
我如果非常非常信任bob的开发能力:git pull /home/bob/myrepo
pull命令的意思是从远端git仓库中取出然后合并(git-merge)到我(rocrocket)的项目中去。git-pull命令有可能会因为/home/bob的目录权限问题而被拒绝,解决方法是chmod o+rx /home/bob
如果我不是很信任bob的开发能力:git fetch /home/bob/myrepo master:bobworks
此命令意思是提取出bob修改的代码内容,然后放到我(rocrocket)工作目录下的bobworks分支中。之所以要放到分支中,而不是master中,就是要我先仔仔细细看看bob的开发成果,如果我觉得满意,我再merge到master中,如果不满意,我完全可以直接git branch -D掉。git whatchanged -p master..bobworks //用来查看bob都做了什么git checkout master //切换到master分区git pull . bobworks //如果我检查了bob的工作后很满意,就可以用pull来将bobworks分支合并到我的项目中了git branch -D bobworks //如果我检查了bob的工作后很不满意,就可以用-D来放弃这个分支就可以了
过了几天,bob如果想继续帮助我开发,他需要先同步一下我这几天的工作成果,只要在其当初clone的myrepo目录下执行git pull即可:git pull //不用加任何参数,因为当初clone的时候,git已经记住了我(rocrocket)的工作目录,它会直接找到我的目录来取。 - 远端库
git 不仅可以保存在本地还可以上传到远端的github库,为了方便上传我们首先配置ssh传输密钥
为本地git库添加远端库git remote add origin 远端库路径(例如git@github.com:spaces-X/paper_version.git)
从本地push到远端库git push origin 源(本地)分支:目的(远端库)分支
在上图中我们可以看到 本地HEAD->master比远端的origin->master先进了一个版本采用上述命令来同步远端库
从远端库拉取到本地git fetch origin 源(远端)分支:目的(本地)分支git checkout master //切换到本地master分支上git merge 分支 //合并分支到master Tag与搜索
git tag V3 $commit_id 以后可以用V3来代替复杂的名称commit_id
可以用git grep帮助我们搜索:
git grep “print” V3 //在V3中搜索所有的包含print的行git grep “print” //在所有的历史记录中搜索包含print的行git log V3..V7 //显示V3之后直至V7的所有历史记录git log –since=”2 weeks ago”//显示2周前到现在的所有历史记录。具体语法可查询git-ref-parse命令的帮助文件。