Git
Git操作
如何构建新分支
首先克隆仓库,创建自己的分支,修改代码后提交,提交时设置上游分支,之后在该分支开发。
git clone <repository_url>
git checkout -b mybranch
git status
git add .
git commit
git push -u origin mybranch
新分支合并到主分支,通常来说如果commit比较少,小于2可以直接rebase,多了就直接merge便于回滚。
新分支与主分支的合并问题
- 如果主分支没有改动,仅新分支改动,则只需要在主分支执行
git merge newbranch即可。 - 如果主分支有改动,但改动位置与新分支改动位置不一样,则只需要在新分支执行
git merge main即可,这样就会把主分支改动内容增加到新分支且保留新分支改动内容,再到主分支中执行git merge newbranch即可。 - 如果主分支和新分支改动了相同位置,则需要在新分支执行
git merge main并手动解决冲突,IDE有解决冲突的视图,终端操作需要手动处理冲突,再使用git add该文件并提交,解决冲突之后再到主分支中执行git merge newbranch即可。
如何将修改合并到上一次提交
如果提交后oci没有通过,或者发现了一些代码中的小错误,可以修改代码后
既然你不想增加新的提交(Commit),最优雅的办法就是**“原地修正”**。
你只需要把格式修复好,然后用 git commit --amend 把这些修改“塞进”上一个提交里。
-
重新暂存(Stage)这些文件:
告诉 Git,你已经把这几个文件修好了。
git add ./src/*** -
合入上一个提交(核心步骤):
执行以下命令,它会把刚才
add的内容合并到你最新的那个提交中,且不改变提交信息:git commit --amend --no-edit--amend:表示修改上一次提交。--no-edit:表示沿用之前的提交信息,不弹出编辑器。
-
强制推送(如果是第一次推送失败后):
如果你之前已经尝试
push过(虽然报错了),或者你想覆盖远程那个“坏”的提交:git push --force-with-lease注意:
--force-with-lease比普通的-f更安全,它会检查远程是否有别人提交的代码,防止不小心覆盖掉同事的工作。
如果提交后感觉commit信息写的不好,这里分两种情况,取决于你要改的是哪一次提交:
情况一:只想修改“最后一次”提交信息
这是最常见的场景。
-
执行修改命令:
git commit --amend -m "这是你新的提交信息"
*如果你不带 `-m` 参数,Git 会打开编辑器让你修改。*
2. **强制推送到远程**(因为提交 ID 改变了):
```bash
git push --force-with-lease
情况二:想修改“更早之前”的提交信息
如果你想修改的不是最近的那次,而是往回数第 2 次或第 3 次,就需要用到 交互式变基 (Interactive Rebase)。
-
进入交互模式(假设要修改最近 3 次内的某一个):
git rebase -i HEAD~3 -
在编辑器中操作:
-
你会看到类似这样的列表:
-
pick a1b2c3d 功能开发 1 pick e4f5g6h 功能开发 2 pick i7j8k9l 功能开发 3
- 将你想修改的那一行前面的 `pick` 改为 `reword`(或者简写为 `r`)。
- 保存并退出编辑器。
3. **修改内容**:
- Git 会自动弹出新的编辑器,让你输入新的提交信息。改好后保存退出。
4. **强制推送**:
```bash
git push --force-with-lease
⚠️ 核心注意事项
- 不要修改已合并的代码:如果你的分支已经合并到了
master或者有其他同事正在基于你的这个分支开发,千万不要修改已经 push 的 Commit 信息。这会破坏他们的提交历史。 - 文件真的没变吗?:执行
git commit --amend时,Git 会把你当前暂存区 (Staging Area) 里的所有变动都塞进去。如果你想“只改信息”,请确保执行命令前git status显示没有待提交的文件修改。
多次重复提交如何合并
有时候需要一点一点修改代码测试,最终得到一个版本,之前的提交记录就可以合并,称为squash操作。如何想留下最新版本:
git rebase -i HEAD~n
执行 git rebase -i HEAD~n 后,Git 会显示一个提交列表,其中包含 n 个提交:
pick abc1234 Commit message 1
pick def5678 Commit message 2
pick ghi9012 Commit message 3
| 指令 | 行为 | 结果 |
|---|---|---|
| pick | 保留该提交 | 记录和代码都留下。 |
| squash (s) | 将该提交合并到前一个提交 | 代码留下,记录合并。 |
| fixup (f) | 同 squash,但不要这个提交的日志 | 代码留下,日志被丢弃。 |
| drop (d) / 直接删行 | 彻底删除该提交 | 代码和记录全部丢失。 |
所以如果想要合并,应该修改成
pick abc1234 Commit message 1
squash def5678 Commit message 2
squash ghi9012 Commit message 3
然后保存并退出编辑器。之后修改commit信息,最后需要强制推送(--force 或 --force-with-lease)到远程仓库。
git push --force-with-lease origin your-branch-name
Git功能
CI/CD
什么是CI/CD
CI/CD 是“持续集成”(Continuous Integration)和“持续交付/持续部署”(Continuous Delivery / Continuous Deployment)的缩写,是一种软件开发实践和方法,旨在提高开发效率、减少错误并加快软件交付的速度。
1. 持续集成 (CI - Continuous Integration)
持续集成的核心思想是:开发人员经常将代码集成到共享的代码库中,而不是长时间地保持分支独立。在每次提交代码时,自动化的构建和测试流程会被触发,从而确保代码在合并之前是有效的,避免了由于合并冲突或错误积累的问题。
主要内容包括:
- 频繁提交: 开发人员每天多次将代码提交到共享代码库。
- 自动化构建: 每次代码提交后,自动触发构建过程,确保代码可以顺利编译。
- 自动化测试: 执行单元测试、集成测试等,以检查代码是否存在问题。
2. 持续交付 (CD - Continuous Delivery)
持续交付的目标是确保每次代码更改都能自动化地通过测试,并准备好可以部署到生产环境。持续交付确保软件在任何时候都处于可发布的状态,但并不直接将其部署到生产环境,而是确保可以随时部署。
主要内容包括:
- 自动化部署: 代码完成测试后,自动部署到一个预生产环境(如 staging 环境)进行进一步验证。
- 版本管理: 始终有一个可以发布到生产的版本,确保代码可以随时投入使用。
3. 持续部署 (Continuous Deployment)
持续部署是持续交付的一个进一步发展,它意味着每次代码更改一旦通过测试,就会自动部署到生产环境,而无需人工干预。
主要内容包括:
- 自动化到生产: 每次通过自动化测试的代码更改会被立即推送到生产环境,不需要人工操作。
- 快速发布: 用户可以快速地体验到最新的功能或修复。
VScode集成
1. 抓取 (Fetch) —— “看一眼更新了什么”
- 作用:从远程仓库获取最新的版本信息(分支名、新的提交记录),但不会更改你本地正在写的代码。
- 使用场景:你想知道同事有没有交新作业,但你现在正忙着写自己的代码,不想让别人的东西立刻混进来。
- 结果:本地会知道“远程有更新了”,你会看到 VS Code 左下角出现同步的小图标,提示你有几个待拉取的提交。
2. 拉取 (Pull) —— “同步并合并到本地”
- 作用:等同于 抓取 (Fetch) + 合并 (Merge)。它会把远程仓库的代码下载下来,并直接合并到你当前正在工作的本地分支中。
- 使用场景:开始写代码前的第一件事。确保你是在最新版本的代码基础上开发的。
- 风险:如果别人改了和你同一行代码,执行拉取时会触发冲突 (Conflict),需要你手动去 VS Code 里选“保留谁的代码”。
3. 提交 (commit) —— “为我的代码拍一张快照”
提交 是在你的本地仓库里为代码拍一张“快照”。
- 打包行为:当你点“提交”时,Git 会把你在暂存区(Staged Changes)里的所有改动打包,给它一个独一无二的编号(Hash 值),并记录下是谁在什么时候改了什么。
- 存档性质:提交仅仅发生在你的本地电脑上。就算你断了网,也可以疯狂提交。
- 撤销后悔药:一旦提交了,你的代码就被安全地存入了 Git 的历史记录中。哪怕你后面把文件删了,也可以通过这个提交记录找回来。
1. 提交(修改) —— Git Amend
对应命令: git commit --amend
- 作用: 将当前的更改“合并”到上一次提交中,而不是创建一个新的提交。它会直接修改上一个提交的记录。
- 使用场景:
- 手残补救: 你刚点完提交,突然发现代码里有个错别字,或者少保存了一个文件。
- 合并零碎: 你不想在记录里留下五个“修复 Bug”的提交,想把它们合成一个。
- 注意: 千万不要在已经“推送(Push)”到远程仓库的提交上使用它! 这会重写历史,导致你的同事无法同步代码。
2. 提交(已签收) —— Signed-off-by
对应命令: git commit -s
- 作用: 在提交信息的末尾自动加上一行
Signed-off-by: 你的名字 <你的邮箱>。 - 使用场景:
- 开源贡献: 很多大型开源项目(如 Linux 内核、Sigma 官方库)要求必须有这个签名,以证明你拥有该代码的版权并同意其开源协议。
- 企业合规: 某些公司为了追踪责任,要求每一行代码都有开发者的显式确认。
- 意义: 这不是加密签名(那叫 GPG 签名),而是一份数字声明。
4. 推送 (Push) —— “把我的成果交上去”
- 作用:把你本地已经 Commit(提交) 的记录上传到远程仓库。
- 使用场景:你写完了一个功能,并已经在本地提交了,现在要分享给团队或者备份到云端。
- 注意:如果远程仓库有你没拉取的代码,Git 会拒绝你的推送,要求你先“拉取”再“推送”。
5. 签出到 (Checkout to...) —— “切换频道”
- 作用:在不同的分支之间跳转,或者回滚到某个特定的历史版本。
- 使用场景:
- 切分支:从
main分支跳到feature-login分支去开发登录功能。 - 新分支:以当前代码为基础,创建一个全新的实验性分支。
- 切分支:从
- 结果:VS Code 左侧的文件列表会瞬间发生变化,显示该分支下的代码样子。
Cherry-Pick
什么是 Git Cherry-pick
Git Cherry-pick 是一个强大的版本控制命令,它允许开发人员从一个分支中挑选特定的提交(Commit),并将这些更改应用到当前所在的分支。与合并整个分支(Merge)不同,Cherry-pick 提供了一种更精确的代码搬运方式。
1. 核心概念 (The Core Concept)
Cherry-pick 的字面意思是“摘樱桃”。在 Git 中,这意味着你不是把整棵树(整个分支的历史)挪过来,而只是摘取其中一颗或几颗最好的“樱桃”(具体的代码提交)。
主要使用场景包括:
- 修复 Bug 的同步: 在开发分支修复了一个紧急 Bug,需要立即将这个修复应用到生产分支,而不带走开发分支中尚未完成的其他功能。
- 功能迁移: 某个分支中的一小部分功能代码是另一个分支急需的。
- 撤销后的恢复: 如果之前的合并被意外回滚,可以用 cherry-pick 重新找回那些正确的提交。
2. 工作流程 (How It Works)
当你执行 cherry-pick 时,Git 会提取该提交引入的更改,并在当前分支上创建一个全新的提交。这个新提交的内容与原提交相同,但会拥有一个新的哈希值(Hash)。
基本操作步骤:
- 获取 ID: 首先找到你想要复制的提交 ID(可以通过
git log查看)。 - 切换分支: 切换到目标分支(例如
production)。 - 执行命令: 使用
git cherry-pick <commit-id>将更改应用过来。
3. 注意事项 (Precautions)
虽然 Cherry-pick 非常灵活,但过度使用可能会导致一些维护上的挑战:
- 重复提交: 同样的逻辑会出现在两个分支的不同提交中,这可能在未来的合并(Merge)时引发冲突。
- 依赖关系: 如果你挑选的提交依赖于之前的其他提交(而你没有一起挑过来),可能会导致编译错误或运行时问题。
- 版本冲突: 如果目标分支的代码与该提交修改的代码行存在差异,仍需要手动解决冲突。
通过 cherry-pick 将实验环境(Experimental)的功能搬运到正式环境(Production/Main)是一个非常经典且稳健的操作。它的精髓在于**“精准打击”**——只带走你需要的代码,留下实验分支里的杂乱测试或未完成逻辑。
以下是完整的操作指南:
第一步:定位“樱桃”(获取提交 ID)
首先,你需要去实验分支找到那个实现了新功能的提交。
- 切换到实验分支:
git checkout experimental - 查看提交历史:
git log --oneline - 记录哈希值: 找到对应的 Commit ID(例如
a1b2c3d)。
提示: 如果功能是由多个提交组成的,记录下这一串 ID 的起始和结束。
第二步:准备正式环境分支
为了保证正式环境的安全,建议先创建一个临时分支进行“试运行”。
- 切换到正式环境:
git checkout main(或者是你的production分支)。 - 拉取最新代码:
git pull origin main。 - 创建并切换到搬运分支:
git checkout -b apply-new-feature。
第三步:执行 Cherry-pick
现在开始把代码“摘”过来。
-
搬运单个提交:
Bash
git cherry-pick a1b2c3d -
连续搬运多个提交(从 A 到 B):
Bash
git cherry-pick A^..B(注意:
^表示包含 A 本身)
第四步:处理可能出现的“坏果子”(冲突)
如果正式环境和实验环境的代码在同一行有不同的修改,Git 会停下来要求你解决冲突。
- 查看冲突文件:
git status。 - 手动修改: 打开冲突文件,选择保留正式环境逻辑、实验环境逻辑,还是两者合并。
- 标记解决:
git add <文件名>。 - 继续搬运:
git cherry-pick --continue。
意外处理: 如果冲突太复杂你想反悔了,可以使用
git cherry-pick --abort回到最初状态。
第五步:验证与合并
- 本地测试: 在
apply-new-feature分支上运行测试脚本,确保新功能在正式环境下不崩坏。 - 推送到远程:
git push origin apply-new-feature。 - 发起 PR/MR: 在 GitHub/GitLab 上发起合并请求,让同事 Code Review 后合入
main分支。