Git
一、Git 基础概念
1. 什么是 Git?
Git 是一个分布式版本控制系统,用于追踪文件(尤其是源代码)的变化。
每个开发者的本地仓库都包含完整的版本历史,可以独立进行提交、分支和合并操作。
2. Git 和 SVN 有什么区别?
- 架构:Git 是分布式的,SVN 是集中式的。
- 分支操作:Git 的分支轻量快速;SVN 分支是目录复制,较重。
- 离线能力:Git 支持离线提交、查看日志;SVN 需要网络连接。
- 性能:Git 基于快照(snapshot),SVN 基于增量(delta)。
- 安全性:Git 通过哈希值(SHA-1)校验完整性。
二、常见操作与命令
1. Git 的常用命令有哪些?
git init # 初始化仓库
git clone <url> # 克隆远程仓库
git add <file> # 添加文件到暂存区
git commit -m "msg" # 提交代码
git status # 查看状态
git diff # 查看修改内容
git log # 查看提交历史
git branch # 查看分支
git checkout <branch> # 切换分支
git merge <branch> # 合并分支
git rebase <branch> # 变基操作
git stash # 暂存未提交的更改
git reset # 撤销提交或回退版本三、分支管理
1. Git 分支的工作原理
Git 的分支本质上是一个指针,指向某次提交(commit)。
创建新分支只是创建一个新的指针,因此操作极快。
2. merge 和 rebase 的区别
-
merge:将目标分支的修改合并到当前分支,保留所有历史记录。
-
rebase:将当前分支的提交“移植”到目标分支上,生成线性历史。
使用建议:
-
团队协作时用 merge,安全且保留上下文;
-
私有分支上可用 rebase,保持历史整洁。
四、版本回退与修正
1. 如何撤销一次提交?
- 回退但保留记录:
git revert <commit_id>- 彻底回退(危险):
git reset --hard <commit_id>2. 如何撤销已提交但未推送的修改?
git reset --soft HEAD~1 # 撤销提交但保留修改
git reset --hard HEAD~1 # 撤销提交并丢弃修改3. 如何修改最近一次提交信息?
git commit --amend五、远程协作
1. push 和 pull 的区别
-
git push:将本地提交推送到远程仓库。
-
git pull:拉取远程更新并自动合并。
(相当于 git fetch + git merge)
2. fetch 和 pull 的区别
- git fetch:只拉取远程更新,不自动合并;
- git pull:拉取并自动合并,风险较高。
六、冲突解决
1. Git 冲突出现的原因
多名开发者修改了同一文件的同一行,并尝试合并时会发生冲突。
2. 冲突的解决流程
- Git 标记出冲突位置(<<<<<<<、=======、>>>>>>>)
- 手动编辑文件,保留正确内容
- 执行:
git add <file>
git commit七、标签与发布
1. 如何创建和推送标签?
git tag v1.0.0
git push origin v1.0.0标签用于标记特定版本(如发布点)。
2. 轻量标签 vs 注释标签
- 轻量标签:仅指向一个提交。
- 注释标签:包含创建者、时间、信息,更常用于发布。
八、Git 工作流(Workflow)
1. Git Flow
常见分支模型:
- master:线上稳定版本
- develop:开发主分支
- feature/*:功能开发
- release/*:预发布版本
- hotfix/*:线上紧急修复
2. Trunk Based Development
强调短周期、频繁集成,直接在主干上开发小分支,减少复杂度。
九、面试高频问题总结
1. 如何解决多人协作中的代码冲突?
- 提前 pull 更新,减少冲突;
- 避免多人改同一文件;
- 用 rebase 保持历史清晰;
- 冲突时手动比对修改再提交。
2. Git 的 HEAD、index、working tree 分别是什么?
- HEAD:指向当前分支的最新提交;
- index(暂存区):保存已添加、待提交的修改;
- working tree(工作区):实际文件系统中的代码。
3. 如何查看某行代码是谁写的?
git blame <file>4. 如何回滚远程仓库版本?
- 本地 reset 到指定版本;
- 强制推送:
git push origin HEAD --force十、实战情景题(高频)
场景1:误删文件后发现还没提交
git checkout -- <file>恢复到上次提交状态。
场景2:想要忽略某个文件的修改但不删除
git update-index --assume-unchanged <file>场景3:如何在不合并的情况下查看另一个分支的文件
git checkout <branch> -- <file_path>是否希望我接着输出 「iOS 项目中常见的 Git 分支策略与团队协作最佳实践」 这一部分?
十一、iOS 项目中的 Git 分支策略与协作实践
1. iOS 团队常用分支模型
在实际 iOS 开发中,常见的团队协作分支模型主要包括三种:
(1)Git Flow 模型
适合中大型团队,结构清晰。
主要分支:
- main(或 master):线上正式发布版本;
- develop:日常开发主线;
- feature/*:开发新功能;
- release/*:预发布;
- hotfix/*:线上紧急修复。
优点:规范、清晰,适合多人协作。
缺点:分支较多,操作复杂。
(2)GitHub Flow 模型
适合小团队或持续集成频繁的项目。
流程简洁:
- 从 main 分支创建 feature 分支;
- 开发并提交 PR;
- 通过代码审查(Code Review);
- 合并回 main 并部署。
(3)Trunk Based Development
主张“所有人都在主干上快速迭代”。
分支生命周期极短(通常 <1天),依赖自动化测试与 CI/CD。
适合高频发布、自动化程度高的 iOS 团队。
2. iOS 项目推荐的分支策略
多数中型 iOS 团队采用以下折中方案:
- main:正式 App Store 版本;
- develop:主开发分支;
- feature/xxx:功能分支;
- release/x.y.z:提测、灰度;
- hotfix/x.y.z:线上问题紧急修复。
实际操作示例:
git checkout develop
git checkout -b feature/login
# 开发完成后
git merge feature/login
git push origin develop3. 代码审查与 Pull Request 流程
PR(Pull Request)是团队协作的核心环节。
标准流程如下:
- 开发者提交功能分支;
- 通过 CI 检查(编译、单测、lint);
- Reviewer 进行代码审查;
- 合并至主分支或开发分支。
常用审查工具:
- GitHub / GitLab Merge Request
- Bitbucket PR
- Phabricator(部分大厂)
重点关注:命名规范、commit message 规范、代码风格一致性。
4. 提交信息规范(Commit Message)
建议使用 Conventional Commits (opens in a new tab) 格式,便于生成变更日志(changelog):
<type>(scope): <description>常见类型:
- feat:新功能;
- fix:修复问题;
- refactor:代码重构;
- perf:性能优化;
- test:单元测试;
- docs:文档修改;
- chore:构建流程或依赖变更。
示例:
feat(login): add Face ID support for iOS 17
fix(coredata): resolve crash on background context merge5. Tag 与 Release 管理
iOS 项目版本发布通常依赖 Git tag 与 CI/CD 管理:
git tag -a v2.3.0 -m "Release v2.3.0"
git push origin v2.3.0CI 系统(如 GitHub Actions / Jenkins / Bitrise)监听 tag 事件自动:
- 构建归档 .ipa;
- 上传 TestFlight;
- 发布 Release Notes。
6. 子模块与多组件管理(Submodules & Subtrees)
当 iOS 项目采用模块化架构(如多个 SDK、组件库)时:
-
Git Submodule
子仓库独立管理,但更新麻烦:
git submodule add <url> Modules/Networking
git submodule update --init --recursive-
Git Subtree
合并时更灵活,不需要手动初始化:
git subtree add --prefix=Modules/Networking <url> main --squash推荐:
- SDK 组件库 → 独立仓库 + CI 自动打包;
- 业务模块 → 子模块或 CocoaPods 私有源管理。
7. 常见协作问题与解决方案
(1)冲突频发
- 规范分支粒度;
- 合并前及时 pull --rebase;
- 合并后强制通过 CI 编译验证。
(2)多人改同一文件(如 Info.plist)
- 统一放置常量文件;
- 拆分 plist;
- 或使用脚本动态注入版本号、配置项。
(3)提交历史杂乱
- 私人分支使用 rebase 整理;
- 统一通过 squash 合并 PR;
- 强制 PR 模板要求清晰描述。
8. Git 与 CI/CD 的结合
在 iOS 项目中,Git 通常与自动化平台结合使用:
| 工具 | 功能 | 常用触发 |
|---|---|---|
| GitHub Actions | 持续集成与部署 | push、PR、tag |
| Jenkins | 企业内部 CI 系统 | 定时/触发构建 |
| Bitrise | 移动端专用自动化 | PR、分支、tag |
| Fastlane | 自动打包与上传工具 | CI 脚本调用 |
示例:
# .github/workflows/release.yml
on:
push:
tags:
- 'v*'
jobs:
build:
runs-on: macos-latest
steps:
- uses: actions/checkout@v3
- run: fastlane ios release9. iOS Git 忽略文件配置(.gitignore)
防止上传敏感文件和缓存:
# macOS
.DS_Store
# Xcode
build/
DerivedData/
xcuserdata/
# CocoaPods
Pods/
# Carthage
Carthage/Build/
# Swift Package Manager
.swiftpm/
# Other
*.xcuserstate10. 面试高频实战题
题1:多人开发同一功能时如何防止冲突?
- 明确模块责任;
- 功能分支粒度小;
- 合并前更新并解决冲突;
- 使用 PR 审核流程。
题2:如何处理一个错误提交到远程仓库的敏感文件?
- 使用 git filter-branch 或 BFG Repo-Cleaner 清除历史;
- 强制推送:git push origin --force --all;
- 更新 .gitignore 防止再次上传。
题3:如何为 iOS 项目维护稳定的发布分支?
- 使用 release/x.y.z 分支进行测试与提审;
- 发布后合并回 main 与 develop;
- 打标签标记版本,便于回滚。
是否需要我接着输出 「十二、Git 高级技巧与优化(例如子仓库管理、cherry-pick、bisect、reflog 等)」?
十二、Git 高级技巧与优化
1. git cherry-pick(挑选提交)
用于从其他分支“复制”特定提交到当前分支。
git cherry-pick <commit_id>场景:
-
某个修复在 develop 已提交,但也需要同步到 release 分支。
优点:
-
不影响其他提交,精确移植。
注意:
-
多个提交可用 git cherry-pick A..B 批量选择。
2. git stash(临时保存修改)
当你需要切换分支但当前修改未提交时:
git stash save "WIP: 调试中"
git checkout other-branch
git stash pop命令解释:
-
git stash list 查看暂存内容;
-
git stash pop 应用并删除暂存;
-
git stash apply 应用但不删除。
典型场景:临时修 bug 时保存当前工作状态。
3. git bisect(二分查找 bug 提交)
用于定位引入 bug 的提交。
git bisect start
git bisect bad HEAD # 标记当前版本为坏
git bisect good <commit_id> # 标记旧版本为好Git 会自动切换版本,让你逐步测试,最终输出问题提交。
非常适合 iOS 项目中回溯某个版本引入崩溃或 UI 错误的情况。
4. git reflog(恢复丢失提交)
当误用了 git reset --hard 或强制推送后,可用 reflog 恢复:
git reflog
git reset --hard HEAD@{3}reflog 记录了本地所有 HEAD 的移动历史,是最后的“保险”。
5. git reset 三种模式
- -soft:仅回退 commit,保留工作区与暂存区修改。
- -mixed(默认):回退 commit,保留工作区但清空暂存区。
- -hard:彻底回退到指定提交,删除所有修改。
示例:
git reset --soft HEAD~1 # 撤销最近提交但保留修改
git reset --hard HEAD~1 # 回退并清空所有修改6. git rebase –interactive(交互式变基)
整理历史提交、合并多次无意义提交:
git rebase -i HEAD~3进入编辑界面后可使用:
- pick 保留提交;
- squash 合并提交;
- edit 暂停修改;
- drop 删除提交。
常用于 PR 前清理 commit 历史,保持提交整洁可读。
7. git tag 与 release notes 自动化
结合 CI 工具(如 GitHub Actions + Fastlane),可自动识别标签并生成变更日志:
fastlane changelog_from_git_commits自动读取 commit 信息中的 feat, fix 等关键词生成发布说明。
这在 iOS 自动打包与 TestFlight 发布流程中非常常见。
8. git hooks(钩子脚本)
Git 在执行关键操作前后可触发脚本,例如:
- pre-commit:提交前检查代码格式;
- commit-msg:校验提交信息格式;
- pre-push:在推送前运行单元测试。
示例(.git/hooks/pre-commit):
#!/bin/bash
xcodebuild test -scheme MyApp -destination 'platform=iOS Simulator,name=iPhone 15'
if [ $? -ne 0 ]; then
echo "❌ 单元测试未通过,终止提交。"
exit 1
fi在团队中结合 Husky (opens in a new tab) 或 lint-staged (opens in a new tab) 可以保证代码质量。
9. git submodule 与 CocoaPods 对比
-
Submodule:版本完全受控,更新需手动。
-
CocoaPods / Swift Package Manager:更自动化,但依赖集中管理。
建议:
-
公共 SDK → 用 SPM / CocoaPods 管理;
-
特殊内部组件 → 用 Submodule 固定版本。
10. git blame 与 log 调试技巧
- 查看某行修改来源:
git blame <file>- 查看谁在什么时候修改了函数:
git log -L :funcName:file.swift- 查看单个文件修改记录:
git log --follow <file>这些命令在定位某段历史变更导致的 UI 问题或逻辑 Bug 时极其高效。
11. git clean(清理工作区)
清除未追踪的文件(例如 DerivedData 残留或中间产物):
git clean -fd参数解释:
- f 强制删除;
- d 包括文件夹;
- x 同时删除忽略文件(谨慎使用)。
12. git sparse-checkout(部分检出)
对于大型仓库(如包含多个模块或 demo 的 iOS monorepo),可只检出部分目录:
git sparse-checkout init --cone
git sparse-checkout set App/ModuleA减少磁盘占用与构建时间,常用于多组件大项目。
13. 常见优化策略
- 浅克隆:
git clone --depth 1 <url>-
仅拉取最新一次提交,适用于 CI 构建。
-
减少提交体积:
不提交二进制文件、缓存、DerivedData。
-
提交前格式化:
结合 SwiftLint 或 SwiftFormat 保持代码统一。
-
CI 缓存依赖:
利用 Git hash 缓存 Pods 或 DerivedData,加快构建。
14. Git 在 iOS 团队中的最佳实践总结
- 小步提交,语义清晰:每次提交只做一件事。
- 合并前自测通过:保持分支可随时发布。
- 保护 main 分支:启用保护规则、强制 PR。
- 使用 tag 管理版本:自动构建与发布。
- 定期清理历史:rebase -i + gc 优化仓库体积。
- 代码审查必经流程:每次 PR 至少一人审核。
15. iOS 面试高频实战问答总结
问:如何回滚一个已经推送到远程的错误提交?
答:
- 使用 git revert 生成反向提交;
- 推送到远程;
- 避免使用 reset --hard 强制覆盖,除非是私有分支。
问:团队多人在同一分支上开发,如何避免提交混乱?
答:
- 严格遵循 feature 分支策略;
- 统一命名规范(feature/xxx、hotfix/xxx);
- 提交前 rebase 同步最新代码;
- 启用保护分支防止直接 push。
问:如何在不合并的情况下测试某分支的变更?
答:
git checkout other-branch -- <file>或用 git worktree 创建并行工作区,独立编译测试。
问:发现某个提交导致构建失败,如何快速定位?
答:使用 git bisect 二分查找问题提交。
问:如何防止机密文件(如 API Key)被上传?
答:
- .gitignore 屏蔽;
- 使用环境变量或 .xcconfig;
- 若已上传,使用 BFG Repo-Cleaner 清理历史。
十三、总结与延伸
Git 是 iOS 开发中不可或缺的核心工具。
面试中考察的不只是命令记忆,更看重:
- 对分支模型的理解;
- 团队协作流程意识;
- 处理冲突与灾难恢复能力;
- 提交规范与自动化发布经验。
掌握 Git 的本质,就像掌握“时间旅行”的能力:
你能在任何时刻回到过去,也能重写未来。
如果需要,我可以进一步扩展最后一节:「十四、iOS 团队 Git 流程自动化与最佳工程实践(结合 CI/CD、Fastlane、App Store 发布)」,把整套从版本到发布的流程串成体系。是否要继续补全?
十四、iOS 团队 Git 流程自动化与最佳工程实践(CI/CD 集成)
1. Git 与 CI/CD 的角色分工
在现代 iOS 团队中,Git 只是“源头”,
CI/CD(持续集成与持续交付)才是版本发布自动化的“引擎”。
二者关系可以简化为:
Git 提交代码 → CI 自动构建与测试 → 自动生成包并发布至 TestFlight / App Store
典型工具链:
- 代码托管:GitHub / GitLab / Bitbucket
- 持续集成:GitHub Actions / Jenkins / Bitrise / CircleCI
- 自动化打包:Fastlane
- 版本发布:TestFlight、App Store Connect API
2. CI/CD 流程概览(结合 Git 工作流)
Feature Branch → Pull Request → Review → Merge to Develop
↓
CI 自动构建 & 单元测试
↓
Merge to Release
↓
自动生成 Tag + 上传 TestFlight
↓
Merge to Main
↓
自动打正式包 & 发布到 App Store关键事件触发器(Trigger):
- push:任意提交时执行基本测试;
- pull_request:合并前执行代码审查与单测;
- tag:创建新版本标签时触发打包与发布。
3. Git 标签与自动发布版本
发布新版本推荐使用语义化标签(Semantic Versioning):
v1.0.0 → 初始稳定版
v1.1.0 → 新功能
v1.1.1 → Bug 修复在 CI 中监听标签事件触发构建脚本:
# .github/workflows/release.yml
on:
push:
tags:
- 'v*'
jobs:
release:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- run: bundle install
- run: fastlane ios release4. Fastlane 自动化打包与上传
Fastlane 是 iOS 自动化的核心工具,可完成以下任务:
- 自动递增版本号;
- 构建 .ipa 文件;
- 上传到 TestFlight;
- 提交 App Store 审核。
示例 Fastfile:
lane :release do
increment_build_number
build_app(
scheme: "MyApp",
export_method: "app-store"
)
upload_to_testflight(
skip_waiting_for_build_processing: true
)
end与 Git tag 结合时,可自动将版本号与 tag 同步:
version = lane_context[SharedValues::VERSION_NUMBER]
add_git_tag(tag: "v#{version}")
push_to_git_remote5. 自动化测试与质量控制
CI 在每次合并前应执行以下任务:
- 编译检查(防止语法错误进入主干);
- 单元测试(xcodebuild test 或 fastlane scan);
- Lint 检查(SwiftLint / SwiftFormat);
- 依赖检查(Pod install 是否通过);
- 打包构建(验证能成功生成 .ipa)。
示例(GitHub Actions):
jobs:
test:
runs-on: macos-latest
steps:
- uses: actions/checkout@v3
- run: bundle install
- run: fastlane scan6. 自动生成 Release Notes 与版本记录
结合 Git 提交信息自动生成版本更新日志:
fastlane changelog_from_git_commits或使用开源工具:
自动生成:
## v2.3.0
- feat: 新增登录保护
- fix: 修复 CoreData 崩溃问题
- perf: 优化视频加载性能7. 分支保护与代码审查自动化
保护关键分支(如 main 和 develop):
- 禁止直接推送;
- 强制 Pull Request;
- 强制通过 CI 测试;
- 要求至少一名 Reviewer 审核。
在 GitHub 中配置:
Settings → Branches → Branch protection rules启用:
- Require status checks to pass before merging
- Require pull request reviews before merging
8. 多 Target / 多环境构建策略
常见 iOS 项目存在多个环境:
- Debug(开发环境)
- Staging(测试环境)
- Release(正式环境)
在 Git 中推荐使用分支对应不同环境配置:
| 分支 | 环境 | 打包方式 |
|---|---|---|
| develop | Debug | 手动打包或 CI 内测 |
| release/x.y.z | Staging | 自动上传 TestFlight |
| main | Release | 自动上架 App Store |
结合 .xcconfig 与环境变量切换不同 API Key 或 Bundle ID。
9. Git 版本号自动同步
避免人工维护 Info.plist 的 CFBundleVersion。
Fastlane 自动脚本:
lane :bump do
increment_build_number
commit_version_bump(
message: "chore: bump build number [skip ci]"
)
push_to_git_remote
end这样,每次构建版本号都会自动加 1,并推送回仓库。
10. 持续部署与灰度发布
-
TestFlight 自动化:
结合 upload_to_testflight,自动上传内测版本给 QA。
-
灰度发布策略:
可在 CI 中控制上传渠道或受邀用户范围;
-
自动上架:
Fastlane 提供 deliver 命令直接上传到 App Store 审核队列。
11. 安全与凭证管理
- 使用 App Store Connect API Key 代替手动输入账号;
- 使用 GitHub Secrets / Jenkins Credentials 存储密钥;
- 使用 match 管理证书和描述文件同步;
- 禁止在代码库中提交 .p12、.mobileprovision 等敏感文件。
12. 自动化回滚与热修复机制
在 CI 流程中保留上一个成功构建版本号:
当新版本发布失败或崩溃率上升时,可自动触发回滚脚本。
企业内部可结合自研 OTA 系统或 Firebase Remote Config 控制灰度比例。
此外:
- 对热修复方案(如 JSPatch、Dynamic Framework Update)要严格控制签名与审核;
- 重要分支在合并前必须经过自动化测试全覆盖。
13. 性能与维护优化
-
使用 shallow clone:git clone --depth=1
减少 CI 拉取时间;
-
缓存 Pods 与 DerivedData:
通过哈希缓存,减少重复构建时间;
-
自动清理旧分支:
定期运行脚本清除已合并的 feature 分支;
git branch --merged | grep -v 'main' | xargs git branch -d14. iOS 团队 Git 自动化最佳实践总结
| 阶段 | 工具 | 作用 |
|---|---|---|
| 提交前 | Husky + SwiftLint | 格式校验、代码规范 |
| 合并前 | GitHub Actions / Bitrise | 自动编译与单测 |
| 发布前 | Fastlane + Tag | 自动打包上传 TestFlight |
| 发布后 | 自动生成 Release Notes | 保留版本历史与日志 |
| 安全 | match + Secrets 管理 | 自动化签名与证书维护 |
核心原则:
让开发者专注于写代码,而非重复劳动。
15. 面试高频问答总结(CI/CD 集成类)
问:如何设计一套自动化 iOS 打包发布流程?
答:
- Git 打 tag;
- CI 检出代码并执行单测;
- Fastlane 打包上传 TestFlight;
- CI 自动生成 changelog;
- 成功后合并回主分支并推送 tag。
问:如何防止错误代码合并到主干?
答:
- 启用保护分支 + 强制 PR;
- 所有合并必须通过 CI;
- Reviewer 至少一人签核。
问:如何在多分支协作下保证版本号一致性?
答:
- 所有构建通过 Fastlane 自动递增;
- CI 用环境变量统一版本号源;
- 禁止手动修改 Info.plist。
问:如何实现“一键打包上传 TestFlight”?
答:
配置 Fastlane:
fastlane ios beta执行自动:
- 编译;
- 生成 IPA;
- 上传 TestFlight;
- 通知团队。
十五、总结:Git 驱动的工程自动化哲学
Git 是整个开发体系的“中枢神经”,每一次提交都是项目演化的节点。
从分支策略到 CI/CD 自动化,关键目标只有一个:
让软件演化变得安全、可控、可重复。
在 iOS 团队中,真正的高手不是会多少命令,
而是能将 Git 作为“时间机器”,
把每一次构建、每一个版本、每一个决策都记录得清清楚楚。
掌握 Git,你就掌握了工程的历史与未来。
——至此,Git 版本控制 + CI/CD 自动化相关的 全部 iOS 面试高频考点 已完整覆盖。