Git与GitHub
一、Git简史
1、什么是Git?
当今世界最先进、最好用的分布式版本控制系统(没有之一)!!!

2、什么是版本控制系统?
早年的软件开发过程,代码管理以手动和邮件等形式,文件命名及保存存在问题。

集中式:包括库和工作区两部分,工作区编码,再上传至库的方式完成多人协作。
问题:工作机与库机需要联网才能控制版本,传输速度较慢。

分布式:每台电脑都有工作区和库自己控制版本,数据更加安全,有逻辑上的中心。

3、有哪些常见版本控制系统?

史前时代:1982年的RCS,可能在UNIX中发布包中寻觅到踪影。

古典时期:1990年的CVS自身缺陷已经过时;1985年的PVCS、1992年的clearcase(费用昂贵、功能复杂沿用至今);微软VVS反人类;Perforace(广泛,谷歌内部最大代码管理器)。

中世纪:SVN解决了CVS的问题,集中式领域王者。AccuRev(支持分支合并让很多公司拜托cvs和clearcase)。

文艺复兴:BitKeeper(SUN大量使用),2002年Linux内核使用,2005年闭源时有人试图破解,于是出现了Git。

4、Git出世
Git的第一个版本由Linus操刀,两周内用C写完。并在向世人介绍Git时强烈批评了CVS和SVN等,Git消除了分支和合并的恐惧。很多大型开源项目由SVN迁移至Git。
2008年www.github.com也成为世界最大的SCM系统,Git称为版本控制系统的主流。

5、GitHub上的著名项目
Linux内核、安卓、jQuery、Bootstrap、Ruby….
二、Git的安装于基本配置
1、安装
Linux安装
二进制包(在线)

yum -y install git  //RedHat系列
apt-get git install     //Debian系列

源码包(官网下载)
Windows安装
Git在Windows使用模拟环境msysgit
下载地址:
http://msysgit.github.io/
注意:如果想让windows作为git服务器则需要搭建ssh服务。

2、初始化
无论Linux还是Windows,安装完成后都要初始化

git config [--global] user.name “Your Name”
git config [--global] user.email “email@example.com”

目的:git操作身份,--global为全局配置,不加则为当前库配置身份。
三、Git常用操作
1、生成版本库
准备空目录、并将其变为Git版本库

mkdir dirname
cd dirname
git init

完成后目录下出现.git隐藏目录,即版本库。

2、 添加文件至版本库

vim newfile/touch newfile /mkdir newdir //创建新文件
git add newfile                     //添加文件至缓存区
git commit -m ‘描述’                  //提交文件至版本库

多文件添加

git add newfile1 newfile2…
git commit -m ‘描述’                  //将缓存区的多次添加一次提交

============== 番外篇:Git实现原理 ==================
工作区(working diretory):编码的地方

图 3-1 工作区
版本库(Reponsitory):负责代码版本控制,就是.git这个隐藏目录。

图 3-2 版本库

图 3-3 版本库原理图

版本库包括:暂存区(index/stage),HEAD(指针),分支(默认为master主分支)等。
文件提交至版本库总共分两步:
① git add filename //添加至stage缓存区
② git commit -m ‘描述’ //将stage的内容提交至版本库的master分支

实验:修改->添加->再次修改->提交->查看状态 查看区别

=================== 番外篇结束 ==========================

3、查看文件修改状态

git status                              //如果文件修改则提示modify
git diff filename                       //查看工作区文件和库文件区别
git log [--pretty=oneline]                  //查看git日志,加选则一行显示

4、版本回退

git reset --hard HEAD^                  //回退上一个版本
git reset --hard HEAD^^                     //回退上两个版本
git reset --hard HEAD~n                     //回退上n个版本

git reset --hard commitid                   //回退指定版本,commitid根据log获取

5、行为日志

git reflog                              //行为日志,显示行为及commitid简写

6、撤销修改
目的:将尚未提交至版本库的修改撤回。
情况一:
文件修改后尚未添加至缓存区
git checkout --filename //在工作区撤销文件修改
情况二:
文件修改已添加至缓存区
git checkout HEAD [filename] //撤回添加至缓存区的修改
注:不指定文件名则撤回所有

7、删除文件控制

rm filename                         //删除工作区文件
git rm filename                         //删除版本库文件

四、远程仓库
非本机的版本控制库(通常为外网网站),在远端有文件备份、版本控制和协同作用。
最知名的免费Git代码托管网站:www.github.com

1、建立远程仓库信任
每次与远程仓库的交互都需要验证身份,固建立ssh非对称加密方式(Linux第五天课程)最为方便。

①生成rsa密钥对
在所在操作系统的登陆用户家目录下执行

ssh-keygen -t rsa

