文章目录
一、Git安装
Git 是开放源代码的代码托管⼯具,最早是在Linux下开发的。开始也只能应⽤于Linux平台,后⾯慢慢的被移植到windows下,现在,Git可以在Linux、Unix、Mac和Windows这⼏⼤平台上正常运⾏了。
如果你的的平台是centos,安装git相当简单,以我的centos7.6为例:
cpp
sudo yum -y install git
我们还可以用下面的指令来查询 git 的版本:
cpp
git --verison
二、创建本地仓库
要提前说的是,仓库是进⾏版本控制的⼀个⽂件⽬录。我们要想对⽂件进⾏版本控制,就必须先创建⼀个仓库。
创建⼀个 Git 本地仓库对应的命令为:
cpp
git init
注意命令要在⽂件⽬录下执⾏,例如:
我们发现,当前⽬录下多了⼀个.git 的隐藏⽂件,.git ⽬录是Git来跟踪管理仓库的,不要⼿动修改这个⽬录⾥⾯的⽂件,不然改乱了,就把Git仓库给破坏了。
我们可以看看Git仓库的内容:
三、配置Git
当安装Git后⾸先要做的事情是设置你的用户名称 和e-mail地址,这是⾮常重要的。配置命令为:
cpp
设置配置
git config [--global] user.name "Your Name"
git config [--global] user.email "email@example.com"
删除配置
git config [--global] --unset user.name
git config [--global] --unset user.email
# 把Your Name 改成你的昵称
# 把email@example.com 改成邮箱的格式,只要格式正确即可。
其中--global
是⼀个可选项。如果使⽤了该选项,表⽰这台机器上所有的Git仓库都会使⽤这个配置 。如果你希望在不同仓库中使⽤不同的 name 或 e-mail 可以不要--global
选项,注意,执⾏命令时必须要在仓库⾥。
我们可以用git config -l
来查看配置:
四、认识工作区、暂存区、本地库
每个 Git 项目的根目录下有一个 .git 目录,它是 Git 默默进行版本控制时读写的"数据库"。下面有几个概念:
- 工作区:代码所在目录;
- 暂存区:
.git/index
文件 - 本地仓库:
.git
目录;
一个典型的工作流程如下图,绿色部分为工作区(Working Directory),对它进行任何修改(包括:新建文件、删除文件、文件重命名等)都和单纯的修改文件一样,不会涉及到版本控制。
通过新建或粘贴进⽬录的⽂件,并不能称之为向仓库中新增⽂件,⽽只是在⼯作区新增了⽂件。必须要通过使⽤git add 和 git commit 命令才能将⽂件添加到仓库中进⾏管理!!!
暂存区是一个包含文件索引的目录树 (.git/index
文件),记录了文件的元数据(文件名、文件长度、修改时间等),而文件内容 则存放在 .git/objects
目录下。
用 Git 进行版本控制,实际上就是在工作区、暂存区、本地仓库三个地方进行文件信息的记录。
五、添加文件
我们可以使用git add .
将当前⽬录下的所有⽂件改动添加到暂存区,也可以添加指定文件或目录:
cpp
添加⼀个或多个⽂件到暂存区:
• git add [file1] [file2]
添加指定⽬录到暂存区,包括⼦⽬录:
• git add [dir]
此时我们发现objects
目录下多了一个文件,而.git
目录下也多了一个index
目录:
然后再使用git commit
将暂存区的内容添加到本地仓库中:
cpp
提交暂存区全部内容到本地仓库中:
git commit -m "message"
提交暂存区的指定内容到仓库区:
git commit [file1] [file2]... -m "message"
注意 git commit 后面的 -m 选项,要跟上描述本次提交的 message,由用户自己完成,
这部分内容绝对不能忽略,并要好好描述,是用来记录你的提交细节,是给程序员看的
我们可以使用git log
或者git log --pretty=oneline
来查看历史提交信息:
需要说明的是,我们看到的⼀⼤串类似1c43...802的是每次提交的commit id (版本号),Git的commit id 不是1,2,3......递增的数字,⽽是⼀个SHA1计算出来的⼀个⾮常⼤的数字,⽤⼗六进制表示。
接下来我们来看看.git
目录的内容:
index
就是我们的暂存区,add后的内容都是添加到这⾥的。HEAD
就是我们的默认指向master分⽀的指针。
而默认的master分支,其实就是(这里保存了我们第一次提交的commit id):
objects
为Git 的对象库,⾥⾯包含了创建的各种版本库对象及内容 。当执⾏git add
命令时,暂存区的⽬录树被更新,同时⼯作区修改(或新增)的⽂件内容被写⼊到对象库中的⼀个新的对象中,就位于.git/objects
⽬录下,让我们来看看这些对象有何⽤处:
查找objects
时要将commit id 分成2部分,其前2位是⽂件夹名称,后38位是⽂件名称 。找到这个⽂件之后,⼀般不能直接看到⾥⾯是什么,该类⽂件是使⽤sha(安全哈希算法)加密过的git cat-file 命令来查看版本库对象的内容:
这是.git
的整体结构:
六、修改文件
Git ⽐其他版本控制系统设计得优秀,因为Git跟踪并管理的是修改,⽽⾮⽂件。
什么是修改?⽐如你新增了⼀⾏,这就是⼀个修改,删除了⼀⾏,也是⼀个修改,更改了某些字符,也是⼀个修改,,甚⾄创建⼀个新⽂件,也算⼀个修改。让我们将ReadMe⽂件进⾏⼀次修改:
此时,仓库中的ReadMe和我们⼯作区的ReadMe是不同的,如何查看当前仓库的状态呢?我们使用git status
:
上⾯的结果告诉我们,ReadMe被修改过了,但还没有完成添加与提交。
⽬前,我们只知道⽂件被修改了,如果能知道具体哪些地⽅被修改了,就更好了。有同学会说,我刚改的我知道呀!可是,你还记得你三天前写了什么代码吗?或者没写?
git diff [file]
命令⽤来显⽰暂存区和⼯作区⽂件的区别 ,显⽰的格式正是Unix通⽤的diff 格式。也可以使⽤git diff HEAD -- [file]
命令来查看版本库和⼯作区⽂件的区别。知道了对ReadMe做了什么修改后,再把它提交到本地仓库就放⼼多了。
我们git add 、 commit
后,工作区 clean,没有文件需要提交了!
七、版本回退
执⾏git reset
命令**⽤于回退版本,可以指定退回某⼀次提交的版本** 。要解释⼀下"回退"本质是要将版本库中的内容进⾏回退,⼯作区或暂存区是否回退由命令参数决定:
cpp
命令语法格式为:git reset [-soft|-mixed|-hard] [HEAD]
--soft 参数对于⼯作区和暂存区的内容都不变,只是将版本库回退到某个指定版本。
--mixed 为默认选项,使⽤时可以不⽤带该参数。该参数将暂存区的内容退回为指定提交版本内容,⼯作区⽂件保持不变。
--hard 参数将暂存区与⼯作区都退回到指定版本。切记⼯作区有未提交的代码时不要⽤这个命令,因为⼯作区会回滚,
你没有提交的代码就再也找不回了,所以使⽤该参数前⼀定要慎重。
HEAD 可直接写成commit id,表⽰指定退回的版本
HEAD 表⽰当前版本 HEAD~0 表⽰当前版本
HEAD^ 上⼀个版本 HEAD~1 上⼀个版本
HEAD^^ 上上⼀个版本 HEAD~2 上上⼀个版本
我们对ReadMe文件进行3次提交,形成3个版本的ReadMe:
cpp
wml@hcss-ecs-e18a testgit]$ vim ReadMe
[wml@hcss-ecs-e18a testgit]$ git add ReadMe
[wml@hcss-ecs-e18a testgit]$ git commit -m 'version1'
[master b20581a] version1
1 file changed, 1 insertion(+)
[wml@hcss-ecs-e18a testgit]$ vim ReadMe
[wml@hcss-ecs-e18a testgit]$ git add ReadMe
[wml@hcss-ecs-e18a testgit]$ git commit -m 'version2'
[master f7933bd] version2
1 file changed, 1 insertion(+)
[wml@hcss-ecs-e18a testgit]$ vim ReadMe
[wml@hcss-ecs-e18a testgit]$ git add ReadMe
[wml@hcss-ecs-e18a testgit]$ git commit -m 'version3'
[master 8f06c3b] version3
1 file changed, 1 insertion(+)
然后我们查看提交记录:
cpp
[wml@hcss-ecs-e18a testgit]$ git log --pretty=oneline
8f06c3b610971c0d8ef6694e0b1ca176e0317ef0 version3
f7933bd62a5abac4ac568e26ecbaf36adb279479 version2
b20581a5d7b7e59ba701d7ac878c82f380b55a1e version1
5c455e504433e0d7e2262f8a347a90dd1364e6f8 添加一些数据
1c435239ffe35b1dd3f763d618d9d48acf6b7802 第一次提交
现在,如果我们在提交完version3后,发现version3编写错误,想回退到version2,重新基于version 2 开始编写。由于我们在这⾥希望的是将⼯作区的内容也回退到要⽤到--hard 参数,示例如下:
如果我们后悔了呢?还能撤销回退到version3吗?如果我们能够找到version3的commit id,那么就可以!如果我们在终端的 git log
中找不到了,我们还能用git reflog
来查找最近执行的指令:
Git 版本回退的速度非常快,,因为Git 在内部有个指向当前分⽀(此处是master)的HEAD指针,
refs/heads/master
⽂件⾥保存当前 master 分⽀的最新commit id,当我们在回退版本的时候,Git 仅仅是给refs/heads/master
中存储⼀个特定的version。
八、撤销修改
1.对于⼯作区的代码,还没有add
例如我们向ReadMe文件中添加几行数据:
cpp
[wml@hcss-ecs-e18a testgit]$ cat ReadMe
aaa
version1
version2
[wml@hcss-ecs-e18a testgit]$ vim ReadMe
[wml@hcss-ecs-e18a testgit]$ cat ReadMe
aaa
version1
version2
safasdfasf
agsdgsdg
gasdgasdg
gasdgasdga
adsgasg
我们可以直接删除(效率不高),也可以通过git checkout -- [file]
让工作区的文件回到最近一次 add
或 commit
时的状态。
2.已经add,但没有commit
我们向ReadMe文件中添加几行数据,用git add
添加到暂存区:
cpp
[wml@hcss-ecs-e18a testgit]$ cat ReadMe
aaa
version1
version2
[wml@hcss-ecs-e18a testgit]$ vim ReadMe
[wml@hcss-ecs-e18a testgit]$ cat ReadMe
aaa
version1
version2
fsdafdafsga
gasdgasdg
adsgagsdgas
gasdgsagas
gdasgasdgas
[wml@hcss-ecs-e18a testgit]$ git add ReadMe //add到缓存区
[wml@hcss-ecs-e18a testgit]$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: ReadMe
#
我们的做法如下:
3.已经add,并且已经commit
我们向ReadMe文件中添加几行数据,用git add
添加到暂存区,再用git commit
提交到版本库。
cpp
[wml@hcss-ecs-e18a testgit]$ cat ReadMe
aaa
version1
version2
[wml@hcss-ecs-e18a testgit]$ vim ReadMe
[wml@hcss-ecs-e18a testgit]$ cat ReadMe
aaa
version1
version2
fsadfsdg
gdasgsd
gadsgdsg
gasdgasdgasgg
[wml@hcss-ecs-e18a testgit]$ git add ReadMe
[wml@hcss-ecs-e18a testgit]$ git commit ReadMe -m 'first commit'
[master bf00595] first commit
1 file changed, 4 insertions(+)
我们的做法如下:
九、删除⽂件
在Git中,删除也是⼀个修改操作,如果我们想删除ReadMe文件:
此时,⼯作区和版本库就不⼀致了,要删⽂件,⽬前除了要删⼯作区的⽂件,还要清除版本库的⽂件。
走到这,一般有两种情况:误删了或者没删完!
对于误删,用git checkout -- [file]
恢复:
对于没删完,这时就需要使⽤git rm
从暂存区和⼯作区中删除,并且commit
: