初始化git项目(前提你装好git环境,然后在命令行或者类似vscode等编辑器的终端中运行如下指令。这个还不会的自行百度吧),两种方式,注意区别:
// 在当前目录新建一个Git代码库
git init
// 在当前目录新建一个目录,并在新建的目录中初始化Git代码库
git init 新建的文件夹名 // 例如 git init git-study
将文件提交到暂存区
// 将单个、多个文件添加到暂存区
git add [file1] [file2]
// 将所有工作区所有改动,添加到暂存区,注意后面有个点
git add .
将暂存区文件提交到本地仓库
// 需要添加-m添加备注信息
git commit -m "备注的信息"
// 如果不添加-m参数,则会调起编辑器编辑commit的备注信息,默认是vim
commit之后发现提交错了信息怎么办?
// 当前的这一次提交出现了错误,可以通过下面这个命令进入vim进行修改
git commit --amend
查看所有commit提交记录
// 只包含提交信息
git log
// 查看所有提交记录的详细细节
// 包含了具体改动的代码
git log -p // -p是--patch的缩写
// 查看简要统计// 简要包含了,哪个文件被改动了
git log --stat
版本回退
// 回退到上一次提交,一个^代表一次提交
git reset --hard HEAD^
// 回退上上次提交
git reset --hard HEAD^^
// 回退更多次的话,可以使用~符号,例如回退一百次
git reset --hard HEAD~100
// 回退到具体的某一次commit
git reset --hard 某次commit的SHA-1值
例如:git reset --hard ee368ca3aed3e34682859495616ced301bbece34
// 本质移动HEAD和当前branch的指向,并把移动后产生的新的差异放进暂存区
// 直接回退到某次commit,--hard是一个参数,表示指向移动后,重置工作区内容
git reset --hard 0E123213
git reset --hard dev
// 参数--soft会把回退后产生的新差异直接放进暂存区,并保留当前工作目录
git reset --soft 02e21321
// 不加参数或者参数--mixed,会保留工作目录,并把暂存区的内容和回退后产生的新差异都放进工作目录,并清空暂存区
git reset 02e2131231
git reset --mixed 02e123123
我们能通过git commit提交记录,自然就能回退记录。
git中版本回退的命令是git reset,默认不加参数,和加参数git reset --mixed是一样的。这种我们用的不多,更多的是加参数--hard,具体的命令都在上面,注释也写的比较详细。
这里提一点概念,HEAD在git中其实是指向当前commit的引用,就像js中的引用类型一样,你也可以把它简单理解为指针等。而一个符号代表一次commit,HEAD就是当前最新的这次commit,HEAD^^是再往前一次commit,以此类推。~n,表示从当前最新的这个commit开始,往前第n个commit,
例如:HEAD~1是当前这次commit,等价于HEAD,HEAD~2是前一次commit,等价于HEAD^。
而一个分支branch,其实也只是一组commit记录。
将某次commit的改动,合并到当前分支
// 首先拷贝需要合并到当前分支的那个commit值的SHA-1值
// 然后在当前分支执行如下命令
git cherry-pick 某次提交的sha-1值
这也是一个很有用的命令。例如你在dev分支上,突然你需要把beta上面的某次commit合并到当前分支上,那你就可以使用该命令。
这里需要提一下SHA-1值,关于他更多的内容不去多说,只说一下他是从哪里得到的,就是git log你可以看到的一长串字符。或者在类似sourceTree的可视化工具中直接复制就可以了。不多介绍。
存储
// 存储已跟踪文件的改动和暂存区的内容
// 未被跟踪的文件不会被暂存
// 所有的存储都会被存储在一个栈上,以期取出
git stash
或
git stash save
// 如果要存储未被跟踪的文件
git stash -u
// 查看所有暂存
git stash list
// 取出
git stash apply // 取出后栈内还保存当前存储记录,下次可以再次取出当前存储
git stash pop // 取出后,栈内便删除当前存储记录,可以理解为数组的pop方法
// 移除存储记录
git stash drop 存储记录的名字(即git stash list每条记录开头显示的名字)
// 暂存除了暂存区以外的改动
git stash save --keep-index
推送相关
// 如果本地已有项目,可以连接远程库
git remote add origin 远程库地址
// 查看远程库
git remote
// 查看远程库详细信息(包含名称和地址)
git remote -v
// 推送到远程分支
git push
// 强制推送,会覆盖远程分支;要确保是私有分支
git push -f
标签
// 查看已打标签
git tag
// 创建一个标签,一般会起v1.0.0、 v2.1.1等等
git tag 标签名
// 创建一个v1.0.0的tag同时,加上备注信息
git tag v1.0.0 -m"备注信息内容"
// 查看标签信息
git show 标签名
// 将本地某个tag上传到远程服务器
git push origin v1.0.0
// 将远程服务器没有的所有本地tag全部上传
git push origin --tags
分支
// 查看分支:
git branch
// 创建分支:
git branch
// 切换分支:
git checkout
// 本质是签出,将HEAD指向某个branch,然后签出这个branch对应的工作目录
// 因此如下都是可行的
git checkout HEAD^^
git checkout master~2
git checkout 0e2321312
// 创建+切换分支:
git checkout -b
// 克隆远程某个分支到本地的新分支
git checkout -b dev origin/dev
// 合并某分支到当前分支:
git merge
// 删除本地分支:
git branch -d
// 删除远程分支
git push origin -d 要删除的分支名 // 误删分支
git reflog // 查看git仓库引用的移动记录
// 找到被删除之前的那次移动记录的SHA-1
// 切换到那次的commit记录
// 然后切出一个新分支就好
git checkout 0123123123
git checkout -b 新分支
// 补:查看某个分支的引用移动记录
git reflog 分支名
// 查看所有分支,包括远程分支
git branch -a
合并当前分支上的多个commit记录
// 列出要操作的commit
git rebase -i HEAD~次数
// 在调起的vim编辑器中,编辑每条记录前面的操作类型
// 最上面的是最老的提交
pick 5e187c7dbe8 提交内容1
pick 6d577eb3440 提交内容2
pick f9b9508a3ab 提交内容3
pick 111ab9cc261 提交内容4
// 先2-4的pick改成squash
pick 5e187c7dbe8 提交内容1
squash 6d577eb3440 提交内容2
squash f9b9508a3ab 提交内容3
squash 111ab9cc261 提交内容4
//然后保存退出,会进入一个设置commit界面的入口
# This is a combination of 4 commits.
# The first commit’s message is:
提交内容1
# The 2nd commit’s message is:
提交内容2
# The 3rd commit’s message is:
提交内容3
# The 4th commit’s message is:
提交内容4# Please enter the commit message for your changes. Lines starting
# with ‘#’ will be ignored, and an empty message aborts the commit.
//这时候需要删掉对应的commit信息,设置一个合并后的commit信息
// 然后保存退出
// 最后可以git push -f 强推远程分支
去掉当前分支上的某些commit引用
// 列出当前分支上需要操作的几次commit
git rebase -i HEAD~次数
// 直接删除对应的commit
// 在vim中删除
将某次commit的改动,合并到当前分支
// 首先拷贝需要合并到当前分支的那个commit值的SHA-1值
// 然后在当前分支执行如下命令
git cherry-pick 某次提交的sha-1值
对比区别
// 对比当前工作区与暂存区的内容,即如果你现在git add .的话暂存区会新增哪些内容
git diff
// 对比当前暂存区和本地仓库的区别,即如果你现在git commit的话,本地仓库会新增哪些内容
// 完全等价于git diff --cached 不仅意思相同,作用也相同
git diff --staged
// 对比当前工作区与本地仓库的区别
// 是上面两种区别的综合
git diff HEAD
查看/修改用户配置信息
// 查看
git config user.name
git config user.email
// 修改
git config --global user.name "xxx"
git config --global user.email "xxx"
.gitignore文件规则
1) 空格不匹配任意文件,可作为分隔符,可用反斜杠转义
2)以“#”开头的行都会被 Git 忽略。即#开头的文件标识注释,可以使用反斜杠进行转义。
3)可以使用标准的glob模式匹配。所谓的glob模式是指shell所使用的简化了的正则表达式。
4)以斜杠"/"开头表示目录;"/"结束的模式只匹配文件夹以及在该文件夹路径下的内容,但是不匹配该文件;
"/"开始的模式匹配项目跟目录;如果一个模式不包含斜杠,则它匹配相对于当前 .gitignore 文件路径的内容,
如果该模式不在 .gitignore 文件中,则相对于项目根目录。
5)以星号"*"通配多个字符,即匹配多个任意字符;
使用两个星号"**" 表示匹配任意中间目录,比如`a/**/z`可以匹配 a/z, a/b/z 或 a/b/c/z等。
6)以问号"?"通配单个字符,即匹配一个任意字符;
7)以方括号"[]"包含单个字符的匹配列表,即匹配任何一个列在方括号中的字符。
比如[abc]表示要么匹配一个a,要么匹配一个b,要么匹配一个c;
如果在方括号中使用短划线分隔两个字符,表示所有在这两个字符范围内的都可以匹配。
比如[0-9]表示匹配所有0到9的数字,[a-z]表示匹配任意的小写字母)。
8)以叹号"!"表示不忽略(跟踪)匹配到的文件或目录,即要忽略指定模式以外的文件或目录,可以在模式前加上惊叹号(!)取反。
需要特别注意的是:如果文件的父目录已经被前面的规则排除掉了,那么对这个文件用"!"规则是不起作用的。
也就是说"!"开头的模式表示否定,该文件将会再次被包含,如果排除了该文件的父级目录,则使用"!"也不会再次被包含。
可以使用反斜杠进行转义。
可以通过设置.gitignore文件的git匹配规则,告知git应该跟踪哪些文件和忽略哪些文件。采用的是标准的glob匹配规则,上面参考网上场景的glob匹配规则,其实就是shell中简化的正则。需要系统学习可以自行查阅glob相关文档。
通过这些内容:暂存/提交/标签/分支/回退/变基,可以解决我们日常中绝大部分的版本管理的内容。特别是变基rebase,是非常常用的一个功能。