git常见命令

231 阅读10分钟

一、背景介绍

       近期在开发过程中因为 Git 操作不当以及使用不熟,带来了不少团队协作问题,比如:分支被覆盖、提交日志杂乱、分支创建很随意,同时在上线日当天需求被推迟上线,前端又需要对代码进行回滚以及 rebase 操作等系列问题。针对以上内部遇到的 Git 问题梳理了相关操作规范和 Git 使用指南。

二、Git 介绍

       Git 是一个分布式版本控制工具,它可以非常轻松帮你管理任何时间任何人做的任何提交。 知识虽旧,历久弥坚。本文总结了在日常工作中是如何玩弄 Git 的,希望这篇总结对部分 Git 操作不熟的同学有所帮助。

概念理解

使用 Git 之前先了解 Git 仓库运转流程,共分为4个概念:本地空间、暂存区、本地仓库和远程仓库。如下图:

  • 本地空间:存放的本地代码
  • 暂存区:存放修改后的文件
  • 本地仓库:存放提交修改后的文件
  • 远程仓库:存放远程推送代码

是不是有点像 VuexAction -> Mutation -> State

三、Git 工作使用

安装配置

git config --global user.name "zhangsan"
git config --global user.email "zhangsan@github.com"
复制代码
  1. 配置账号和邮箱后,提交代码会显示提交人,便于问题追查和 CR 。
  2. 想要托管账户,可使用ssh-keygen -t rsa -C "xxx@github.com"生成公钥,把id_rsa.pub内容复制到SSH keys

常用操作

日常工作中,对于 Git 的掌握用好了,也是一种提效,以下总结一些日常必备的 Git 技能。

远程仓库

  1. 克隆远程仓库
git clone <repo-url>
复制代码
  1. 关联远程仓库
git remote add origin <repo-url>
复制代码

本地已存在的项目关联到已有的仓库中。

代码提交

  1. 代码拉取
git pull
复制代码
  1. 文件暂存
git add .
复制代码

注意后面是一个点,点代表暂存所有,单个文件暂存改成文件路径即可。

  1. 本地仓库提交
git commit -m "feat: 开发订单" -a
复制代码

-m 代表提交备注,-a 代表提交所有文件。提交描述可参照下文的提交规范。

代码合并

如果想要把 feature/order 合并到 release

# 切换到 release 分支
git checkout release

# 合并功能分支到当前 release 分支
git merge feature/order
复制代码

分支合并是基本操作,合并的过程中很多时候会产生冲突,如果不确定使用谁的代码,最好跟当事者沟通一下。

远程推送

git push <remote> <branch>
复制代码

如果推送的时候被驳回了,大概率是冲突了,优先解决冲突并从新推送;如果确认使用本地代码,则可以使用 --force 强制推送。

分支操作

  • 查看本地分支:git branch
  • 查看远程分支:git branch -r
  • 查看所有分支:git branch -a
  • 切换分支:git checkout
  • 切换并创建新分支:git checkout -b
  • 删除本地分支:git branch -d
  • 删除远程分支: git push origin :
  • 合并分支:git merge

代码回滚

  1. 本地代码丢弃
# 单个文件丢弃
git checkout main.js

# 所有文件丢弃
git checkout .
复制代码
  1. 撤销某次提交

如上图,可以看到有2条记录,如果想要撤回log 1的提交代码,可使用 git revert <commit-hash> 进行回滚。

git revert 0ac68bc3a99a351b4ef9e475436efffa307e7288
复制代码

使用 git revert 会生成一条新的提交记录

  1. 软回滚

同样以上图为例,如果发现log 2的提交只是部分代码写错了,我们想要撤回来从新修改一下再提交,并不是完全舍弃,可使用 git reset --soft <commit> 进行软回滚。

git reset --soft <commit>
复制代码

需要注意的是,commit 指要回滚到哪个版本,此版本以后的提交都会被回滚(不包含当前版本),而 revert 只能撤销某一条提交。

回滚以后,从新执行 git status 你会发现这 log 2 文件变成了 modify ,也就是跟刚做完未提交是一个状态,此时我们可以若无其事的正常开发,正常提交。但是推送的时候由于跟远程仓库不一致,我们需要执行--force进行强制推送。

  1. 硬回滚

同样以上图为例,如果发现 log 2 完全提交错误,想要舍弃,此时可使用 git reset --hard <commit>进行回滚。

git reset --hard <commit>
复制代码

执行完硬回滚一下,本地仓库会完全删除 log 2的代码,我们只需要强制推送即可。

软回滚本地会保留提交代码,硬回滚本地会删除对应提交代码。最后都必须通过--force才能推送到远程。为了方便起见,可使用 [HEAD]进行快捷操作,比如:git reset --soft HEAD~3 回退到前3次。

四、规范

多人协作时,为了更好管理分支以及提交日志,我们最好建立相关规范,提高协作效率。

分支规范

分支介绍环境
master仓库默认分支,暂无使用-
release线上保护分支Prd
release-pre预发环境分支,用于QA做固定Pre测试Pre
test测试环境分支,用于QA做固定Test测试Test
feature/xxx功能开发分支Dev/Test
hotfix/xxx热修复分支Pre/Prd
release-2022xxx上线分支;上线当日部署到Pre进行验证,通过以后直接作为上线分支使用Pre/Prd

