本文仅为学习笔记,大部分来自:面试官:说说你对版本管理的理解?常用的版本管理工具有哪些? | web前端面试 - 面试官系列 (vue3js.cn)
版本管理
版本控制,记录任何工程项目内各个模块的改动历程,并为每次改动编上序号。
类别:
- 本地版本控制系统
- 集中式版本控制系统
- 分布式版本控制系统
git 概述
git,是一个分布式版本控制软件。
当我们通过git init
创建或者git clone
一个项目的时候,项目目录会隐藏一个.git
子目录,其作用是用来跟踪管理版本库的。
通过git status
进行查询修改文件的状态,状态情况如下:
- 已修改(modified):表示修改了文件,但还没保存到数据库中。
- 已暂存(staged):表示对一个已修改文件的当前版本做了标记,使之包含在下次提交的快照中。
- 已提交(committed):表示数据已经安全的保存在本地数据库中。
文件状态对应的,不同状态的文件在Git
中处于不同的工作区域:
fork, clone, branch
fork
fork 克隆一个仓库的新拷贝,包含了原来的仓库(即upstream repository,上游仓库)所有内容,如分支、Tag、提交。不属于 git 的命令。
点击github
仓库中右上角fork
标识的按钮将会把源仓库全部内容复制到自己的 github 仓库中。然后 git clone
这个复制后的仓库,就可以对它进行一系列操作,而 push 也会推送到自己的 github 上。当然发送 pull requests
给源仓库。
可以通过的 Pull Request 将你的修改合并到原项目中时。
clone
clone
,译为克隆,它的作用是将文件从远程代码仓下载到本地,从而形成一个本地代码仓。默认配置下远程 Git
仓库中的每一个文件的每一个版本都将被拉取下来。
branch
查看当权分支状态或者开启另一个分支, 使用分支可以把你的工作从开发主线上分离开来,以免影响开发主线。git branch
创建分支,git checkout
切换分支。
HEAD、工作树和索引
HEAD
Head
是一个特别的指针,是一个指向你正在工作中的本地分支的指针。简单来讲,就是你现在在哪儿,HEAD 就指向哪儿。
比如,我们在test
分支commit
的时候,HEAD
指针指向了test
分支指针,而test
分支指针已经指向了最新创建的提交。
HEAD指针 --------> 分支指针 --------> 最新提交
工作树和索引
在Git
管理下,实际操作的目录被称为工作树,也就是工作区域。
在数据库和工作树之间有索引,索引是为了向数据库提交作准备的区域,也被称为暂存区域。通过 git add 则添加到 git 索引。
pull 和 fetch
git fetch
是将远程主机的最新内容拉到本地,用户在检查了以后决定是否合并到工作本机分支中。
git pull
则是将远程主机的最新内容拉下来后直接合并,即:git pull = git fetch + git merge
,这样可能会产生冲突,需要手动解决。
fetch
sh
git fetch origin master:temp
git merge temp
从远程的origin
仓库的master
分支下载代码到本地并新建一个temp
分支。执行后需要手动执行git merge
合并。
stash
stash
会把暂存区和工作区的改动进行保存,这些修改会保存在一个栈上。
git stash
会缓存下列状态的文件:
- 添加到暂存区的修改(staged changes)
- Git跟踪的但并未添加到暂存区的修改(unstaged changes)
但以下状态的文件不会缓存:
- 在工作目录中新的文件(untracked files)
- 被忽略的文件(ignored files)
如果想要上述的文件都被缓存,可以使用-u
或者--include-untracked
可以工作目录新的文件,使用-a
或者--all
命令可以当前目录下的所有修改。
适用于以下场景:
当你的开发进行到一半,但是代码还不想进行提交 ,然后需要同步去关联远端代码时.如果你本地的代码和远端代码没有冲突时,可以直接通过git pull
解决
但是如果可能发生冲突怎么办.直接git pull
会拒绝覆盖当前的修改,这时候就可以依次使用下述的命令:
- git stash
- git pull
- git stash pop
或者当你开发到一半,现在要修改别的分支问题的时候,你也可以使用git stash
缓存当前区域的代码
- git stash:保存开发到一半的代码
- git commit -m '修改问题'
- git stash pop:将代码追加到最新的提交之后
rebase 和 merge
merge
生成一个新的提交,并且master
分支的HEAD
会移动到新的分支上。通过merge
合并分支会新增一个merge commit
,然后将两个分支联系起来。
rebase
老的提交X
和Y
没有被销毁,只是简单地不能再被访问或者使用。rebase
会将整个分支移动到另一个分支上,有效地整合了所有分支上的提交。
分支合并
reset 和 revert
reset
:真实硬性回滚,目标版本后面的提交记录全部丢失了
- --mixed(默认):默认的时候,只有暂存区变化
- --hard参数:如果使用 --hard 参数,那么工作区也会变化
- --soft:如果使用 --soft 参数,那么暂存区和工作区都不会变化
sh
// 没有指定ID, 暂存区的内容会被当前ID版本号的内容覆盖,工作区不变
git reset
// 指定ID,暂存区的内容会被指定ID版本号的内容覆盖,工作区不变
git reset <ID>
revert
:同样回滚,这个回滚操作相当于一个提价,目标版本后面的提交记录也全部都有
sh
//把这次撤销,作为一次最新的提交
git revert <commit_id>
//撤销前一个版本
git revert HEAD