前言
git作为当前最流行的版本控制系统,是每一个程序员的必备技能。
本文是作者对git使用的简单总结,适合实习生和校招生入职前扫盲用 。
先叠个甲,本文内容:
- 均为git基础操作,不涉及进阶内容;
- 如有不严谨地方,欢迎大家批评指正;
git详细教程推荐
Pro Git(中文版) (gitee.com) 从git基础 -> 使用 -> 内部原理 梳理了git相关内容,深入浅出,很适合git入门和深入了解git原理。
相关概念
想要熟练使用git,首先要清楚git各个区的概念。直接上图:
首先要建立本地和远程的概念,本质是两个代码仓库的关系,当建立联系后可以通过git命令来更新仓库代码。
- local:可以理解为本地文件夹,其实本质为本地仓库的.git文件,里面存储了git相关的配置信息以及修改内容(与远程仓库的diff)的快照;
- 工作目录:本地工作区,通俗来讲就是写代码的地方;
- 暂存区:改动代码的快照存储区域;
- 本地仓库:暂存代码提交后的存储区域,即项目路径的.git文件夹
- remote:
- 远程仓库:与本地仓库为远程映射关系
使用git的常规开发流程
首次拉取仓库代码
使用SSH连接后,直接使用git clone命令拉取仓库代码。
Bash
git clone git@github.com:[repository-name].git
此时,本地仓库处在主分支master上,且与远程仓库代码完全一致。
新建feature分支
接下来我们将从主分支master上切出feature分支进行开发迭代。
一般有两种切出开发分支的方式:
- 基于远程仓库的分支切出新的feature分支,本地仓库基于远程的分支新建本地分支(同时与远程分支建立联系),本地仓库运行如下git命令:
Bash
#获取远程仓库的最新提交记录和文件
git fetch
#或者可以获取指定分支的内容
git fetch origin/[feature-branch-name]
#基于远程分支新建本地分支
git checkout -b [feature-branch-name] origin/[feature-branch-name]
基于远程仓库的origin/[feature-branch-name]分支,在本地仓库新建并切换到该新建分支。
首先需要通过git fetch命令获取远程仓库的更新内容,或者可以使用git fetch命令获取指定的新建分支的内容更新到本地,否则本地仓库无法基于远程新建分支来新建本地分支,会遇到git报错提示 致命错误:[feature-branch-name]不是一个提交,不能基于它创建分支[feature-branch-name]。
其中git checkout用于切换分支,-b参数是新建分支git branch [new-branch-name]的缩写。 2. 基于本地仓库的分支切出feature分支,再将新建的本地分支推送到远程仓库;
Bash
git checkout -b [featrue-branch-name]
git push -u origin
同样在本地仓库分支切出feature开发分支后,使用git push命令将本地分支推送到名为origin的远程仓库,-u参数用于将其与远程仓库的同名分支建立联系。
当然也可以在featrue分支上完成开发内容后,再将分支同步到远程分支,可以使用git push origin/[feature-branch-name]推送到远程仓库的指定分支(这里同时包括新建远程分支的操作)。
推荐使用第一种方式,结合公司的相关基建工具,开发流程相对规范。
提交本地更改
本阶段涉及git最常用的5个命令,分别是:
- git status: 查看工作区内容的改动文件,可以理解为工作区目录与本地仓库存储快照之间的文件内容diff情况;
- git add: 将改动后的特定内容存储到暂存区,支持添加指定的变更文件名称(可以从git status的返回内容中获取),同时也支持一次性提交所有更改内容;
Bash
# 提交指定更改文件到暂存区
git add [change-file-name]
# 一次性提交所有更改文件到暂存区
git add .
- git commit: 将暂存区的内容提交至本地仓库,强烈推荐带上-m参数,附带本次commit的解释信息,明确本次代码提交的意义;如果直接使用git commit命令还需要进入vi编辑模式输入提交信息;
Bash
# 提交指定更改文件到暂存区
git commit -m 'commit msg'
- git log: 查看本地仓库的提交记录,每一次代码提交或本地仓库的变更都会在项目的.git文件中写入一次commit记录,且每一条commit记录都会对应一个唯一标识(commit ID)。 通过git log可以获取到的信息为:commit ID、作者、提交时间以及提交信息。
这里推荐遵循commit message的提交规范,以便于团队协作和代码管理。
Bash
# commit messeage规范
<preType>: <commit msg>
commit msg用于描述本次提交的具体改动,简明扼要即可。
其中preType表明本次提交的类型说明,常用的有:
- feat:开发的新功能或新需求
- fix:bugfix,表明本次提交是修复已知问题;
- merge:代码合并;
- git push: 将本地仓库的改动更新到远程仓库;
常见的开发场景
多人在同一个分支开发时,同事先提交了代码变更
上图为多人协作场景,当你和同事在同一个feature分支上开发时,经常会遇到同事先push代码的情况,此时你的改动将无法正常推送到远程仓库,git会提示本地分支落后于远程分支,push失败。此时需要进行前置操作:合并远程分支的最新更改。
Bash
# 当本地分支与远程分支已经建立联系
git pull
# 当本地分支未与远程分支建立联系,需要指定拉取的远程分支
git pull origin/[remote-branch]
合并后如果遇到冲突(conflict),需要解决冲突后才能进行提交。
合并提交后的示意图如下:
代码冲突conflict
代码冲突通常发生在代码合并的操作中,比如git merge或git pull。这是因为本地工作目录的代码和将要合并的代码更改了同一个文件的同一行代码,git无法判断哪些内容期望被保留,哪些内容期望被舍弃。此时需要开发人员来手动解决冲突,以保留符合预期的更改。
解决冲突时建议使用IDE提供的可视化能力来进行代码修改,可以清晰地看到产生冲突的代码位置,并明确标识了对应的本地工作目录代码和将要合入的代码。
多个分支并行开发,暂存工作目录修改
开发中经常会遇到多个分支同时开发的场景,当你从当前分支切换到另外一个开发分支,同时又期望保留当前未提交的代码改动,完成另一个分支的开发任务再回到当前分支继续开发时,git stash命令可以完全满足以上需求。
Bash
# 将当前工作区的改动(包括工作目录和暂存区)保存在一个栈中,方便后续应用
git stash
# 查看所有入栈的暂存内容
git stash list
# 取出栈顶的暂存内容,并将其应用到当前的工作目录
git stsh pop
git stash命令可以完整地保留某一个分支的工作进度,类似于单机游戏存档的操作,在需要的时候取出读档即可。
撤销提交,回到某个特定的commit提交版本
当遇到某些commit需要舍弃的场景时,比如上一次commit记录漏掉了一行代码的修改,但是又不想重新提交单独生成一个新的commit记录,那么就可以使用git reset命令来实现上一个commit的撤回操作。
首先我们先来了解下git reset命令涉及到的参数:
- HEAD:当前分支引用的指针,总是指向某次coomit记录,默认是git log中最近的一次提交记录。其中HEAD表示当前版本,HEAD^表示上一个版本,上上个版本可以用HEAD^^或HEAD^2表示,以此类推;
- --hard:撤销工作区中所有未提交的修改内容(包括工作目录修改和已经暂存的内容),将暂存区与工作目录都回退到指定的版本,并删除之前的所有信息提交;
- --soft:回退到某个指定版本,但是与--hard不同的是会保留工作目录和暂存区的修改,是一次"软"回退操作;
下面为多个git reset应用示例:
Bash
# 回退到上一个commit记录,同时丢弃工作目录和暂存区修改
git reset --hard HEAD^
# 回退到上上个commit记录,同时保留工作目录和暂存区修改
git reset --soft HEAD^2
# 回退到的指定版本还可以通过commit ID
# 首先使用git log命令查看回退版本的commit ID
git log
# 回退到指定commit ID对应的版本
git reset --hard [commit ID]
git reset --soft [commit ID]
以上为本地仓库的回退操作,那么远程分支的回退操作怎么进行呢?可以思考下。
其实关键在于本地仓库和远程仓库的对应关系,利用这一点我们可以在本地仓库实现回退操作后,使用git push来实现远程仓库的更新。但当实际操作时会发现git push操作无法正常完成,git会提示本地分支落后于远程分支,需要更新后才能进行push操作。
其实细想一下这是符合预期的表现,回退操作完成后,被撤销的本地commit记录如果还存在远程仓库,显然不能完成push操作。但是我们可以通过强制推送的方式来实现远程仓库的更新:
Bash
# 强制push操作,-f是force的缩写
git push -f
注意: 以上命令只能在独属于自己的分支上使用,不能在多人协作的开发分支上使用,否则会影响正常的开发进度。多人协作的分支容易出现以下尴尬情况:你的同事已经在你想要撤销的commit提交记录基础上进行了迭代,产生了新的commit记录,当你实现回退操作时会丢弃同事新产生的commit记录,同事:???。
清空工作目录的更改
存在这样一个场景,本地工作目录的调试代码不期望被提交到远程仓库,常见于排查线上问题的debug代码,也就是需要清空或舍弃工作目录的更改。此时可以用如下命令实现:
Bash
# 清空工作目录的代码更改
git checkout -- .
其中git checkout命令除了可以切换git分支,还可以用于恢复工作树文件;
--是一个命令行参数分割符;
.表明命令的作用域范围为当前项目路径,也可以改为特定的文件。
IDE插件推荐
推荐GitLens,可以简化git操作,且每一行代码的后面都会显示最近一次改动的相关信息,包括时间、作者以及commit记录。
结语
第一次写技术文章,希望对您有所帮助~