前面已经安装并测试成功安装了GIT工具,接下来就是具体的使用了。
一、设置开发者个人信息
在任何一个系统之中都会存在有多个开发者(多人协作开发),而在GIT之中,对于每一个开发者(单机),都需要开发者自己定义自己的名字和email邮件地址,以便进行联系。
设置全局信息
GIT是分布式版本控制系统,每个单机都有自己的基本信息:开发者名字,email地址等。
姓名:git config --global user.name"czl"
email:git config --global user.email"czl@163.com"
查询全局信息:git config -l
二、创建仓库(版本库)
创建版本库(repository)
版本库就是仓库,在此仓库中的所有内容都会被Git管理,仓库中的所有文件修改、删除、更新都会被记录下来,可以随时恢复到某一特定状态。
初始化仓库:git init
如果要开发项目,首先必须创建一个仓库,在电脑选择一个磁盘创建文件夹,如:
d:
md myproject
此时定义D盘中创建的myproject文件件为仓库,首先进入文件夹;
cd myproject
然后初始化仓库(将此目录变为可以被GIT管理的仓库)
git init
注意此时myproject文件中会创建一个“.git
”的目录,这个目录就是仓库信息,不能更改,也不能删除。不同于SVN、CVS等版本控制系统,以SVN为例,SVN会在每个子目录下面创建.svn文件夹,该文件夹包含一些配置文件,这些配置文件可以建立对版本库的跟踪(实际上这是版本控制系统的共性)。这些配置文件会记录工作区的文件名称、修改时间和版本等信息,通过时间戳的对比可以快速扫描工作区的改动。在.svn文件夹下还包括原始文件的拷贝,这些拷贝文件可以脱离版本库独立操作。此外,SVN的版本库与工作区是分离的。
注:.svn目录并不是本地仓库,而是为了建立与远端版本仓库的关联而引入的配置文件,所以SVN的版本库与工作区是分离的。
SVN这样的设计的好处是在提交的时候可以只针对差异部分进行提交,因为改动的文件可以与原始文件的拷贝进行差异比较。然而,缺点就是会加倍占用工作区的空间,而且当在工作区目录下针对文件内容进行搜索的时候,会因为.svn
目录还有原始文件的拷贝使得搜索结果加倍,混淆真正的搜索结果。
三、添加文件
仓库创建完成后,就可以进行文件的基本管理了。建议所有的文件都是用UTF-8编码格式,以免出现编码错误等问题。
新建一个hello.java
文件,保存于D:/myproject
文件下,此文件属于git仓库管理目录。使用以下命令查看当前状态:
git status
在git status
状态查询操作上可以发现有如下几个提示信息:
- 现在的开发属于主分支:On branch master;
- 初始化仓库的提交:Initial commit;
- 未标记的文件:Untracked files
- 还有提示命令:(use “git add …” to include in what will be committed)
- 未标记文件列表,示例中只有一个:hello.java
添加文件到仓库
- 增加文件到暂存区:
git add 文件名称
; 提交文件:
git commit -m"注释"
git add hello.java
然后查询状态
git status
现在文件并没有真正提交到主分支上(主分支是真正要运行的程序的所有代码)。
注意:所有修改的代码都会被git自动监测,所有的代码在使用commit提交前必须得先使用add添加到暂存区,否则不会有任何代码提交。
此处代码提交,可以将add
和commit
合并一步执行git commit -a -m"注释"
提交文件信息,执行此命令之后,hello.java
文件就被提交到主分支上,也就意味程序发布成功。例如:
git commit -m"new java file to be create"
git工具下用户每一次进行的提交实际上都会被日志记录下来,此时可以查看提交日志信息。使用git log 文件名
就可以查看详细日志信息。
注意:提交信息中的一串字符串可以理解为每次提交的唯一标识ID号,多次提交就会有多个。
四、修改仓库文件
当文件修改之后
- 查看修改结果:
git status
; - 修改前后文件对比:
git diff 文件名称
; - 查看操作日志:
git log 文件名称
;
这里我修改了刚刚创建的Java文件hello.java
使用git status
查看修改后的状态,如下图所示:
可以单刀现在git提示用户,文件没有保存到暂存区之中,提示要么将文件保存到暂存区要么恢复文件,同时说明已经修改了hello.java
。
查看文件前后区别
git diff hello.java
确认修改后,将修改后的代码内容加入到暂存区后进行提交
git commit -a -m"update hello.java file add one print"
五、工作区和暂存区
在Git学习过程中,有几个重要概念必须搞明白:工作区、暂存区和版本库。这些概念,让Git的版本控制更加便捷和高效。而Git相比其他版本控制系统的一个不同是暂存区,实际上如果理解了暂存区,对Git的其他命令理解会很快。
工作区:简单理解就是需要进行版本的某个文件夹(此处我的文件夹为myproject),这个文件夹有一些特殊之处——多了.git
这个隐藏的文件夹
版本库: myproject文件夹下的.git
文件夹就是版本库
暂存区:暂存区可以理解为一个虚拟工作区,这个虚拟工作区会跟踪工作区的文件变化(增删改等操作)。这个工作区的位于.git
文件夹下的index
目录下
需要理解一点:当需要对工作区的修改提交到版本库前,暂存区会与工作区进行差异比较,如果工作区与暂存区的文件不一致,那么需要同步工作区的修改到暂存区,然后才可以提交到版本库。从这个意义讲,暂存区可以说是工作区和版本库的桥梁。好处自然是可以在真正提交到版本库之前做任意的操作,在需要真正提交的时候push到版本库。
Git之父Linus当初设计暂存区的初衷是由于每次在SVN中commit
的时候都需要选择需要提交到版本库的文件,发现这个功能太鸡肋了。于是他想如果能够在真正commit
做任意的修改,这些修改可以先放在暂存区中,如果后悔了不仅可以非常方便撤销,而且不会影响到现有的版本库。
下面通过一张图理解为工作区、暂存区和版本库的关系:
从这张图可以得出以下信息:
Git的操作围绕工作区、暂存区(图中的index
)、版本库(图中的master
,实际上这是版本库的主分支)、对象库(图中的objects
)几个部分进行
工作区、暂存区和版本库都维持着一棵目录树
objects 标识的区域为 Git 的对象库,实际位于.git/objects
目录下
暂存区跟踪记录了工作区的文件名和文件状态(修改时间,文件大小等信息)
图中的HEAD
是一个指向最新commit的引用,可以通过版本回退的方式改变HEAD的指向
执行git add
会更新暂存区的目录树,同时将工作区的文件内容生成一个对象放入objects对象库中,在暂存区记录了该对象的索引index
执行git commit
会更新版本库的目录树,commit
成功后版本库指向的目录树就是暂存区的目录树
在图中还有其他的命令,这里可以暂时不用理会,后面就会慢慢理解的。目前只需要理解git add
和git commit
这两个命令就可以。
既然暂存区会跟踪记录工作区的文件变化,那么Git是如何实现的呢?答案是时间戳。可以使用命令git status
查看工作区与暂存区的差异情况,在执行git status
时,首先会到.git/index
下查看被跟踪的工作区文件的时间戳,如果发现自上次执行git add
(执行git add
可以让工作区的文件被跟踪)以来,文件的时间戳发生了变化,那么判断文件发生了改动,于是会与暂存区的原始文件与工作区中的该文件进行差异比较,如果发现两个文件内容不一致,那么就给出差异信息。
下面针对具体实现过程,上几张图,就一目了然了:
第一步:工作区编写程序
第二步:加入文件到暂存区(git add)
第三步:提交到master分支
六、版本回退
当用户每一次将自己的代码提交到版本库之后都会自动的生成一个commit
记录进行操作保存,每一条记录都会自动生成一个commit ID
进行唯一标识。
察看日志:git log --pretty=oneline 文件
注意:每当用户进行代码提交的时候都会生成一个commit ID,而这个commit ID就是进行代码回退的主要操作方式,回退是根据ID找到历史版本进行回退操作。
回退指针:HEAD~次数
默认状态下的HEAD
保存的是最后一次提交点
在master分支上会有一个HEAD指针存在,而这个指针默认情况下永远指向最后一次提交的位置。
当回退一次之后HEAD
改变保存提交点
当使用回退操作之后,会发现HEAD
的位置已经发生变化,如果只是回退一步,那么之前的操作不会被删除,所有的代码将回退到指定位置的状态。
git reset --hard HEAD~1
如果此时还想恢复到最新状态,那么就需要使用commit ID
进行操作了.
--找到所有的已经删除的信息的commit ID
git reflog
--恢复最后一次提交
git reset --hard ff44521
七、管理修改
在有了暂存区和master主分支概念之后,就需要回避一个问题,只有保存在暂存区之中的内容才可以被真正的修改,而不是针对于文件。
八、撤销修改
有了修改操作之后就会有撤销修改,有时候会发生这种状况,当你修改完之后,发现这样修改也许不合理,此时想要撤回到之前状态,这时候就需要撤销操作了。
1. 情况一:在为增加(git add)与提交前(git commit)用户可以直接撤销对文件所作出的修改操作。
撤销所作出的修改操作:git checkout -- 文件名称
如果在工作区之中的代码并没有增加到暂存区之中,那么如果要恢复到原始状态是很简单的。
例如代码如下(这段代码显然是有问题的,但是只要代码一修改,git就可以监测到):
public class hello{
public static void main(String args[]){
System.out.println("hello world");
System.out.println("today is bad day");
你好世界!!!!!
}
}
此时代码并没有增加到暂存区之中,此时只要使用下面的操作就可以恢复到之前状态。
git checkout -- hello.java
现代代码恢复正常状态
public class hello{
public static void main(String args[]){
System.out.println("hello world");
System.out.println("today is bad day");
}
}
2. 情况二:在已增加(git add)与未提交前(git commit)用户可以直接撤销对文件所作出的修改操作。
撤销暂存区的修改操作:git reset HEAD 文件名
丢掉已经修改的文件内容:git checkout -- 文件名称
现在假设已经将代码提交到暂存区之中。使用git add .
,然后查询状态git status
。
从暂存区之中退出
git reset HEAD hello.java
已经从暂存区中恢复到工作区之中,然后再执行
git checkout -- hello.java
九、删除文件
在之前创建的myproject之中再新建一个demo.java示例文件,然后进行删除操作,但是在git之中严格来讲,删除操作也属于修改操作。
使用以下命令
--del 要删除的文件名
del demo.java
--删除之后查看状态
git status
文件被删除之后只能利用版本控制的方式进行恢复。一般不建议使用删除操作。