目录

git

目录

常用命令

diff

image.png

git diff:当工作区有改动,临时区为空,diff的对比是“工作区”与最后一次commit提交的仓库的共同文件”;当工作区有改动,临时区不为空,diff对比的是“工作区”与“暂存区”的共同文件”。 git diff --cached:显示暂存区与最后一次commit的改动。 git diff <分支1> <分支2> 显示两个分支最后一次commit的改动。

init

git init初始化一个仓库

add

git add .将除.gitignore中声明的所有文件加入暂存区 也可以git add 特定文件,将文件加入暂存区。

commit

image.png

git commit -m "提交说明" 提交到工作区

git commit --amend 修改上次的提交记录

push

git push 提交到远程库。可以指定分支提交 比如:git push origin main 指定为main分支

pull

git pull 将改动拉倒本地库,并合并,默认为Merge合并 如果加上rebase参数则合并方式变为rebase合并。

log

git log 查看提交历史 git log --oneline简洁输出

branch

git branch xxx 建立分支xxx 然后用git checkout xxx 切换到分支xxx 或者用git checkout -b xxx 完成同样的操作

checkout

image.png

git checkout 回退版本即head分离 但master不变 checkout可以切换分支,也可以head分离,但是分支的位置不变,但后面的reset和revert都会改变分支

reset

git reset --hard HEAD^回退一个版本(master也改变) git reset --hard HEAD~n 回退n个版本 git reset --hard xxxxxx xxxxxx为版本号 即为git log显示的每一个版本号 一般为前六位

reset的参数有三种,其作用如下:

最危险但最常用的就是hard。soft也常用来修改某个提交,只修改提交,之后再进行提交即可达到修改的目的。

revert

git revert命令用于撤消对仓库提交历史的更改。其他“撤消”命令,例如 git checkout 和 git reset,将HEAD和分支引用指针移动到指定的提交。git revert也需要一个指定的提交,但是,它并不会将 ref 指针移动到这个提交。revert 操作将采用反转指定的提交的更改,并创建一个新的“还原提交”。然后更新 ref 指针以指向新的还原提交,使其成为分支的HEAD。(创建一个新的commit结点)

merge

git merge 比如在master分支里 执行git merge xxx 将xxx分支合并到master中,一般项目开发,一人一个分支,最后提交的时候合并再提交。不过更推荐用git rebase方法,这样合并后的分支更加直观。一般是进行三方合并。

branch

最常用的就是创建和删除分支

git branch -f master~3将分支强制回退三个版本,但head不动

cherry-pick

当需要另一个分支的所有改动时,用git merge,但当需要部分改动时候,要用git cherry-pick xxx xxx为哈希值或者分支名,指定为分支名时候,将分支的最新改动合并过来 image.png

rebase

当不知道提交的哈希值时,可以用git rebase -i HEAD~x 来可视化管理,可以调整提交的顺序,可以删除不想要的提交,或合并提交 这是线性化的自动的 cherry-pick git rebase xx1 xx2将xx2分支上的提交记录放到xx1后面

image.png 此外活用git rebase -i ,进行可视化的操作。 ### fetch git fetch获取远程仓库的数据,不会改变你本地仓库的状态,不会更新你的master,也没有更改你的本地磁盘文件,可以理解为单纯的下载操作。而git pull相当于git fetch + git merge即抓取后合并

reflog

git reflog 查看操作记录,这个操作可以撤销不小心用git reset回退版本的操作

底层内容

这几天系统学习了一下git的底层内容,通透了很多,记录一些。贴一下原博客:https://www.lzane.com/tech/git-internal/ 首先看一个图

首先要明确有四种object,第一种是记录文件内容,第二种是记录目录结构,第三种是记录提交信息,第四种是记录tag信息,第四种无关紧要。

从下面开始看,最下面记录的文件内容,注意只记录文件内容,不包括文件名等其它内容。是一个blob类型的节点,将文件的内容信息经过SHA1哈希算法得到对应的哈希值作为这个object在Git仓库中的唯一身份证。

然后再往上的三角形记录的是仓库的目录结构,它将当前的目录结构打了一个快照。从它储存的内容来看可以发现它储存了一个目录结构(类似于文件夹),以及每一个文件(或者子文件夹)的权限、类型、对应的身份证(SHA1值)、以及文件名。

再往上就是记录的提交的信息,它储存的是一个提交的信息,包括对应目录结构的快照tree的哈希值,上一个提交的哈希值,提交的作者以及提交的具体时间,最后是该提交的信息。

还有分支的信息和Head。HEAD、分支和普通的Tag可以理解为一个指针,指向对应commit的sha1值。

仓库有三个分区:工作目录、index索引区域、Git仓库。

当文件被修改后,只是工作目录发生了改变,其余两个是没有任何变化的。当运行git add xxx命令后,即将xxx文件加入了索引区域,此时新建了一个blob object,并且将原来指向xxx指向了新建的blob Object,记住索引索引的是add的所有文件,这时运行git commit,会生成一个tree object,然后创建commit object,将分支等信息指向新的commit。注意每次commit都是储存的全新的文件快照而不是变更部分。

参考

图解Git (marklodato.github.io) 这才是真正的Git——Git内部原理 - LZANE | 李泽帆(靓仔)