大厂程序员讲解Git开发流程和回退

fork开发模式

因为项目都是多人开发,所以一般都是采用的fork模式进行开发,也就是程序员们先把修改提交到自己fork的仓库,然后在这个仓库的某个分支上进行项目的仓库分支的merge request,一般是向develop分支发起合并。

首先我们会对主仓库进行fork,有一个个人版本的仓库,还有一个项目的仓库。在本地进行git的配置,一般会把两个远程仓库都配上(origin repo + your repo),至于为什么会这么做,我们后面再说。

下文用origin来代表项目仓库,yourrepo来代表你fork的仓库。因为涉及到内部信息和系统,所以不会有截图,全文都是文字和具体命令。

使用分支管理开发

通常,企业内部会有一个需求单系统,需求在这个系统上发布,在实现需求的时候会将某个分支绑定上,这样就可以很容易追踪一个需求到底是如何实现的,进行了哪些修改。并且能够自动绑定分支的提交信息和流转状态等等。

作为一个程序员,我们的视角应该是这样的。

  1. 接到一个需求
  2. 打算进行开发
  3. git checkout develop 回到develop分支,这应该是我们开发时每一次需求的根分支,要保持这个分支和远程仓库的同步。
  4. git pull origin master 拉取一下最新的代码,pull命令就是fetchmerge的组合命令。fetch用来获取远端仓库该分支最新的修改,merge用来和你的本地分支进行合并,这样就能保持decelop的干净状态、和远端项目永远是同步的。一般来说master分支是比较稳定的最新代码,这样只之后提交发生冲突的概率比较低。如果你们的项目是c端的频繁发布的产品,那么git pull origin release可能更符合你们的情况。
  5. git checkout -b branchname,基于这个干净的develop分支代码和记录,生成一个新的分支,在这个分支上进行开发。
  6. 将分支与需求进行绑定。
  7. 进行开发和单元测试,测试无误之后准备提交代码。
  8. git add filenames,这里把工作目录下的文件添加到暂存区,禁止使用 git add . 提交全量
  9. git commit -m "msg",这里提交到本地仓库,也就是在branchname这个分支上进行了某些修改,本地已经有记录了,但是还没有同步到远程代码仓库。commit信息有特定的规范,一般像下面一样,以行为类型开头,括号包裹模块,附上简单信息,description中附加详细信息或测试结果。feat (project): 1.添加xx表 2.添加xx功能
  10. git fetch origin,再次获取最新的代码仓库信息。
  11. git rebase -i origin/develop,这里向最新的仓库develop分支进行基准,合并到origin/develop分支上,补全缺失的历史记录,注意,rebase操作的本质上,把你本地分支branchname的修改应用到develop分支上,它会找到这两个分支最近的一次公共祖先,然后把a对于develop缺失的历史记录打一系列的补丁,再在分支前方生成一个新的点,让这次提交是develop的最新提交,从而让develop提交记录是一条线。注意:rebase是会更改历史sha-1值的,因为更改了a分支的历史提交记录。
  12. git push yourrepo develop,进行提交。如果需要多次提交的话,之后需要-f或者--force-with-lease这种比较安全的强制提交。因为rebase会修改记录,所以想多次提交必须强制执行,这也是分支管理开发最不方便的一点。
  13. 发起merge-request,这里会比较你更改的这些文件和原仓库对应文件的区别,一般不会有问题。偶尔如果你和同事一起修改了某一个文件,会产生冲突,这时候你需要处理冲突,重复上述add commit push的操作就ok了。
  14. 更改需求状态,完成需求。

一条分支走到底

上面那一种使用分支管理进行开发是比较规范的开发过程,但是诟病有两个。

  1. 同一时刻只能进行一个功能的开发,如果需要切换到其他功能的开发,需要git stash,然后完成之后再git stash pop重新开发。当然stash也不是万能的,如果需要你先commit提交某些修改,再进行新功能的开发,往往就不是很方便。
  2. 一个分支进行rebase + push之后,想要再次提交就必须强制执行,这是比较危险的操作,如果想要安全执行的话又需要创建新分支add + commit + rebase + push,对于需求单和程序员都不够友好。

所以在某些时候,使用单分支进行开发能解决一部分问题,即一条分支走到底,多个功能复用一个分支进行开发,甚至所有功能都在这个分支上进行开发。

这样会比较简单,上述内容的git pull + add + commit + push + merge request就是开发过程的全流程了。

远程开发同步问题

