目录
1. Git概念
Git又叫版本控制器,负责记录每次的修改及版本迭代的管理系统。(我们当然也可以自己备份好每一个版本,可如果修改几百次,那就要备几百份,并且你能记住每次修改的内容吗)
Git能管理电脑上所有的文件(文本文件/二进制文件)
- 管理文本文件:能记录项目中的源代码在第几行改了什么
- 管理二进制文件:如图片,视频,只能记录大小变化,如100kb—>200kb
git_7">2. 安装git
2.1 centos环境
查看:git --version
安装:sudo yum install git -y
卸载:sudo yum remove git -y
ubuntu_12">2.2 ubuntu环境
查看:git --version
安装:sudo api-get install git -y
卸载:sudo api-get remove git -y
ubuntu_16">3. Git基本操作(基于ubuntu环境)
3.1 创建本地仓库
想要追踪管理一台电脑上的文件,必须把文件放在电脑的一个地方,这个地方就是本地仓库,放到本地仓库下的文件才能被管理
列出目录内容:ls 或 la
3.2 配置本地仓库
创建完本地仓库必须先配置用户名称和用户email
,后期想往本地仓库中提交代码,没有这两个配置很有可能会出问题
1. 针对单个仓库
- 配置用户名:git config user.name " "
- 配置用户名:git config user.email " "
- 查看配置:git config -l
- 删除配置:git config --unset uesr.name “”(加不加双引号都可以)
【代码演示】
//配置用户名,用户邮箱
[cjq@localhost Git]$ git config user.name "Cheng"
[cjq@localhost Git]$ git config user.email "123qq.com"
//查看本地仓库的配置,能看到出现user相关信息
[cjq@localhost Git]$ git config -l
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
user.name=Cheng
user.email=123qq.com
//删除用户email配置
[cjq@localhost Git]$ git config --unset user.email
[cjq@localhost Git]$ git config -l
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
user.name=Cheng
2. 针对一台电脑下所有仓库
配置所有仓库必须单独global吗
- 配置仓库:git config --global user.name " "
- 配置用户名:git config --global user.email " "
- 查看配置:git config -l
- 删除配置:git config --global --unset uesr.name,不加global删除会失败
【代码演示】
//对所有本地仓库配置user.name
[cjq@localhost Git]$ git config --global user.name "MaoMao"
//最上面出现了user.name,下面也有user.name
[cjq@localhost Git]$ git config -l
user.name=MaoMao
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
user.name=Cheng
//对所有本地仓库配置user.email
[cjq@localhost Git]$ git config --global user.email "aa.com"
[cjq@localhost Git]$ git config -l
user.name=MaoMao
user.email=aa.com
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
user.name=Cheng
//切换到我创建的其他git仓库(gitcode),我已在gitcode目录下创建本地仓库.git
[cjq@localhost Git]$ cd ..
[cjq@localhost ~]$ cd gitcode
//查看gitcode仓库配置,也有上面设置的配置
[cjq@localhost gitcode]$ git config -l
user.name=MaoMao
user.email=aa.com
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
uesr.name=cjq
3.3 认识工作区,暂存区及版本库
[cjq@localhost Git]$ touch readMe
[cjq@localhost Git]$ ls -la
total 4
drwxrwxr-x. 3 cjq cjq 32 Nov 13 06:27 .
drwx------. 17 cjq cjq 4096 Nov 13 06:13 ..
drwxrwxr-x. 7 cjq cjq 119 Nov 13 06:04 .git
-rw-rw-r--. 1 cjq cjq 0 Nov 13 06:27 readMe
注:
【git原理图】
【代码演示】能看到git树下有HEAD,objects
[cjq@localhost Git]$ tree .git/
.git
├── branches
├── config
├── description
├── HEAD
├── hooks
│ ├── applypatch-msg.sample
│ ├── commit-msg.sample
│ ├── post-update.sample
│ ├── pre-applypatch.sample
│ ├── pre-commit.sample
│ ├── prepare-commit-msg.sample
│ ├── pre-push.sample
│ ├── pre-rebase.sample
│ └── update.sample
├── info
│ └── exclude
├── objects
│ ├── info
│ └── pack
└── refs├── heads└── tags
由图可知:
- 创建的readMe文件是在工作区,真正的本地仓库.git(版本库)不属于工作区
- 版本库中有暂存区(索引),master分支和objects对象(工作区add操作的内容,会写入对象库的一个新git对象中),每个索引指向每个不同的git对象
- 暂存区和master分支在功能上有什么区别,暂时不用知道
- 只有commit到master分支才算真正的存入仓库
- 对着目录树会发现,没有stage/index,是因为仓库刚创建,没有进行过add操作就没有暂存区
3.4 添加文件
- git add 文件名:将该文件加载进暂存区
- git add . :将该目录下所有文件加载进暂存区
- git commit -m “” :将暂存区内容加载进版本库(master分支)
- git log:查看所有的提交记录
- git log --pretty=oneline:打印漂亮的提交记录
编辑文件内容:
- 命令:vim 文件名
- 按insert键进入insert状态,编写完毕按ESC键后,enter+“ : ”,输入“wq”
【代码演示】
[cjq@localhost Git]$ vim readMe
[cjq@localhost Git]$ cat readMe
hello git[cjq@localhost Git]$ git add readMe
[cjq@localhost Git]$ git commit -m "add first File"
[master (root-commit) ab6b0e4] add first File1 file changed, 2 insertions(+)create mode 100644 readMe//创建多个文件并一键add操作
[cjq@localhost Git]$ touch file file1
[cjq@localhost Git]$ ls
file file1 readMe
[cjq@localhost Git]$ git add file file1
[cjq@localhost Git]$ git commit -m "add 2 file"
[master 4054c71] add 2 file2 files changed, 0 insertions(+), 0 deletions(-)create mode 100644 filecreate mode 100644 file1
[cjq@localhost Git]$ git log
commit 4054c7137096da92a70dd5a0af1da09bd0c7de38
Author: Cheng <aa.com>
Date: Wed Nov 13 07:14:26 2024 -0800add 2 filecommit ab6b0e4e4d4a36edc97414ebcbfdd78250214b40
Author: Cheng <aa.com>
Date: Wed Nov 13 07:12:21 2024 -0800add first File
[cjq@localhost Git]$ git log --pretty=oneline
4054c7137096da92a70dd5a0af1da09bd0c7de38 add 2 file
ab6b0e4e4d4a36edc97414ebcbfdd78250214b40 add first File
底层原理剖析
[cjq@localhost Git]$ tree .git/
.git/
├── branches
├── COMMIT_EDITMSG
├── config
├── description
├── HEAD
├── hooks
│ ├── applypatch-msg.sample
│ ├── commit-msg.sample
│ ├── post-update.sample
│ ├── pre-applypatch.sample
│ ├── pre-commit.sample
│ ├── prepare-commit-msg.sample
│ ├── pre-push.sample
│ ├── pre-rebase.sample
│ └── update.sample
├── index
├── info
│ └── exclude
├── logs
│ ├── HEAD
│ └── refs
│ └── heads
│ └── master
├── objects
│ ├── 40
│ │ └── 54c7137096da92a70dd5a0af1da09bd0c7de38
│ ├── 7f
│ │ └── 112b196b963ff72675febdbb97da5204f9497e
│ ├── a2
│ │ └── 4f52571733dca79fecb2ba4c76218a9bb0c262
│ ├── a7
│ │ └── f136a6cce5d5bdcfe13d1609d55732cd1c5d13
│ ├── ab
│ │ └── 6b0e4e4d4a36edc97414ebcbfdd78250214b40
│ ├── e6
│ │ └── 9de29bb2d1d6434b8b29ae775ad8c2e48c5391
│ ├── info
│ └── pack
└── refs├── heads│ └── master└── tags18 directories, 24 files
[cjq@localhost Git]$ cat .git/HEAD
ref: refs/heads/master
[cjq@localhost Git]$ cat .git/refs/heads/master
4054c7137096da92a70dd5a0af1da09bd0c7de38
//查看master内部有什么
[cjq@localhost Git]$ git cat-file -p 4054c7137096da92a70dd5a0af1da09bd0c7de38
tree a7f136a6cce5d5bdcfe13d1609d55732cd1c5d13
parent ab6b0e4e4d4a36edc97414ebcbfdd78250214b40
author Cheng <aa.com> 1731510866 -0800
committer Cheng <aa.com> 1731510866 -0800add 2 file
//查看tree内部有什么
[cjq@localhost Git]$ git cat-file -p a7f136a6cce5d5bdcfe13d1609d55732cd1c5d13
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 file
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 file1
100644 blob 7f112b196b963ff72675febdbb97da5204f9497e readMe
//查看readMe编号内部
[cjq@localhost Git]$ git cat-file -p 7f112b196b963ff72675febdbb97da5204f9497e
hello git
3.5 修改文件
对工作区修改包括:增加删除文件,对文件内容修改。Git追踪管理的是文件修改内容,不是整个文件。也就是说,Objects对象中存储的是修改的内容,而不是整个文件。
【代码演示】
//对文件进行修改
[cjq@localhost Git]$ vim readMe
//查看仓库状态
[cjq@localhost Git]$ git status
# On branch master
# Changes not staged for commit: //暂存区内无要提交的文件
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: readMe //工作区内readMe文件有改动 (也就是上面的in working directory)
#
no changes added to commit (use "git add" and/or "git commit -a")
//再次查看状态
[cjq@localhost Git]$ git status
# On branch master
# Changes to be committed: //暂存区有文件要提交
# (use "git reset HEAD <file>..." to unstage)
#
# modified: readMe //暂存区的文件有改动
#
//再查看仓库状态,发现已经没有文件需要提交
[cjq@localhost Git]$ git status
# On branch master
nothing to commit, working directory clean
3.6 版本回退
Git能够管理文件的历史版本,如果某天发现工作出了问题,需要从某个特定的历史版本重新开始,就需要用版本回退功能。
- git reset --soft 需要回退的commit的id:只回退版本库的内容
- git reset --mixed 需要回退的commit的id:回退版本库和暂存区的内容
- git reset --hard 需要回退的commit的id:回退工作区,暂存区及版本库的内容(慎用)
- git reflog:不小心用了hard,可以再找回原来的版本。(但git很多次迟早会把原来的commit Id冲掉)
【图示】
【代码演示】
[cjq@localhost Git]$ ls
file file1 readMe
[cjq@localhost Git]$ cat readMe
hello git
hello world[cjq@localhost Git]$ git log --pretty=oneline
7f192acb4c5fccb3d194a04b852f9d3f53fa434a add git status
4054c7137096da92a70dd5a0af1da09bd0c7de38 add 2 file
ab6b0e4e4d4a36edc97414ebcbfdd78250214b40 add first File
[cjq@localhost Git]$ git reset --hard ab6b0e4e4d4a36edc97414ebcbfdd78250214b40
HEAD is now at ab6b0e4 add first File
[cjq@localhost Git]$ cat readMe
hello git //版本回退后,内容只有hello git[cjq@localhost Git]$ ls //版本回退后,文件只有readMe
readMe
[cjq@localhost Git]$ git log --pretty=oneline
ab6b0e4e4d4a36edc97414ebcbfdd78250214b40 add first File//用了hard,怎么回到原来的版本
[cjq@localhost Git]$ git reflog
ab6b0e4 HEAD@{0}: reset: moving to ab6b0e4e4d4a36edc97414ebcbfdd78250214b40
7f192ac HEAD@{1}: commit: add git status
4054c71 HEAD@{2}: commit: add 2 file
ab6b0e4 HEAD@{3}: commit (initial): add first File
[cjq@localhost Git]$ git reset --hard 7f192ac
HEAD is now at 7f192ac add git status
[cjq@localhost Git]$ git log --pretty=oneline
7f192acb4c5fccb3d194a04b852f9d3f53fa434a add git status
4054c7137096da92a70dd5a0af1da09bd0c7de38 add 2 file
ab6b0e4e4d4a36edc97414ebcbfdd78250214b40 add first File
[cjq@localhost Git]$ cat readMe
hello git
hello world
【版本回退的速度非常快的原因】
更改master指向的commit Id即可
3.7 撤销修改
有时代码写的不满意,可以进行撤销修改
- 只有工作区存在需要撤销的代码(没有add和commit):git checkout – 文件名
//撤销修改前
[cjq@localhost Git]$ cat readMe
hello git
hello world
[cjq@localhost Git]$ vim readMe
[cjq@localhost Git]$ cat readMe
hello git
hello world
xxx code
//撤销修改后
[cjq@localhost Git]$ git checkout -- readMe
[cjq@localhost Git]$ cat readMe
hello git
hello world
- 工作区和暂存区都存在需要撤销的代码(已add,没commit):git reset --mixed HEAD(因为没有commit,HEAD指向的是上一次的commit Id),这样暂存区就撤销修改了,现在情况回到了第一种情况,再git checkout – 文件名
//对readMe文件内容修改
[cjq@localhost Git]$ cat readMe
hello git
hello world
[cjq@localhost Git]$ vim readMe
[cjq@localhost Git]$ cat readMe
hello git
hello world
xxx code
//查看仓库状态
[cjq@localhost Git]$ git status
# On branch master
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: readMe
#
//把修改后的readMe文件进行add
[cjq@localhost Git]$ git add readMe
//查看仓库状态,readMe修改后的文件已在暂存区
[cjq@localhost Git]$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: readMe
#
[cjq@localhost Git]$ git add readMe
[cjq@localhost Git]$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: readMe
#
//使用完reset命令后,暂存区修改内容已撤销,工作区没有
[cjq@localhost Git]$ git reset HEAD
Unstaged changes after reset:
M readMe
//再使用checkout命令,这时cat文件才能看到文件内容修改了
[cjq@localhost Git]$ git checkout -- readMe
[cjq@localhost Git]$ cat readMe
hello git
hello world
- 工作区,暂存区和版本库都存在需要撤销的代码(已add和commit):前提是没有push到远程仓库,git reset --hard HEAD^
HEAD^^:上上个版本
HEAD^:上一个版本
HEAD:当前版本
//编辑并查看文件
[cjq@localhost Git]$ vim readMe
[cjq@localhost Git]$ cat readMe
hello git
hello world
xxx code
//add文件后查看仓库状态
[cjq@localhost Git]$ git add readMe
[cjq@localhost Git]$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: readMe
#
//commit文件后查看仓库状态
[cjq@localhost Git]$ git commit -m "git commit reset "
[master 7ba7b90] git commit reset //这是双引号的内容 不是命令1 file changed, 1 insertion(+), 1 deletion(-)
[cjq@localhost Git]$ git status
# On branch master
nothing to commit, working directory clean
//使所有的区域都版本回退到上一个版本
[cjq@localhost Git]$ git reset --hard HEAD^
HEAD is now at 7f192ac add git status
[cjq@localhost Git]$ cat readMe
hello git
hello world
3.8 删除文件
如何删除版本库中的文件?有以下两种方法
//删除前
[cjq@localhost Git]$ ls
file1 readMe
//删除后
[cjq@localhost Git]$ git rm file1
rm 'file1'
[cjq@localhost Git]$ ls
readMe
[cjq@localhost Git]$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# deleted: file1
#
[cjq@localhost Git]$ git commit -m "git rm"
[master 925dc4e] git rm1 file changed, 0 insertions(+), 0 deletions(-)delete mode 100644 file1
[cjq@localhost Git]$ git status
# On branch master
nothing to commit, working directory clean