日常开发中,对于线上环境、预发环境和测试环境建议使用固定分支进行部署,所有分支以 release 作为基线分支。之所以不用release-pre 或者 release 作为上线分支,是因为上线当天经常因为各种原因导致只有部分feature是可以上线的。上线当天创建 release-20220818 并部署到Pre,如果验证通过直接部署上线,如果部分上线,则直接丢弃,再创建一个新的上线分支即可,避免污染 release

提交规范

提交代码时,务必填写提交日志,日志清晰明了,说明本次提交的目的。同时需要遵循一定的提交规范。

<type>(<scope>): <subject> 
复制代码
  1. Header:包括三个字段:type(必需)、scope(可选)和subject(必需)。
  2. Type:提交commit的类别,建议使用下面标识
  • feat: 加入新特性
  • fix: 修复bug
  • improvement: 在现有特性上的改进
  • docs: 更改文档
  • style: 修改了代码的格式
  • refactor: 代码重构,不包含bug的修复以及新增特性
  • perf: 提升性能的改动
  • test: 测试用例的改动
  • build: 改变了构建系统或者增加了新的依赖
  • ci: 修改了自动化流程的配置文件或者脚本
  • chore: 除了源码目录以及测试用例的其他修改
  • revert: 回退到之前的一个commit
  1. Scope:用于说明 commit 影响的范围,默认可忽略。
  2. Subject:简短精炼的提交描述。

五、超实用技巧

场景一

如果我们正在开发一个功能,突然告知有线上问题,我们做了一半的代码如何保存

# 缓存本地开发文件 
git stash
    
# 取出最后一条缓存记录并删除
git stash pop
    
# 查看所有缓存列表
git stash list
    
# 应用某一条缓存
git stash apply stash@{index}
复制代码
  1. 使用 git stash 可以临时存储本地所有变动的文件,并从当前分支删除修改的代码。
  2. 切换到 release 创建 hotfix-xxx 修复问题。
  3. 切换到 feature/xxx ,执行 git stash pop 还原刚刚开发的代码。

一切都像没发生一样,很丝滑。

场景二

release-pre 合并了 5 次提交,最终QA反馈只有一个功能对应的2次提交可以上线,我们如何把其中 2 次提交代码合并到release?

  • 方法一:把需要上线的功能分支直接合并到 release 进行上线。
  • 方法二:使用`git revert 回滚其中不必要的提交。
  • 方法三:使用git cherry-pick挑选需要的提交进行合并。
# 把某一次提交应用到当前分支
git cherry-pick <commit-hash>
    
# 把某几次提交应用到当前分支
git cherry-pick <commit-hash> <commit-hash>
    
# 把某个区间的提交应用到当前分支,注意不包含起始提交
git cherry-pick <start-commit>..<end-commit>
复制代码

如上图,如果想要挑选 4 和 5 的提交代码到 feature/order 分支,则执行:git cherry-pick 0c20eb75..6938e5e0 即可,注意不包含起始提交,左开右闭

场景三

某需求做完以后,提测的时候通过 git log 发现 feature/order 分支有无数的提交记录,如下图,如何在提测的时候,让提交日志更干净

通过git rebase -i <start-commit> <end-commit>

  1. 执行命令,弹出交互式界面
git rebase -i 6938e5e0
复制代码

  1. 修改指令

我们只需要把最后三次提交的pick指令改为squash或者fixup即可,更多参数可参考如下:

  • pick:保留该commit(缩写:p)
  • reword:保留该commit,但我需要修改该commit的注释(缩写:r)
  • edit:保留该commit, 但我要停下来修改该提交(不仅仅修改注释)(缩写:e)
  • squash:将该commit和前一个commit合并(缩写:s)
  • fixup:将该commit和前一个commit合并,但我不要保留该提交的注释信息(缩写:f)
  • exec:执行shell命令(缩写:x)
  • drop:我要丢弃该commit(缩写:d)
  1. 输入 :wq 保存后,会进入到从新修改提交日志界面

  1. 我们只需要删除这些日志,从新输入我们本次功能开发的日志即可:

  1. 再次输入::wq 保存退出即可,最后查看日志如下:

这个世界真的很美好!!!

场景四

多人协作时,分支提交错综复杂,如何让分支提交变的更加线性?

现实是这样的?

使用 rebase 变基前后对比

已知线上分支 release 和 功能分支 feature/order ,当功能分支开发的同时,release 也同步做了修改(hotfix合并进来),此时我们通过 rebase 进行变基

# 切换到功能分支
git checkout feature/order
    
# 执行变基
git rebase release
复制代码

相当于临时保存 feature/order 分支代码,从新拉取 release 最新代码到本地,然后把 feature/order 合并进来,这个过程称之为变基,如果中间发生冲突,我们需要正常处理冲突,处理完以后,使用 git add .添加到暂存区,使用git rebase --continue继续执行,直到所有冲突解决完为止。如果中途想要放弃,可使用 git rebase --abort 进行终止。

git merge 是以提交的时间为先后顺序,而 git rebase 不同, release 代码提交在前,功能分支提交在后,哪怕功能分支先提交的也不行。

以上就是给大家准备的Git指北,看完如果有问题可以在评论区留言,如果感觉有帮助,请点个赞,最后附上一张我收藏多年的宝藏图。


作者:HuolalaFE
链接:juejin.cn/post/712263… 来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。