现在开发机环境和本地通常是隔离的,也就是说我们必须在本地IDE连接上开发机,才能拥有开发机的网络和测试环境。

这时候我们就有两套代码,一套是在本地IDE供我们编辑和修改的,一套是在开发机上测试执行的,我一般是这么同步的。

  1. 开启auto upload功能,每次进行修改自动推到远端开发机上。
  2. 在开发机上推代码,维护开发机的git、代码和分支永远是干净的。
  3. 在开发机上推完代码之后,本地的git环境就会有很多已修改的文件,这时候我们再把远端开发机的.git仓库download过来。
  4. 完成一个需求开发之后,本地和远端开发机的文件以及git状态应该是一致的,分支无需一致,因为本地不用推代码。

Git回退

因为git将从开始工作 到提交到远程仓库存储分成了四部分,即我们都知道的工作区、暂存区、本地仓库和远程仓库,所以回退应该也有四种,分别是

  • 取消工作目录的修改
  • 取消暂存区的修改
  • 取消本地仓库的修改
  • 取消远程仓库的修改

取消工作区: git checkout filename,会把文件的状态回滚到最近一次提交,和ide提供的git rollback功能是一样的,一般是我们不想要某个文件的修改时使用。

取消暂存区: 有时候我们修改了很多文件,有一些文件不应该是这次提交,但是不小心git add了,这时候我们应该通过git reset filename进行重置,让这个文件从暂存区移除,reset命令有三种模式,--soft--hard--mixed,默认是--mixed

三者的区别如下

  • mixed:只有暂存区变化,也就是add之后,我们使用git reset filename,不会改变文件的修改,但是会把它从我们的暂存区移出去。
  • soft:回溯到某个节点,不会影响工作区和暂存区。比如我们commit了三次,然后git reset --soft commit1id,这个时候本地仓库分支就回退到了commit1的时候,但是本地工作区代码还是commit3时的代码。
  • hard:和soft相反,会影响工作区,git reset --hard commit1id,这个时候本地仓库分支就回退到了commit1的时候,但是本地工作区代码也变成了commit1时的代码。

取消本地仓库

某些时候我们可能编写了一些不合时宜的代码,里面有bug或者不需要,但是这些代码以及被commit到了本地仓库,这时候我们对它们回滚就需要用到git resetgit revert这两个方法。

上面已经说过了reset,就是把HEAD指针移到之前的某个修改,并且可以选择保存工作区代码或者丢弃。

另一个选择是revert,这个命令和reset来说刚好相反,它是生成一个新的commit节点,这个节点的内容就是撤销某一次提交,历史commit记录会被保存,撤销的这一次commit记录也会保存,刚好和reset相反。

git revert HEAD用来回退一次版本,git revert HEAD^回到上上一次。

取消远程

其实就是在取消本地仓库 的基础上push一下推到远端,如果是reset取消,那么需要-f,因为修改了分支历史;但是如果是revert,则直接推就可以,并没有修改分支历史,而是多了一个撤销某一次提交的记录。

推荐阅读

当说到云原生时,我们究竟在谈论什么? - 掘金

不太熟悉Git? 不妨看看这篇文章 - 掘金

一文搞定常见分布式事务实现 - 掘金

你真的理解分布式理论吗? - 掘金

深入了解异地多活 - 掘金

02.K8S架构详解 - 掘金

01.你为什么需要学习K8S - 掘金

相关推荐
2401_857622667 小时前
SpringBoot框架下校园资料库的构建与优化
spring boot·后端·php
2402_857589367 小时前
“衣依”服装销售平台:Spring Boot框架的设计与实现
java·spring boot·后端
哎呦没8 小时前
大学生就业招聘:Spring Boot系统的架构分析
java·spring boot·后端
_.Switch9 小时前
Python Web 应用中的 API 网关集成与优化
开发语言·前端·后端·python·架构·log4j
杨哥带你写代码10 小时前
足球青训俱乐部管理:Spring Boot技术驱动
java·spring boot·后端
AskHarries11 小时前
读《show your work》的一点感悟
后端
A尘埃11 小时前
SpringBoot的数据访问
java·spring boot·后端
yang-230711 小时前
端口冲突的解决方案以及SpringBoot自动检测可用端口demo
java·spring boot·后端
Marst Code11 小时前
(Django)初步使用
后端·python·django
代码之光_198011 小时前
SpringBoot校园资料分享平台:设计与实现
java·spring boot·后端