这是我参与「第三届青训营 -后端场」笔记创作活动的第1篇笔记
项目初始化
mkdir study
cd study
git init
其他参数
--initial-branch 初始化的分支
--bare 创建一个裸仓库(纯Git目录,没有工作目录)
--template 可以通过模板来创建预先构建好的自定义git目录
使用tree .git 查看当前目录结构
tree .git在git bash中无法使用
参考www.cnblogs.com/snowdreams1…
常见Git配置
用户名配置
git config --global user.name "guochuang"
git config --global user.email 248704991@qq.com
Instead of
git config --global url.git@github.com:.insteadOf github.com/
Git命令别名设置
git config --global alias.cin "commint --amend --no-edit"
Git Remote
查看Remote
git remote -v
添加Remote
git remote add origin_ssh git@github.com:git/git.git
git remote add origin_http github.com/git/git.git
同一个Origin设置不同的Push和Fetch URL
git remote add origin git@github.com:git/git
git remote set-url --add --push origin git@github.com:MY_REPOSITY/git
查看:git remote -v
Git Add
touch readme.md
git commit -m "add readme"
Objects
commit/tree/blob在git里统称为Object,除此之外还有个tag的object
Blob
存储文件的内容
Tree
存储文件的目录信息
Commit
存储提交信息,一个Commit可以对应唯一版本的代码
如何把这三个信息串联在一起的?
1、通过Commit寻找到Tree信息,每个Commit都会存储对应的Tree ID
git cat-file -p 4b825dc642cb6eb9a060e54bf8d69288fbee4904
2、通过Tree存储的信息,获取对应的目录树信息
git cat-file -p 4b825dc642cb6eb9a060e54bf8d69288fbee4904
3、从tree中获得blob的ID,通过Blob ID获取对应的文件内容
git cat-file -p 4b825dc642cb6eb9a060e54bf8d69288fbee4904
Refs
cat .git/refs/heads/master
cat .git/refs/heads/testrefs的内容就是对应的Commit ID
因此把ref当做指针,指向对应的Commit来表示当前Ref对应的版本
refs/heads前缀表示的是分支,除此之外还有其他种类的ref,比如refs/tags前缀表示的是标签
Branch
git checkout -b 可以创建一个新分支
分支一般用于开发,是可以不断添加Commit进行迭代
Tag
标签一般表示的是一个稳定版本,指向的Commit一般不会变更
通过git tag命令生成tag
Annotation Tag
附注标签
一种特殊的Tag,可以给Tag提供一些额外的信息
创建附注标签
通过git tag -a 命令来完成附注标签的创建
查看tag object 的内容
追溯历史版本
获取当前版本代码
通过Ref指向的Commit可以获取唯一的代码版本
获取历史版本代码
Commit里面会存有parent commit字段,通过commit的串联获取历史版本代码
1、修改文件,并提交,创建新的commit
2、查看最新的commit,新增了parent信息
1、新增 tree object 3a
2、新增 blob object 55
3、新增 commit object 64
test ref 指向新的commit
修改历史版本
1.commit - amend
通过这个命令可以修改最近一次的commit信息,修改之后commit id 会变
2.rebase
通过git rebase -i HEAD ~3可以实现对最近三个commit的修改
1、合并commit
2、修改具体的commit message
3、删除某个commit
3. filter -branch
该命令可以指定删除所有提交中的某个文件或者全局修改邮箱地址等操作
通过git commit — -amend 命令尝试修改commit message
Obejects
新增的Object
修改Commit后我们可以发现git object 又出现了变化
新增commit object 7f
但是之前的commit object 63并没有被删除
悬空的Object
没有ref指向的object
Git GC
GC
通过git gc 命令,可以删除一些不需要的object,以及会对object进行一些打包压缩来减少仓库的体积
Reflog
reflog是用于记录操作日志,防止误删除操作后数据丢失,通过reflog来找到丢失的数据,手动将日志设置为过期
指定时间
git gc prune=now 指定的是修剪多久之前的对象,默认是两周前
完整的Git视图
Git Clone & Pull & Fetch
Clone
拉取完整的仓库到本地目录。可以指定分支,深度
Fetch
将远端某些分支最新代码拉取到本地,不会执行merge操作,会修改refs/remote内的分支信息,如果需要和本地代码合并需要手动操作
Pull
拉取远端某分支,并和本地代码进行合并,操作等同于git fetch + git merge,也可以通过git pull --rebase完成git fetch + git rebase操作
可能存在冲突,需要解决冲突
Git Push
常用命令
一般使用git push origin master 命令即可完成
冲突问题
1、如果本地的commit记录和远端的commit历史不一致,则会产生冲突,比如git commit --amend or git rebase 都又可能导致这个问题
2、如果该分支就自己一个人使用,或者团队内确认过可以修改历史则可以通过git push origin master -f来完成强制推送,一般不推荐主干分支进行该操作,正常都应该解决冲突后再进行推送
常见问题
1、为什么配置Git,但是依然没有办法拉取代码?
免密认证没有配
Instead Of配置没有配,配的SSH的免密配置,但是使用的是HTTP协议访问
2、Fetch了远端分支,但是本地当前的分支历史没有变化
Fetch会把代码拉取到本地的远端分支,但是并不会合并到当前分支,所以当前分支历史没有改变