学习文章1
学习文章2
学习文章3
Git是开源分布式版本控制系统,版本控制是一种记录文件内容变化,查阅特定版本修订情况的系统。
虽然有两种说法,但大概意思是相同的,前三个区域都在本地,只有远程仓库不在本地。
本地仓库 = 工作区 + 版本区
.git
文件 , git init
表示在本地区域创建一个.git
文件,也就是创建版本区版本区 = 暂存区 + 仓库区
.git
目录下的index
文件,通过git add
可将工作区文件添加到暂存区git commit
可将暂存区的文件提交到仓库区,形成历史版本常见流程案例
git init
初始化,把这个文件变成Git可以管理的仓库。初始化后打开隐藏的文件可以看到有一个.git
文件。git add .
把这个文件全部提交到暂存区。git commit -m "评论"
把暂存区的全部文件提交到本地仓库。git remote add origin 仓库地址
把本地的仓库与GitHub上的远程仓库连接起来。只需要连接一次,就可以一直使用。git push -u origin master
把本地仓库提交到远程仓库。指令 | 描述 | 常见使用方法 |
---|---|---|
git add | 将本地区文件添加到暂存区,可以多次像暂存区添加 | 添加文件到暂存区:git add 文件名 添加所有文件到暂存区: git add . 添加变化的文件到暂存区: git add -A 删除暂存区的文件: git rm --cached 文件名 |
git commit | 将暂存区的全部文件提交到仓库区,形成历史版本 | 提交文件: git commit -m ”版本日志信息" 文件名 提交所有文件: git commit -m ”版本日志信息” |
git status | 查看仓库区(本地库)状态 | 红色文件没有加入暂存区,绿色加入了暂存区 |
git show 提交hash值 | 查看某次commit的修改内容 |
git commit --amend
回车 修改上次的提交信息,push后不会增加新的commit记录,但是会修改本次的commit的thash(可以理解为删掉了最新的一次commit,重新又提交了一次)git commit -m "msg" --no-verify
强制提交不检查开头 | 备注 |
---|---|
feat: | 新功能、新特性 |
fix: | 修改 bug |
perf: | 更改代码,以提高性能(在不影响代码内部行为的前提下,对程序性能进行优化) |
refactor: | 代码重构(重构,在不影响代码内部行为、功能下的代码修改) |
docs: | 文档修改 |
style: | 代码格式修改, 注意不是 css 修改(例如分号修改) |
test: | 测试用例新增、修改 |
build: | 影响项目构建或依赖项修改 |
revert: | 恢复上一次提交 |
ci: | 持续集成相关文件修改 |
chore: | 其他修改(不在上述类型中的修改) |
release: | 发布新版本 |
workflow: | 工作流相关文件修改 |
忽略哪些文件?
以vue项目为例,node_modules下载的依赖包是不用上传的,因为该文件太大了并且有包管理文件package.json
,可以利用包管理文件在重新下载依赖。
忽略一些与项目实际功能无关,比如.vscode
等IDE文件
目的
1.屏蔽IDE工具之间的差异
2.上传的文件尽可能小,别人下载的速度会更快,更好的体验
怎么忽略
1.创建忽略规则文件 xxx.ignore
, 建议是git.ignore
为了便于让~/.gitconfig
文件(.git里)引用,建议与它放在一个目录下,或者可以直接修改~/.gitconfig
git.ignore文件模板,以vue项目为例
.DS_Store
node_modules/
/dist/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
在.gitconfig
里引用
// 注意斜线的方向
excludesfile = 绝对路径/git.ignore
看了一篇很有意思的文章,感觉对版本控制的理由有帮助:Git之撤销修改 git checkout – file、git reset HEAD file 的使用
若多屏显示控制方式:空格向下翻页 b向上翻页 q退出
查看完整历史版本:git log
D:\work_code\demo\vue3_test>git log
commit eca39ce053d6a6c7650c10c6ab80d174cbbe3fcd (HEAD -> master)
Author: Ranan <ranan>
Date: Fri Aug 25 19:20:25 2023 +0800
modify
commit 36d5ec0bfa96ba0beb59e765de03024f383c9ae9
Author: Ranan <ranan>
Date: Fri Aug 25 18:44:37 2023 +0800
init
返回的信息中包含提交的UUID(commit 完整版本号
)、当前分支、作者、日志和描述信息。
查看精简历史版本:git reflog
HEAD@{移动到当前版本需要多少步},前面的数字表示本次版本的哈希值。
D:\work_code\demo\vue3_test>git reflog
eca39ce (HEAD -> master) HEAD@{0}: commit: modify
36d5ec0 HEAD@{1}: commit (initial): init
区别
git reflog
会记录每一次命令,可以查看所有分支的所有操作记录。
git log
不会显示回溯版本之后提交的版本也不能查看已经删除的记录。
本质:操作HEAD的指针,HEAD指针默认是指向最近的版本。
命令:git reset 强度 局部hash
(推荐用法)
强度 | 头指针恢复 | 已经add的缓存区 | 工作区代码 | 描述 |
---|---|---|---|---|
--soft commithash |
√ | 不丢失 | 不变 | 从commithash之后的提交回退到暂存区 |
--mixed commithash |
√ | 丢失 | 不变 | |
--hard commithash |
√ | 丢失 | 恢复到穿梭的版本 |
如果穿梭git reset
在旧版本后,使用git push
会把报错,因为本地仓库HEAD
指向的版本比远程库旧。
解决办法:git push -f
强制推,该版本之后的新版本全部消失。
常见使用场景
执行commit后,还没执行push时,想要撤销这次的commit:git reset --soft HEAD^
其他用法
git reset --hard head #当前版本
git reset --hard HEAD^ #回退到上一个版本
git reset --hard HEAD^^ #回退到上上一个版本
git reset --hard HEAD~3 #回退到往上3个版本
git reset --hard HEAD~10 #回退到往上10个版本
使用案例
先使用git reflog
查看本地库的版本情况以及对应的局部hash
值,在使用git reset --hard 局部hash
回溯版本
// 案例: 回到版本36d5ec0
D:\work_code\demo\vue3_test>git reset --hard 36d5ec0
HEAD is now at 36d5ec0 init
D:\work_code\demo\vue3_test>git reflog
36d5ec0 (HEAD -> master) HEAD@{0}: reset: moving to 36d5ec0
eca39ce HEAD@{1}: commit: modify
36d5ec0 (HEAD -> master) HEAD@{2}: commit (initial): init
D:\work_code\demo\vue3_test>git log
commit 36d5ec0bfa96ba0beb59e765de03024f383c9ae9 (HEAD -> master)
Author: Ranan <ranan>
Date: Fri Aug 25 18:44:37 2023 +0800
init
版本前进
// 案例: 前进到modify版本
D:\work_code\demo\vue3_test>git reset --hard eca39ce
HEAD is now at eca39ce modify
D:\work_code\demo\vue3_test>git reflog
eca39ce (HEAD -> master) HEAD@{0}: reset: moving to eca39ce
36d5ec0 HEAD@{1}: reset: moving to 36d5ec0
eca39ce (HEAD -> master) HEAD@{2}: commit: modify
36d5ec0 HEAD@{3}: commit (initial): init
D:\work_code\demo\vue3_test>git log
commit eca39ce053d6a6c7650c10c6ab80d174cbbe3fcd (HEAD -> master)
Author: Author: Ranan <ranan>
Date: Fri Aug 25 19:20:25 2023 +0800
modify
commit 36d5ec0bfa96ba0beb59e765de03024f383c9ae9
Author: Author: Ranan <ranan>
Date: Fri Aug 25 18:44:37 2023 +0800
init
命令:git reset HEAD
说明: 拉取最近一次提交到版本库的文件到暂存区,不影响工作区
从版本库中 拉取file到 暂存区。当我们把工作区的某个文件弄乱了 ,就可以使用该命令把版本库中的同名文件拉到暂存区,然后在拉回工作区。
这里HEAD是版本指针,也可以是其他版本地址的哈希值。
// 1.工作区修改age为15 add src/App.vue 文件进暂存区
D:\work_code\demo\vue3_test>git add -A
// 2.将仓库区最新版本的该文件拉到暂存区,不影响工作区age还是15
D:\work_code\demo\vue3_test>git reset HEAD src/App.vue
Unstaged changes after reset:
M src/App.vue
todo 这里感觉和
git rm --cached 文件名
删除暂存区的文件很像,之间的差异暂时通过看文章没有感觉出来,等工作中使用积累后更新
命令:git checkout -- fileName
放弃指定文件工作区的修改 | git checkout .
放弃工作区所有文件的修改
说明:可以理解撤销add的内容(基于上一次add),把该文件在工作区的修改全部撤销(没办法恢复!)
案例说明
1.add之后(比如 one),工作区代码修改(添加two),使用git checkout -- fileName
恢复命令,工作区代码从暂存区拉出来(只有one)
2.先add添加后commit提交(比如 one),工作区代码修改(添加two),使用git checkout -- fileName
恢复命令,工作区从仓库区恢复(只有one)
关于是从暂存区还是仓库区拉取,这里有争议。我暂时的理解是先走暂存区,暂存区没有再走仓库区。
使用说明
--
选项的作用是表明内容是目录或文件,而不是分支名,避免有文件名和分支名一样而出错的情况,因为 git checkout
后面直接加分支名就成了切换分支了,在保证不会混淆的情况下,可以直接使用git checkout
命令:git revert -n 版本号
本质:git revert
是用于“反做”某一个版本,以达到撤销该版本的修改的目的。
举例:commit
了三个版本(版本一、版本二、 版本三),突然发现版本二不行(如:有bug),想要撤销版本二,但又不想影响撤销版本三的提交,就可以用 git revert -n 版本二的版本号
命令来反做版本二,生成新的版本四,这个版本四里会保留版本三的东西,但撤销了版本二的东西。
说明: 生成一个新的提交来覆盖旧的提交,被撤销的提交 和新的提交记录都会保存
命令 | 原理 | 适用场景 |
---|---|---|
git reset | 修改HEAD的位置,即将HEAD指向的位置改变为之前存在的某个版本 | 恢复到之前某个提交的版本,且该版本之后提交的版本都不需要了 |
gir revert | 用于“反做”某一个版本,以达到撤销该版本的修改的目的。 | 想撤销之前的某一版本,又想保留该目标版本后面的版本,记录下这整个版本变动流程 |
git revert取消指定的某次提交内容时需要考虑两种commit
git commit
提交,只有一个parent commitgit merge
合并两个分支后,会得到一个新的merge commit,有两个parent commit使用git show
查看merge commit
➜ git show bd86846
commit bd868465569400a6b9408050643e5949e8f2b8f5
Merge: ba25a9d 1c7036f
# merge commit bd86846是从 ba25a9d 和 1c7036f 两个 commit 合并过来的。
命令:git revert -m 选项 需要撤销的merge哈希值
-m
选项接收的参数是一个数字,数字取值为 1 和 2,也就是 Merge 行里面列出来的第一个还是第二个。
经典的案例:https://www.cnblogs.com/bescheiden/articles/10563651.html
git checkout -- 文件名 #丢弃某个文件的修改
git checkout . #丢弃全部
丢弃全部包括:新增的文件会删除,删除的会恢复,修改的会回去。变化的地方是基于上一次add或commit。
git reset HEAD <file> #从最近的版本将该文件拉取到暂存区
git reset HEAD .
仅改变暂存区,不改变工作区。
程序员将自己的工作从开发主线上分离开来,开发自己的分支不会影响主线分支的运行。
优势
git branch
查看当前工作在哪个分支
HEAD
指针指向当前工作的本地分支,可以理解为当前分支的别名。
master
分支上创建。目的分支创建时会继承此时源分支的所有提交。命令名称 | 作用 |
---|---|
git branch 分支名 | 在当前所在的提交对象上创建一个指针,指针名为分支名。 |
git branch -v | 查看分支 |
git checkout 分支名 | 切换分支,修改HEAD指针的指向 |
git checkout -b 分支名 | 以当前分支为基准,创建并切换到指定分支 等于 git branch 分支名 + git checkout 分支名 |
git merge 分支名 | 把指定的分支合并到当前分支上 |
git branch -D 分支名 | 删除本地分支,需要在其他分支上进行 |
git push origin -D [branchName] | 删除远端分支 |
参考文章:https://juejin.cn/post/6844903945245048846
合并分支时,如果没有冲突,并且分支是单向一条线路继承下来的,git会使用fast forword
模式,但是有些快速合并不能成功,又没有冲突时,就会触发分支管理策略,git会自动做一次新的提交。
git merge [branchName] --squash
将branchName合并到当前分支,并将branchName上的所有提交合并成一次提交参考文章:https://blog.csdn.net/weixin_42310154/article/details/119004977
结论摘要:不推荐使用
拉公共分支最新代码——rebase,也就是git pull -r
或git pull --rebase
。
好处是提交记录会比较简洁。
缺点是rebase以后不知道当前分支最早是从哪个分支拉出来的了,因为基底变了。
使用场景
正在修改A分支的某个功能时,优先级更高的任务出现了,但是该任务在B分支。
①提交后切换,代码保存在A分支,但是产生了无意义的提交。
在分支A上做的修改如果没有add或者commit,切换分支之后修改会被携带。
②git stash
将当前修改(未提交的代码)存入暂存区,切换分支B修改完成后,在git stash pop
取出。
git stash
暂存后,工作区代码会恢复到最后一次提交时的代码。
常见命令
命令 | 描述 |
---|---|
git stash | 临时存储当前未commit的工作现场 |
git stash save “message” | 临时存储当前未commit的工作现场,并添加描述。 在多个stash的时候推荐 |
git stash show | 查看刚才暂存的修改 |
git stash show -p stashname | 显示指定的贮藏文件具体改动 |
git stash pop | 切换到临时存储现场的分支后,弹出栈顶的stash |
git stash apply stash@{X} | 换到临时存储现场的分支后,取出相应的暂存。X可使用命令git stash list 查看,省略stash@{X}表示最近一次。 |
git stash drop stash@{X} | 将记录表中取出的对应暂存记录删除。X可使用命令git stash list 查看,省略stash@{X}表示最近一次。 |
git stash list | 查看存储区的所有暂存修改记录 |
使用步骤
git stash
或 git stash save "message"
git stash pop
或 git stash apply stash@{X}
恢复现场存储位置说明
.git/refs/stash
中,存储的是最后一个 stash 对应的节点指针.git/log/refs/stash
中,可以看到全部的 stash 记录信息说明
git stash 只能将修改项藏匿,并能将新增项藏匿。
解决办法:
①先 git add
,在 git stash
,成功藏匿了新增和修改。
②git statsh -u