前言:本系列笔记是基于极客时间的《玩转Git三剑客》专栏的笔记。
Git是一种分布式的代码管理工具。
我们在使用git前首先要设置git 的用户名和邮箱,这样git在版本管控的时候,就可以知道哪些变更、改动是哪个用户进行的改动,一目了然。(只有做了相关配置,git才能进行版本控制)
1.配置基本的用户名,用户邮箱
$ git config --global user.name 'your_name'
$ git config --global user.email '[email protected]'
2.config的三个作用域
#缺省等于local
$ git config --local #只针对某个仓库有效,对其他仓库无效。作用域为局部
$ git config --global #global对当前用户所有仓库有效
$ git config --system #system对系统所有登录的用户都有效
3.显示config的配置,加–list
$ git config --list --local
$ git config --list --global
$ git config --list --system
小结
添加配置
git config [–local | --global | --system] user.name ‘Your name’
git config [–local | --global | --system] user.email ‘Your email’查看配置
git config --list [–local | --global | --system]
区别
local:区域为本仓库
global: 当前用户的所有仓库
system: 本系统的所有用户
两种场景:
1.把已有的项目代码纳入Git管理
$ cd 项目代码所在的文件夹
$ git init
2.新建的项目直接用Git管理
$ cd 某个文件夹
$ git init your_project #your_project就是你要新建的项目,会在当前路径下创建与项目名称相同的文件夹
$ cd your_project
为了区分config的local设置和global设置不同时,仓库采用哪个设置,我们这里用local进行设置。(结论:局部优先于全局)
3.做一次简单的提交
$ git add -u
$ git log
commit abe254ce11b429b6f19ff8b5cbc84e4e27de242c (HEAD -> master)
Author: Jack-song-gif <562054870@qq.com>
Date: Fri Apr 22 00:15:45 2022 +0800
Add refering projects
commit 675f2d69f9a0e197e7338bc7dd61bd81a6913aa2
Author: Jack-song-gif <562054870@qq.com>
Date: Fri Apr 22 00:05:56 2022 +0800
Add js
commit 0cbe4a5ddd935fbdc380bb51b23cc5798ca6430f
Author: Jack-song-gif <562054870@qq.com>
Date: Fri Apr 22 00:03:49 2022 +0800
Add style.css
commit 57a9d1467bbd12c7e3507c3d21bfdc926e83ddda
Author: Jack-song-gif <562054870@qq.com>
Date: Thu Apr 21 23:59:07 2022 +0800
Add index+logo
commit e2ed4a8b41dd52cb8e31d345f9b4e41e50d3c92a
Author: Jack-song-gif <562054870@qq.com>
Date: Thu Apr 21 23:44:13 2022 +0800
Add readme
场景:给git-learning目录下的readme文件重命名
mv readme readme.md
git add readme.md
git rm readme
git mv readme readme.md
网友补充:
针对“零维”和“Sleeves” git mv 命令大小写敏感问题的补充实验
我使用的是Windows系统,系统的大小写是不敏感的。
core.ignorecase 默认配置是 true基于此配置做 git mv readme Readme 操作的话,可以在 git status 看到文件名的变化。
但是,同样基于此配置,做 mv readme Readme 操作后,再使用 git status 查看文件状态,发现 status 仍为 clean 的状态。当 core.ignorecase 配置修改为 false 时,两个操作的执行结果正好相反。
当切换到Ubuntu这种大小写敏感的系统上,不管 core.ignorecase 配置是什么,使用 git mv 和 mv 命令的结果都是一样的。
OS大小写敏感问题对 git mv 命令和 git status 命令产生了什么样的影响,想不出来可以怎么解释清楚,还希望可以有小伙伴可以继续来讨论。
总结:
直接一步修改文件名:git mv file newfile
先用mv修改,再用git管理:mv file newfile ; git add newfile;git rm file
撤销工作区和暂存区的全部修改,回退到版本库最后一次commit状态:git reset --hard
也可以指定回退到具体某一次commit:git reset --hard commitID
git log --oneline #只显示commit ID和commit message,显示一行
git log -n4 #显示最近四次提交的日志
git log -n4 --oneline #组合使用
git log --oneline -n4 #组合使用
git log #默认查看的是当前分支的日志
git log --all #查看所有分支的日志,--all表示所有分支
git log --all --graph #图形化查看版本演进历史,可以查看父子关系
git log --all --graph --oneline
git log --all --graph --oneline -n4 #n4表示显示所有分支的最近四个提交
#example
$ git log --oneline
abe254c (HEAD -> master) Add refering projects
675f2d6 Add js
0cbe4a5 Add style.css
57a9d14 Add index+logo
e2ed4a8 Add readme
git checkout -b temp(新分支名) commitID
或者:
git checkout -b temp master #基于master分支的最新提交新建temp临时分支
git log默认查看当前分支的日志
git log --all 查看所有分支的日志
git log --all --graph #图形化查看版本演进历史,可以查看父子关系
git log --all --graph --oneline
git log --all --graph --oneline -n4 #n4表示显示所有分支的最近四个提交
3.如果想查看详细的git log的使用
git help --web log #通过浏览器查看文档
gitk
修改当前仓库的用户名和邮箱
git cat-file -t 对象名 #查看对象类型
git cat-file -p 对象名 #查看对象内容
首先切换到objects文件夹,可以发现里面有两种文件夹一种是02类型,另一种是pack文件夹
cd objects/
ls -al
注意:在git眼里只要文件的内容相同就是唯一的blob
一个commit就对应一个tree树,一个tree就是存储某个commit的快照,改快照就是当前commit对应的仓库内所有文件夹,文件的信息。(即tree记录在那个时间点,文件夹和文件的信息)
tree树就是文件夹,文件夹就是树
blob跟文件名无关,只要文件内容一样就是唯一的blob
网友解读:
现在我们应该明白git底层的运行流程了,当我们添加或者修改了文件并且add到Stage Area之后,首先会根据文件内容创建不同的blob,当进行提交之后马上创建一个tree组件把需要的blob组件添加进去,之后再封装到一个commit组件中完成本次提交。在将来进行reset的时候可以直接使用git reset --hard xxxxx可以恢复到某个特定的版本,在reset之后,git会根据这个commit组件的id快速的找到tree组件,然后根据tree找到blob组件,之后对仓库进行还原,整个过程都是以hash和二进制进行操作,所以git执行效率非常之高。
$ git cat-file -t 2d832d9044
blob
$ git cat-file -p 2d832d9044
hello,world
网友总结:
没有文件也就是没有blob对象的目录是不会被git管理的,因为git要对文件进行版本管理,所以没有必要对空目录生成对象。基于这一点,readme文件的全路径是这样:[仓库根目录]/doc/readme。那么tree的数量与全路径中“/”的数量一致。
我的总结
git add操作会生成blob对象
git commit操作后才会生成tree,因为tree的作用就是为了记录commit快照。
你可以直接用git checkout commitID切换到某一个提交上,此时并没有和任何分支进行挂钩。
假设你基于某个提交进行了一些修改,此时你接收到紧急任务,需要fig一个bug,然后你就切换到master分支进行修改bug了,而原来基于某个提交的变更就会被git当作垃圾给丢弃。
当你想要进行一些变更,但是只是想要实验一下看看效果,你就可以分离头指针到某个提交,然后进行修改,不满意效果就直接切换到别的分支,那些你原来基于提交的修改就会被丢弃。
将基于commit修改的变更保存到新分支
git branch <new-branch-name> 1df216a #1df216a是变更后的最新提交
1.我们通过一个场景来演示:
#新建一个fix_readme分支,并且切换到新分支
git checkout -b fix_readme fix_css
$ git checkout -b fix_readme fix_css
Switched to a new branch 'fix_readme'
$ git branch -av #查看所有分支,发现头指针指向fix_readme分支
fix_css 1df216a Backgroud to green
* fix_readme 1df216a Backgroud to green
master abe254c Add refering projects
temp 025f501 Add zhangsan
$ cat .git/HEAD
ref: refs/heads/fix_readme
#本质上HEAD还是指向某一个提交的,HEAD指向的是分支的最新提交。
$ git cat-file -t refs/heads/fix_readme
commit
2.使用git diff比较两次提交的差异
$ git diff 1df216 675f2d69f9 #根据ID比较两次提交
$ git diff HEAD HEAD^1 #根据头指针比较当前提交与前一次提交(父提交)
$ git diff HEAD HEAD~n #比较当前提交和前n次提交
#注:git diff a b 显示的差异是b-a的结果,也就是b相对a没有的用-显示,b比a多的用+显示
扩展阅读:
git dif
repo
repo1