之间的询问可一路Enter回车即可,家目录中生成.ssh/目录,公私密钥文件各一。

图 4-1 ssh生成rsa密钥对
②添加SSH远程信任
[login github] -> [setting] -> [SSH keys] -> [Add SSH key] -> [title] -> [粘贴公钥内容] -> [add key] 如图:

图 4-2 添加SSH远程信任
③创建远程仓库

图 4-3 创建远程仓库
库名设置同本地一致,易于辨认。默认公开库内容,并点击创建库即可。

2、本地与远程同步

图 4-4 本地与远程同步
点击创建库后,出现此页面,可使用HTTPS和SSH(默认)两种协议同步,SSH已经信任,可直接同步。HTTPS需要每次操作输入登陆用户名密码(不使用)。

①回到本地命令行建立远程连接:

git remote add origin git@github.com:username/xxx.git

注:username为github登陆用户名,xxx为同步库名,例如:
git remote add origin git@github.com:KID-G/learngit.git
等录用户为KID-G,同步库名为learngit
②推送本地版本至远程
git push -u origin master
第一次本地提交,因为远程为同名空库加选项-u 之后可省略,origin表远程,master表是提交至主分支,成功后查看远程库,已经同步。

添加远端库信任后,第一次操作会提示:
The authenticity of host 'github.com (xx.xx.xx.xx)' can't be established.RSA key fingerprint is xx.xx.xx.xx.xx.
Are you sure you want to continue connecting (yes/no)?
输入yes即可,还会出现:
Warning: Permanently added 'github.com' (RSA) to the list of known hosts.
此句表示将key添加到.ssh/know_hosts文件中,之后不会再出现。

3、远程克隆
有了远程后,想建立一台新的Git服务器除了初始化git init之外,可通过clone的方式拷贝一份远端库。

mkdir clonedir                              //创建克隆地点
cd clonedir                             
git clone git@github.com:KID-G/learngit.git     //git协议
git clone https://github.com/KID-G/learngit.git //https协议

再看已将远端库learngit同步至本地clonedir目录。
五、分支管理
分支的作用:
多功能同时开发,互不影响。便于发布和备份作用。

1、创建分支

git checkout -b dev                 //创建并切换到dev分支
git branch                          //查看当前分支,标*的为当前分支
git checkout master                 //切换分支,例切换至master主分支

图 5-2 HEAD指向master的最新版本

图 5-3 HEAD指向master的新分支dev

2、合并与删除
git merge [--no-ff -m “描述”] dev //合并分支到当前分支,禁用FF模式
禁用FF模式:分支合并后,删除分支。默认启用ff模式,此模式会删除掉分支信息,固合并时可禁用。
git branch -d dev //删除dev分支

图 5-4 HEAD指向dev分支的新版本

图 5-5 HEAD将dev分支合并至master分支

图 5-6 删除dev分支,完成新版本开发

3、解决冲突
多分支修改同一文件,合并可能出现冲突。冲突部分用<<<===>>>表示。

解决方法:
先手动修改冲突部分,再次提交即可。
查看日志(图形化):课件分支走向。

git log –grap –pretty=oneline --abbrev-commit

4、Bug分支
如果出现临时bug怎么办?
储藏:将当前库状态保存,以后再回复存档

git stash                       //将当前状态存储
git stash list                  //查看存储列表
git stash apply                 //回复存储
git stash drop                  //删除存储
git stash apply stash@{n}           //多存储时指定第n个存储

5、分支管理策略

图 5-7 分支管理策越
六、多人协作
将GitHub当做中心库协同开发,需要将本地文件推送至远端,远端拉取到本地两种操作类似SVN的提交/更新。
1、查看远端库列表

git remote -v

2、推送/拉取

git push origin branch          //将本地库推送到远程banch分支
git pull origin branch          //将远端banch分支拉取到本地并且合并

3、分布拉取

git fetch origin                    //将远端库获取本地但不合并
git merge origin                //将本地的远端库合并

七、标签与文件忽略
有时版本号commitid太长不便于记忆,可创建标签,操作标签等同于操作commitid
1、标签管理

git tag tagname             //创建标签
git tag                         //查看标签
git tag -d tagname              //删除标签

git tag origin tagname          //将标签推送至远端
git push origin --tags/tagname      //删除远端标签

2、忽略文件
工作区某些文件不控制版本,请忽略
方法一:添加忽略文件名至/.git/info/exclude文件中。
方法二:在工作区生成.gitignore文件,将忽略文件写入。
注意:方法二仅对后生成的文件有效,如果文件已存在,需要再加。
八、GitHub的世界
了解开源世界的注明项目,并参与其中,先找到开源项目fork回来,然后可以clone到本地,修改完毕后可以将修改提交到远程仓库,然后pull requests给源项目,等待合并。