• 各种场景下的Git管理方法


    本文着重列举开发过程中自己遇到过的各种场景以及用法,不再阐述Git的基础

    基本操作

    git add .
    git commit -m "修改备注"
    git push -u origin main
    

    1.本地关联远程仓库

    在本地已经建立仓库,或者已有多次提交,后来需要提交到远程的仓库,这时候就需要把本地与远程库存关联

    git remote add origin https://github.com/SpringUE/xform.git
    
    # 关联操作
    git remote rm name  # 删除远程仓库
    git remote rename old_name new_name  # 修改仓库名
    

    2.多环境策略

    大型项目中,多人协同,快速更新迭代,无法避免多特性同时开发,甚至边开发边修复UAT问题、生成问题。
    以develop分支做基线,SIT环境使用,UAT环境使用release分支,生产环境使用master

    • 合入顺序: develop --> release --> master
    • 修改生产问题同步推送到release && develop
    • 修改UAT问题同步推送到develop

    ::: warning
    Tips
    修改UAT、生产问题务必同步向前推送到develop,否则修改的越多最终越难合并,多人协同特别注意
    :::

    3.本地多分支开发调试

    现代项目几乎大多数后端都微服务化,前后端分模块分人联调,这些都是常见的事。
    管理多套完整代码,主要用到stash命令的功能

    stash 命令能够将还未 commit 的代码存起来,让你的工作目录变得干净。

    git stash # 保存当前未commit的代码
    git stash save "备注的内容" # 保存当前未commit的代码并添加备注
    git stash list # 列出stash的所有记录
    git stash clear # 删除stash的所有记录
    git stash apply # 应用最近一次的stash
    git stash pop # 应用最近一次的stash,随后删除该记录
    git stash drop # 删除最近的一次stash
    
    # 当有多条 stash,可以指定操作stash,首先使用stash list 列出所有记录:
    $ git stash list
    stash@{0}: WIP on ...
    stash@{1}: WIP on ...
    stash@{2}: On ...
    
    # 应用第二条记录:
    $ git stash apply stash@{1}
    
    # pop,drop 同理。
    

    不同的环境、不同的模块接口人,在前端联调的时候需要临时性设置联调参数,例如:环境地址、微服务代理地址等。
    这些代码仅在本地某个分支联调过程中临时存在,并不会提交推送,则使用stash可保存个联调场景需要的临时代码,切换时将这部分代码暂存起来,下次切换回来后换出即可。

    4.撤回提交

    经常因为操作太快导致误提交,reset --soft命令,它能让 commit 记录强制回溯到某一个节点,修改的内容都回到暂存区。

    # 恢复最近一次commit
    git reset --soft HEAD^
    
    # reset 到某一次commit
    git reset --soft 5b62bybx2wxci1x7422hdhh9my374tf6hj9ynx
    

    ::: warning
    Tips
    以上说的是还未 push 的commit。对于已经 push 的 commit,也可以使用该命令,不过再次 push 时,由于远程分支和本地分支有差异,需要强制推送 git push -f 来覆盖被 reset 的 commit。
    值得注意的是,在 reset --soft 指定 commit 号时,会将该 commit 到最近一次 commit 的所有修改内容全部恢复,而不是只针对该 commit
    举个栗子:
    commit 记录有 c、b、a
    reset 到 a
    此时的 HEAD 到了 a,而 b、c 的修改内容都回到了暂存区
    :::

    reset --soft 总的来说是给你有可以再次修改重新提交的机会,保持干净的 commit 记录。

    5.挑拣提交的内容

    场景1:经常在改sit环境BUG问题单的时候,uat同时发现了某个同样的问题,然而因为环境之间不同步,这时候就需要把某个或某些 commit 挑拣出来,单独合入release_uat分支

    场景2:有时候一大波需求开发结束准备上uat,但由于某些原因导致某些特性不能及时上线,则把N多个特性 commit 中抽取部分commit 到新的分支

    cherry-pick 挑拣代码

    挑拣多个提交应用到当前分支:

    git cherry-pick commit1 commit2
    

    挑拣多个连续的commit,也可区间复制:

    git cherry-pick commit1^..commitN
    

    上面的命令将 commit1 到 commitN 这个区间的 commit 都应用到当前分支(包含commit1、commitN),commit1 是最早的提交。

    cherry-pick 代码冲突

    在 cherry-pick 挑拣多个commit时,可能会遇到代码冲突,这时 cherry-pick 会停下来,让用户决定如何继续操作。下面看看怎么解决这种场景。

    还是 feature 分支,现在需要把 c、d、e 都复制到 release 分支上。先把起点c和终点e的 commitHash 记下来。

    切到 release 分支,使用区间的 cherry-pick,可以看到 c 被成功复制,当进行到 d 时,发现代码冲突,cherry-pick 中断了。这时需要解决代码冲突,重新提交到暂存区。

    然后使用 cherry-pick --continue 让 cherry-pick 继续进行下去。最后 e 也被复制进来,整个流程就完成了。
    以上是完整的流程,但有时候可能需要在代码冲突后,放弃或者退出流程:

    放弃 cherry-pick

    gits cherry-pick --abort
    

    取消操作,就像什么都没发生过。

    退出 cherry-pick:

    git cherry-pick --quit
    

    不回到操作前的样子。即保留已经 cherry-pick 成功的 commit,并退出 cherry-pick 流程。

    6.还原普通提交

    revert 给定一个或多个现有提交,恢复相关提交引入的更改,并记录一些这些更改的新提交。这就要求你的工作树是干净的(没有来自头部的修改)。
    将现有的提交还原,恢复提交的内容,并生成一条还原记录。

    现在 master 记录如下:

    git revert 5b62bybx2wxci1x7422hdhh9my374tf6hj9ynx
    

    revert 掉自己提交的 commit。

    因为 revert 会生成一条新的提交记录,这时会让你编辑提交信息,编辑完后 :wq 保存退出就好了。

    再来看下最新的 log,生成了一条 revert 记录,虽然自己之前的提交记录还是会保留着,但你修改的代码内容已经被撤回了。
    revert 合并提交
    在 git 的 commit 记录里,还有一种类型是合并提交,想要 revert 合并提交,使用上会有些不一样。

    现在的 master 分支里多了条合并提交。

    使用刚刚同样的 revert 方法,会发现命令行报错了。
    为什么会这样?在官方文档中有解释。

    通常无法 revert 合并,因为您不知道合并的哪一侧应被视为主线。此选项指定主线的父编号(从1开始),并允许 revert 反转相对于指定父编号的更改

    我的理解是因为合并提交是两条分支的交集节点,而 git 不知道需要撤销的哪一条分支,需要添加参数 -m 指定主线分支,保留主线分支的代码,另一条则被撤销。
    -m 后面要跟一个 parent number 标识出"主线",一般使用 1 保留主分支代码。

    git revert -m 1 <commitHash>
    

    revert 合并提交后,再次合并分支会失效
    还是上面的场景,在 master 分支 revert 合并提交后,然后切到 feature 分支修复好 bug,再合并到 master 分支时,会发现之前被 revert 的修改内容没有重新合并进来。
    因为使用 revert 后, feature 分支的 commit 还是会保留在 master 分支的记录中,当你再次合并进去时,git 判断有相同的 commitHash,就忽略了相关 commit 修改的内容。
    这时就需要 revert 掉之前 revert 的合并提交,有点拗口,接下来看操作吧。

    现在 master 的记录是这样的。

    再次使用 revert,之前被 revert 的修改内容就又回来了。

    7.管理重录中记录的信息

    官方文档描述:
    此命令管理重录中记录的信息。

    如果说 reset --soft 是后悔药,那 reflog 就是强力后悔药。它记录了所有的 commit 操作记录,便于错误操作后找回记录。
    应用场景
    应用场景:某天你眼花,发现自己在其他人分支提交了代码还推到远程分支,这时因为分支只有你的最新提交,就想着使用 reset --hard,结果紧张不小心记错了 commitHash,reset 过头,把同事的 commit 搞没了。没办法,reset --hard 是强制回退的,找不到 commitHash 了,只能让同事从本地分支再推一次(同事瞬间拳头就硬了,怎么又是你)。于是,你的技术形象又一落千丈。
    命令使用

    分支记录如上,想要 reset 到 b。

    误操作 reset 过头,b 没了,最新的只剩下 a。

    这时用 git reflog 查看历史记录,把错误提交的那次 commitHash 记下。

    再次 reset 回去,就会发现 b 回来了。
    设置 Git 短命令
    对我这种喜欢敲命令而不用图形化工具的爱好者来说,设置短命令可以很好的提高效率。下面介绍两种设置短命令的方式。
    方式一
    git config --global alias.ps push

    方式二
    打开全局配置文件
    vim ~/.gitconfig

    写入内容
    [alias]
    co = checkout
    ps = push
    pl = pull
    mer = merge --no-ff
    cp = cherry-pick

    使用

    # 等同于 git cherry-pick 
    git cp <commitHash>
    
  • 相关阅读:
    网址导航收藏引导页面H5源码(自适应引导页HTML源码)-自动检测域名延迟
    回顾大一|我们要做的是提前准备,而不是提前焦虑
    Paxos 算法详解
    25.10 MySQL 约束
    minio安装以及使用
    vue中用ref实现父子组件、孙组件、兄弟组件、非亲子孙组件互相调用的方法
    资源:加快进入区块链的5种最佳编程语言
    web前端tips:js继承——原型式继承
    扫描线及其应用
    Jmeter常用函数用法详解
  • 原文地址:https://blog.csdn.net/spring5530/article/details/127040334