下载安装及基本配置
Git官网下载
Git GUI下载
安装成功后,打开,右击选择options进行个性化设置:
- 外观
- 字体
- 版本
1 版本控制
1.1 关于版本控制
- 版本控制是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统。开发中,我们仅对保存着软件源代码的文本文件作版本控制管理,但实际上,可以对任何类型的文件进行版本控制。
- 采用版本控制系统就可以将某个文件回溯到之前的状态,甚至将整个项目都回退到过去某个时间点的状态。
- 可以比较文件的变化细节,查出最后是谁修改了哪个地方,从而找出导致怪异问题出现的原因,又是谁在何时报告了某个功能缺陷等等。
- 使用版本控制系统通常还意味着,就算你乱来一气把整个项目中的文件改的改删的删,你也照样可以轻松恢复到原先的样子。但额外增加的工作量却微乎其微。
1.1.1 本地版本控制系统
- 许多人习惯用复制整个项目目录的方式来保存不同的版本,或许还会改名加上备份时间以示区别。这么做唯一的好处就是简单。不过坏处也不少:有时候会混淆所在的工作目录,一旦弄错文件丢了数据就没法撤销恢复。
- 为了解决这个问题,人们很久以前就开发了许多种本地版本控制系统,大多都是采用某种简单的数据库来记录文件的历次更新差异
- 其中最流行的一种叫做 rcs,现今许多计算机系统上都还看得到它的踪影。甚至在流行的 Mac OS X 系统上安装了开发者工具包之后,也可以使用 rcs 命令。它的工作原理基本上就是保存并管理文件补丁(patch)。文件补丁是一种特定格式的文本文件,记录着对应文件修订前后的内容变化。所以,根据每次修订后的补丁,rcs 可以通过不断打补丁,计算出各个版本的文件内容,像WPS也有类似功能。
1.1.2 集中化的版本控制系统
- 如何让在不同系统上的开发者协同工作?
- 于是,集中化的版本控制系统( Centralized Version Control Systems,CVCS )应运而生。
- 诸如 CVS,Subversion 以及 Perforce 等,都有一个单一的集中管理的服务器,保存所有文件的修订版本,而协同工作的人们都通过客户端连到这台服务器,取出最新的文件或者提交更新。多年以来,这已成为版本控制系统的标准做法
- 每个人都可以在一定程度上看到项目中的其他人正在做些什么。
- 管理员也可以轻松掌控每个开发者的权限,并且管理一个 CVCS 要远比在各个客户端上维护本地数据库来得轻松容易。
缺陷
- 中央服务器的单点故障。如果宕机一小时,那么在这一小时内,谁都无法提交更新,也就无法协同工作。
- 要是中央服务器的磁盘发生故障,碰巧没做备份,或者备份不够及时,就会有丢失数据的风险。
- 最坏的情况是彻底丢失整个项目的所有历史更改记录,而被客户端偶然提取出来的保存在本地的某些快照数据就成了恢复数据的希望。但这样的话依然是个问题,你不能保证所有的数据都已经有人事先完整提取出来过。
- 本地版本控制系统也存在类似问题,只要整个项目的历史记录被保存在单一位置,就有丢失所有历史更新记录的风险。
- 于是分布式版本控制系统( Distributed Version Control System,简称 DVCS )面世!
1.1.3 分布式版本控制系统
- 像 Git,Mercurial,Bazaar 以及 Darcs 等,客户端并不只提取最新版本的文件快照,而是把代码仓库完整地镜像下来。
优势
- 任何一处协同工作用的服务器发生故障,事后都可以用任何一个镜像出来的本地仓库恢复。因为每一次的提取操作,实际上都是一次对代码仓库的完整备份
- 许多这类系统都可以指定和若干不同的远端代码仓库进行交互。籍此,你就可以在同一个项目中,分别和不同工作小组的人相互协作。你可以根据需要设定不同的协作流程,比如层次模型式的工作流,而这在以前的集中式系统中是无法实现的。
2 Git 发展史
- Linux 内核开源项目有着为数众广的参与者。绝大多数的 Linux 内核维护工作都花在了提交补丁和保存归档的繁琐事务上(1991-2002年间)。到 2002 年,整个项目组开始启用分布式版本控制系统 BitKeeper 来管理和维护代码。
- 到了 2005 年,开发 BitKeeper 的商业公司同 Linux 内核开源社区的合作关系结束,他们收回了免费使用 BitKeeper 的权力。这就迫使 Linux 开源社区(特别是 Linux 的缔造者 Linus Torvalds )不得不吸取教训,只有开发一套属于自己的版本控制系统才不至于重蹈覆辙。他们对新的系统制订了若干目标:
- 速度
- 简单的设计
- 对非线性开发模式的强力支持(允许上千个并行开发的分支)
- 完全分布式
- 有能力高效管理类似 Linux 内核一样的超大规模项目(速度和数据量)
- 自诞生于 2005 年以来,Git 日臻成熟完善,在高度易用的同时,仍然保留着初期设定的目标。它的速度飞快,极其适合管理大项目,它还有着令人难以置信的非线性分支管理系统(见第三章),可以应付各种复杂的项目开发需求。
2 Git 命令
2.1 Git配置
代码语言:javascript复制$ git config --global user.name "Your Name"
$ git config --global user.email "email@example.com"
- git config命令的--global参数,表明这台机器上的所有Git仓库都会使用这个配置,也可以对某个仓库指定不同的用户名和邮箱地址。
2.2 版本库
初始化一个Git仓库
代码语言:javascript复制$ git init
添加文件到Git仓库
包括两步:
代码语言:javascript复制$ git add <file>
$ git commit -m "description"
- git add可以反复多次使用,添加多个文件,git commit可以一次提交很多文件,-m后面输入的是本次提交的说明,可以输入任意内容。
查看工作区状态
代码语言:javascript复制$ git status
查看修改内容
代码语言:javascript复制$ git diff
代码语言:javascript复制$ git diff --cached
代码语言:javascript复制$ git diff HEAD -- <file>
代码语言:javascript复制git diff 可以查看工作区(work dict)和暂存区(stage)的区别
git diff --cached 可以查看暂存区(stage)和分支(master)的区别
git diff HEAD -- <file> 可以查看工作区和版本库里面最新版本的区别
查看提交日志
代码语言:javascript复制$ git log
简化日志输出信息
代码语言:javascript复制$ git log --pretty=oneline
查看命令历史
代码语言:javascript复制$ git reflog
版本回退
代码语言:javascript复制$ git reset --hard HEAD^
- 以上命令是返回上一个版本,在Git中,用HEAD表示当前版本,上一个版本就是HEAD^,上上一个版本是HEAD^^,往上100个版本写成HEAD~100。
回退指定版本号
代码语言:javascript复制$ git reset --hard commit_id
代码语言:javascript复制commit_id是版本号,是一个用SHA1计算出的序列
工作区、暂存区和版本库
- 工作区:在电脑里能看到的目录;
- 版本库:在工作区有一个隐藏目录.git,是Git的版本库。
- Git的版本库中存了很多东西,其中最重要的就是称为stage(或者称为index)的暂存区,还有Git自动创建的master,以及指向master的指针HEAD。
进一步解释一些命令:
代码语言:javascript复制git add # 实际上是把文件添加到暂存区
git commit # 实际上是把暂存区的所有内容提交到当前分支
撤销修改
丢弃工作区的修改
代码语言:javascript复制$ git checkout -- <file>
- 该命令是指将文件在工作区的修改全部撤销,这里有两种情况:
- 一种是file自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;
- 一种是file已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。
- 总之,就是让这个文件回到最近一次git commit或git add时的状态。
丢弃暂存区的修改
分两步:
第一步,把暂存区的修改撤销掉(unstage),重新放回工作区:
代码语言:javascript复制$ git reset HEAD <file>
第二步,撤销工作区的修改
代码语言:javascript复制$ git checkout -- <file>
小结:
- 当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令git checkout -- <file>。
- 当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,第一步用命令git reset HEAD <file>,就回到了第一步,第二步按第一步操作。
- 已经提交了不合适的修改到版本库时,想要撤销本次提交,进行版本回退,前提是没有推送到远程库。
删除文件
代码语言:javascript复制$ git rm <file>
git rm <file>相当于执行
代码语言:javascript复制$ rm <file>
$ git add <file>
进一步的解释
- Q:比如执行了rm text.txt 误删了怎么恢复?
- A:执行git checkout -- text.txt 把版本库的东西重新写回工作区就行了
- Q:如果执行了git rm text.txt我们会发现工作区的text.txt也删除了,怎么恢复?
- A:先撤销暂存区修改,重新放回工作区,然后再从版本库写回到工作区
$ git reset head text.txt
$ git checkout -- text.txt
- Q:如果真的想从版本库里面删除文件怎么做?
- A:执行git commit -m "delete text.txt",提交后最新的版本库将不包含这个文件
git rm 与 git rm --cached
- 当我们需要删除暂存区或分支上的文件, 同时工作区也不需要这个文件了, 可以使用
git rm file_path
- 当我们需要删除暂存区或分支上的文件, 但本地又需要使用, 只是不希望这个文件被版本控制, 可以使用
git rm --cached file_path
2.3 远程仓库
创建SSH Key
代码语言:javascript复制$ ssh-keygen -t rsa -C "youremail@example.com"
关联远程仓库
代码语言:javascript复制$ git remote add origin https://github.com/username/repositoryname.git
推送到远程仓库
代码语言:javascript复制$ git push -u origin maste
- -u 表示第一次推送master分支的所有内容,此后,每次本地提交后,只要有必要,就可以使用命令git push origin master推送最新修改。
从远程克隆
- 在使用git来进行版本控制时,为了得一个项目的拷贝(copy),我们需要知道这个项目仓库的地址(Git URL).
- Git能在许多协议下使用所以Git URL可能以ssh://, http(s)