Git工作必看
# Git工作必看
# 一些概念
在git中常常会有多个分支,每种分支代表不同的用途,在进行日常办公时,你需要谨记,这样方便按流程来,从而实现代码的可控可回退,提高发布的安全性。
master(github中是 main):主分支 =>用于线上发版开发:
develop:开发分支
feature: 功能开发 =>开发新功能
Release:预发布版本=>用于测试
hotfix:修复补丁=>用于修复master上的bug
当然每个公司的规定可能不同,但大体上是相近的。
# 指定提交
假如你本地commit了多次,但你只想push其中一次,该怎么操作?
可以使用
git reset --mixed <commit>
具体的效果在重置提交中有说明。
# 重置提交
假如你push了多次,结果突然发现,你应该只push其中某一次,此时该怎么做呢?
比如:你push了3次,按时间先后,依次为 a1,a2,a3,但现在你发现a2,a3都是错误的,不应该提交,只用提交a1即可。
这是你就可以使用git reset
这个指令了。
# git reset
# --soft
在 Git 中,重置提交(git reset
)是指将当前分支的 HEAD 指针移动到指定的提交,并根据选项调整工作目录和暂存区的状态。git reset
是一个非常强大的命令,但也是比较复杂的命令之一,因为它有多种模式和用途。以下是 git reset
的几种常见用法及其解释:
git reset --soft <commit>
- 作用:将 HEAD 移动到指定的提交,但不会改变工作目录和暂存区的内容。所有在原 HEAD 和目标提交之间的更改都会保留在暂存区。
- 适用场景:当你想要取消最近的几次提交,但保留这些更改以便重新提交时。
比如:
git reset --soft HEAD~1
# 这条命令会取消最近的一次提交,但所有更改仍然在暂存区中,你可以继续编辑提交信息或添加更多更改后再次提交
2
只是push被取消了,对应的add没收影响。
# --mixed
git reset --mixed <commit>
- 默认模式,如果未指定模式,则默认为
--mixed
。 - 作用:将 HEAD 移动到指定的提交,工作目录保持不变,但暂存区会被重置为目标提交的状态。也就是说,所有在原 HEAD 和目标提交之间的更改都会从暂存区移出,回到工作目录中。
- 适用场景:当你想要取消最近的几次提交,并且需要重新选择哪些更改要暂存时。
以下是一个例子:
git reset --mixed 3e30c164
这个命令的作用是将当前分支的 HEAD(即指针)移动到指定的提交 3e30c164
,同时保留工作目录中的文件不变,但重置暂存区(即索引)。
- HEAD:指向了提交
3e30c164
。 - 暂存区(Index):被重置为
3e30c164
的状态。任何在3e30c164
和之前 HEAD 指向的提交之间的更改都会从暂存区移除,不再准备提交。 - 工作目录(Working Directory):保持不变。你的文件仍然会显示最新的修改,即使这些修改已经被从暂存区移除。
简单的说即为:3e30c164,之后的提交取消,且对应的文件都从暂存区释放,需要重新add。
# --hard
git reset --hard <commit>
- 作用:将 HEAD、工作目录和暂存区都重置为目标提交的状态。所有在原 HEAD 和目标提交之间的更改都将被丢弃。
- 适用场景:当你确定要放弃最近的几次提交以及所有相关的更改时。
以下是几个例子:
git reset --hard HEAD~1
# 这条命令会取消最近的一次提交,并且所有更改都会被永久删除,无法恢复。请谨慎使用此命令,特别是在共享分支上操作时。
git reset --hard 3e3ff164
# 3e3ff164 本次之后的提交都会取消,无法恢复
2
3
4
5
所以,对于hard模式,请一定谨慎使用。
# --hard 注意事项
--hard
模式危险:git reset --hard
会永久删除未提交的更改,请确保你确实不再需要这些更改。- 影响范围:
git reset
只影响当前分支的 HEAD 指针。如果你在多个分支之间切换并重置,其他分支不会受到影响。 - 远程仓库:如果你已经将更改推送到远程仓库,使用
git reset
后可能需要强制推送 (git push --force
),但这可能会覆盖其他人的更改,因此在团队协作中应非常小心。
# 回滚提交
在 Git 中回滚版本(即撤销更改或恢复到之前的某个状态)是一个非常常见的操作,它有多种原因和应用场景。以下是一些主要的原因:
修复错误:
- 引入了Bug:如果最近的提交引入了新的 Bug 或者破坏了现有功能,你可以选择回滚到一个已知稳定的状态,以便快速修复问题。
- 配置错误:有时会不小心提交了不正确的配置文件或其他不应该包含在版本库中的敏感信息,这时需要回滚来移除这些更改。
探索创新:
- 尝试新特性或改进:开发者可能希望尝试某些新特性、优化或者架构调整,但不确定最终效果如何。通过创建临时分支进行开发,并在必要时回滚,可以避免对主代码库造成影响。
- 探索性编程:有时候开发者会在本地环境中做一些实验性的改变,之后发现这些改动并不适合当前项目,这时就可以简单地回滚到之前的状态。
紧急修复:
- 紧急修复:当生产环境出现问题时,迅速回滚到一个稳定版本可能是最快捷的方式,确保服务尽快恢复正常运行。
- 安全漏洞:如果发现了一个严重的安全漏洞,可能需要立即回滚到漏洞被引入之前的版本,并从那里开始修补工作。
# 回滚的方法
根据具体情况,Git 提供了几种不同的方式来回滚版本,包括但不限于:
git revert
:创建一个新的提交来撤销指定的旧提交,不会改变历史记录。git reset
:移动 HEAD 指针,可以选择保留或丢弃工作目录和暂存区的更改。git checkout
:切换到另一个分支或特定的提交,也可以用来恢复单个文件的历史版本。
# git revert
git revert
是 Git 中用于撤销更改的一个非常有用的命令。与 git reset
不同,git revert
并不会改变提交历史,而是通过创建新的提交来撤销指定的旧提交。这种方式使得项目的历史记录保持完整,并且可以安全地在公共分支上使用,因为不会重写已有的提交。
git revert <commit>
或者要撤销一系列连续的提交:
git revert <first-commit>~..<last-commit>
git revert HEAD~3..HEAD
# 撤销最近的三个提交
git revert 3e3ff164
# Git 将生成一组与 3e3ff164 相反的更改(即如果 3e3ff164 添加了某些行,则 revert 操作将删除这些行;如果 3e3ff164 删除了某些行,则 revert 操作将恢复这些行)
# 然后 Git 会创建一个新的提交,这个提交包含了与 3e3ff164 相反的更改
git revert 3e3ff164 a1b2c3d4
2
3
4
5
6
7
8
9
10
# 合并
关于合并主要有2种:
- git merge
- git rebase
- git cherry-pick
其中第三个,cherry-pick,你可能很少用到,但它的功能却很有效。
在Git中,cherry-pick
命令的作用是从一个分支中选取特定的提交(commit),然后将这些提交应用到当前分支上。这个操作不会合并整个分支,而只是挑选出你指定的一个或多个提交。合并后,当前分支分支会生成新的commit,cherry-pick几个commit,就会生成几个新的commit(但它们与原来的hash值是不同的)。
以下是cherry-pick
的一些常见使用场景:
- 选择性地应用修复:如果你在一个分支上做了几个提交,其中有一个是bug修复,而你想把这个修复应用到另一个分支而不带入其他更改,这时就可以用
cherry-pick
来单独挑出这个修复的提交。 - 避免不必要的合并:当你只需要某个分支上的某些提交时,你可以用
cherry-pick
来避免合并整个分支所带来的所有更改。
# cherry-pick
对于单个commit,你可以使用如下命令,
git cherry-pick <commit>
对于多个commit,也比较简单,只需要在每个commit之间用空格分隔开即可:
git cherry-pick <commit> <commit> <commit>
如果要应用多个连续的提交,可以使用范围,例如
git cherry-pick <first-commit>^..<last-commit>
需要注意的是,cherry-pick
可能会导致冲突,尤其是在所选提交和当前分支之间存在差异的情况下。发生冲突时,Git将暂停cherry-pick
过程,让用户解决冲突,之后可以通过git cherry-pick --continue
继续操作,或者用git cherry-pick --abort
来取消整个cherry-pick
操作。
# 工作流
还记得开头说的那些概念吗,这里就要用到了。
下面介绍一些实际的开发流程:
# 首先开发新功能
- 首先拉取远程仓库到本地,然后创建一个对应的功能分支:
% git checkout -b fire
Switched to a new branch 'fire'
%
2
3
- 完成开发后,进行add,然后commit,然后进行push
- 但,这时候,请注意,你的远程分支是没有所谓的
fire
分支的,此时怎么办呢?
你可以使用以下命令(如果你在 fire分支上):
git push --set-upstream origin fire
# 这个命令的作用是将本地的当前分支推送到远程仓库 origin 的 fire 分支,并且设置一个上游跟踪关系
# 以下是简写形式
git push -u origin fire
2
3
4
origin
:这是远程仓库的名称,默认情况下指向你在 GitHub、GitLab 等平台上创建的远程仓库。fire
:这是你想要推送到远程仓库的分支的名称。远程如果没有,则新建对应分支
这之后,任何时候你在 fire
分支上做更改并想推送这些更改,只需执行:
git push
# 更新
git pull
2
3
# 继续开发一个新功能
接下来又要开发一个新功能,又从本地分支master,创建一个新分支继续开发:
% git checkout -b func
Switched to a new branch 'func'
%
2
3
然后重复上述操作。完成对应开发后,push到远程。
# 完成后的release推送
完成所有功能需求的开发后,要把他们合体,然后再次推送:
git checkout -b release
然后把fire 和 func合并到release分支中:
git merge origin/fire
# 将远程仓库 origin 中的 fire 分支合并到当前的 release 分支
git merge origin/func
# 完成后 ,push
git push -u origin release
2
3
4
5
6
最后,由管理员在仓库对release的pr,进行merge到main(或master)即可。
# 扩展
假设你在 release
分支上工作,并且想要合并来自本地的 feature
分支:
git checkout release
git pull origin release # 确保本地 release 分支是最新的(如果适用)
git merge feature # 合并 feature 分支的更改
2
3
# 一些工作流展示
以下是其他人的工作流展示
公司A:
三个环境
dev(开发环境)冒烟测试 ->发送提测邮件
test(测试环境》测试完成的邮件 发送一个上线邮件抄送各大领导人
master(生产环境)晚上10点多
feature-1.0.0(开发分支) -平时写代码的分支
feature-2.4.3(开发分支)
devhotfix-2.4.3(热补丁)
T0 级别bug 用户阻塞级别bug 两小时之内修复 全部门通报扣钱
# 打tag
在工作中,有时还要求我们要对某次提交打tag,如何实现呢?
首先,你需要知道,在 Git 中,给提交打标签(tag)是一种标记特定提交点的方法,通常用于标识发布版本或其他重要的历史点。
你可以为当前提交打标签,也可以为已经存在的提交打标签。以下是两种情况下如何操作的详细步骤。
# 提交代码时打标签
如果你希望在提交代码的同时创建一个标签,可以使用 git commit
和 git tag
的组合。不过,Git 并不直接支持在 git commit
命令中同时创建标签,因此你需要分两步走:
首先,正常提交你的更改。
git commit -m "your commit message"
然后为该次commit打tag。
git tag v1.0
以上为轻量级标签。
如果你想创建一个带注释的标签(推荐做法,因为它包含了更多元数据),可以使用 -a
参数,并提供标签信息:
git tag -a v1.0 -m "Version 1.0 release"
最后,为commit进行push,同时还要为你的tag进行push(一共要进行2次,因为 在 Git 中,标签(tags)和分支(branches)是分开管理的实体。)
git push origin v1.0
# 推送单个标签
2
# 对已经提交的提交打标签
如果你已经有一个或多个提交,并且想为这些提交中的某一个打标签,你可以根据该提交的哈希值来创建标签。
找到要打标签的提交: 使用 git log
查看提交历史,找到你想要打标签的提交的哈希值。
git log --oneline
创建标签: 使用 git tag
命令和指定的提交哈希值来创建标签。例如,如果你想为提交 abc1234
打上标签 v2.0
:
git tag v2.0 abc1234
# 以下是带标签的注释
git tag -a v2.0 abc1234 -m "Version 2.0 release"
2
3
4
- 推送标签:不要忘记将标签推送到远程仓库,否则其他开发者将无法看到这些标签。
- 查看标签:你可以使用
git tag
命令列出所有的标签,或者使用git show <tag>
来查看特定标签的信息。
# 推送标签到远程仓库
无论你是为新的提交还是旧的提交打标签,一旦标签创建完成,都需要将其推送到远程仓库,以便其他开发者也能看到这些标签。
- 推送单个标签:
git push origin v1.0
- 推送所有标签:
git push origin --tags
你可以通过如下命令来看是否推送成功:
git ls-remote --tags origin