1. Git 基本概念
- 版本控制 (Version Control)
- 管理文件随时间的变化,并保留历史版本,便于回溯、查阅、比较和协作。
- 工作区 (Working Directory / Working Tree)
- 指本地文件所在目录,你正在编辑或查看的文件就是在工作区。
- 暂存区 (Staging Area / Index)
- 提交前临时存放改动的区域,用
git add
命令把修改加入暂存区,再通过git commit
将其永久存储为一个提交(commit)。
- 提交前临时存放改动的区域,用
- 本地仓库 (Local Repository)
.git
文件夹所在的位置,包含所有版本信息、配置等。
- 远程仓库 (Remote Repository)
- 远程服务器上的仓库,用于多人协作,如 GitHub / GitLab / Gitee 等。
- 提交 (Commit)
- Git 以“快照”方式记录文件当前状态(而不是保存差异),形成一个提交历史链条。
2. Git 安装与配置
2.1 安装 Git
- Windows:从 git-scm.com 下载最新的安装包;或使用包管理器(Scoop、Chocolatey)安装。
- macOS:使用 Homebrew 安装:
brew install git
。 - Linux:使用发行版自带的包管理器安装,例如 Ubuntu 中
sudo apt-get install git
。
2.2 全局配置
安装完成后,可使用以下命令配置用户信息:
git config --global user.name "YourName"
git config --global user.email "YourEmail@example.com"
查看所有配置信息:
git config --list
可在 ~/.gitconfig
文件中修改相关配置。
3. 创建与克隆仓库
3.1 创建本地仓库
mkdir my-project
cd my-project
git init
git init
会在当前目录下创建一个.git
文件夹,标识这是一个 Git 仓库。
3.2 克隆远程仓库
git clone <远程仓库URL> [本地目录名]
示例:
git clone https://github.com/username/project.git
[本地目录名]
可选,不填则默认为仓库名。
4. 基础操作
4.1 查看仓库状态
git status
- 可查看新建、修改、删除的文件,哪些已进入暂存区,哪些未提交。
4.2 添加修改到暂存区
git add <文件/目录>
- 如:
git add README.md
或git add .
(将所有改动加入暂存区)。
4.3 提交 (Commit)
git commit -m "提交信息"
- 提交信息最好简明扼要,包含本次改动的核心点。
4.4 查看提交历史
git log
常见用法:
git log --oneline
:简洁地显示提交记录(提交哈希的简写 + 提交信息)。git log --graph --oneline --decorate
:以图形方式显示分支、合并历史。
4.5 比较差异 (Diff)
git diff
- 暂存区与工作区比较:
git diff
或git diff --staged
- 提交之间比较:
git diff <commit1> <commit2>
5. 分支与合并
5.1 新建与切换分支
# 新建并切换到新分支
git checkout -b feature/login
git checkout <分支名>
可以切换到已有的分支。
5.2 查看分支
git branch
git branch -v
:查看每个分支最新的一条提交信息。git branch -a
:查看所有分支(包含远程分支)。
5.3 合并分支
# 先切换到需要接收改动的分支(通常 main 或 master)
git checkout main
# 合并 "feature/login" 分支到当前分支
git merge feature/login
- 如有冲突,需要手动解决冲突后,再
git add <文件>
并git commit
。
5.4 删除分支
git branch -d <分支名>
- 如果分支未合并到任何分支,需要强制删除:
git branch -D <分支名>
。
6. 远程仓库操作
6.1 添加远程仓库
git remote add <别名> <远程仓库URL>
- 如:
git remote add origin https://github.com/username/project.git
。
6.2 查看远程仓库
git remote -v
- 可查看当前已配置的远程仓库地址。
6.3 推送本地分支到远程
git push <别名> <本地分支>:<远程分支>
- 如果本地与远程分支同名,可以省略
:远程分支
:
git push origin main
6.4 拉取远程分支
git pull <别名> <分支名>
-
git pull
=git fetch
+git merge
-
若想保持提交历史更干净,可以采用
fetch + rebase
:
git fetch origin git rebase origin/main
6.5 追踪远程分支
git checkout -b <本地分支> <远程仓库>/<远程分支>
- 为本地分支设置跟踪远程分支。
7. 进阶操作
7.1 交互式变基 (Interactive Rebase)
在提交较多或想保持提交历史干净时,可以使用交互式 rebase:
# 将当前分支基于 main 进行 rebase
git checkout feature/login
git fetch origin
git rebase -i origin/main
-i
允许你在弹出的编辑器中对每个提交做操作(如 squash、reword、drop 等)。
7.2 修改上一次提交 (Amend)
git add .
git commit --amend --no-edit
- 将当前修改合并到上一次提交中,不会产生新提交。
- 如果提交已经推送到远程,需要强制推送:
git push -f origin feature/login
7.3 重置 (Reset)
# 撤销最后一次提交,但保留工作区改动
git reset --soft HEAD~1
# 撤销最后一次提交和暂存区,保留工作区改动
git reset --mixed HEAD~1
# 回退到指定提交,丢弃所有改动 (危险操作)
git reset --hard <提交哈希>
7.4 回滚提交 (Revert)
git revert <提交哈希>
- 生成一个新提交用来撤销指定提交,不破坏已有历史,适用于多人协作的主分支。
7.5 Cherry-pick
git cherry-pick <提交哈希>
- 将指定提交(可能在其他分支)“摘取”到当前分支,常用于修复 Bug 或跨分支复用某次提交。
7.6 暂存改动 (Stash)
git stash
git stash list
git stash pop
- 将当前未提交的改动保存到“栈”里,并清空工作区;
pop
会将最新的 stash 恢复并弹出。
8. 冲突解决与常见问题
8.1 合并冲突
当执行 merge
或 rebase
时,如果同一行或同一文件的修改无法自动合并,就会出现 合并冲突。示例如下:
<<<<<<< HEAD
console.log("这是本地分支的内容");
=======
console.log("这是远程分支的内容");
>>>>>>> origin/main
解决方法:
- 手动编辑冲突标记所在的文件,保留正确的修改或合并双方的逻辑。
git add <文件>
将解决后的文件重新加入暂存区。git commit
(如果在 rebase 流程,则执行git rebase --continue
)。
8.2 常见错误及解决
-
fatal: refusing to merge unrelated histories
- 表示两个仓库没有共同基点,可使用
git pull origin main --allow-unrelated-histories
临时解决,但应先确认仓库关联性。
- 表示两个仓库没有共同基点,可使用
-
detached HEAD
状态-
当你检出一个具体的提交而非分支时就会出现,若需要提交修改,需先创建分支:
git checkout -b <新分支名>
-
-
“Already up to date.” 但本地代码不是最新
- 可能你在错误的分支上,或者远程分支更新并未拉取。先
git fetch
并检查本地分支与远程分支。
- 可能你在错误的分支上,或者远程分支更新并未拉取。先
9. 团队协作与 Pull Request (PR) 工作流
9.1 Fork 仓库
- 在 GitHub / GitLab 上点击 Fork,将项目复制到自己账号下。
- 将 Fork 后的仓库克隆到本地。
9.2 添加上游仓库 (Upstream)
cd <项目目录>
git remote add upstream <官方/上游仓库URL>
- 这样可通过
git fetch upstream
来获取官方仓库的最新更新。
9.3 创建分支进行开发
git checkout -b feature/new-feature
# ...进行开发和提交...
git push origin feature/new-feature
9.4 发起 Pull Request
- 在你的 Fork 仓库页面选择
Compare & Pull Request
。 - 选择要合并到官方仓库 (upstream) 的哪个分支(通常是
main
)。 - 填写 PR 标题与描述,说明改动内容。
- 提交后等待代码审查 (Code Review)。
9.5 处理审查意见
- 审查通过前,如果需要修改,可以在本地同一分支上继续提交,然后 push(如有合并提交被要求合并为单个 commit,可能需要
git commit --amend
+git push -f
)。
9.6 同步上游仓库最新改动
git checkout main
git fetch upstream
git merge upstream/main
git push origin main
- 保证你的本地
main
分支同步到官方最新,然后你的功能分支也可以与最新的 main rebase 或 merge,减少冲突。
10. Git Hooks
Git Hooks 是在 Git 各种操作前后触发的小脚本,可以让你在以下时机执行自定义脚本:
- pre-commit:在执行 commit 前运行,可用于检查代码风格、静态分析等。
- commit-msg:在提交信息编辑完毕后、真正提交前调用,可用于校验提交信息格式(如是否符合团队约定)。
- pre-push:在执行 push 前调用,可进行测试或其他验证逻辑。
示例:在 .git/hooks
目录下创建或修改对应脚本文件(如 pre-commit
),设置执行权限后即可生效。
11. Git 大文件管理与子模块
11.1 Git LFS (Large File Storage)
- 当项目中需要管理大文件(如视频、图片、模型文件等)时,建议使用 Git LFS。
- Git LFS 会将大文件追踪并存储在外部,仓库中仅保留对应指针文件。
安装后在项目中指定要追踪的大文件类型:
git lfs track "*.psd"
git lfs track "*.zip"
git add .gitattributes
git commit -m "Add LFS tracking"
11.2 Git Submodule
-
有时一个项目需要依赖另一个仓库,可以将另一个仓库以子模块的方式嵌入本项目中:
git submodule add <子模块仓库URL> <目标目录>
-
更新子模块时:
git submodule update --init --recursive
12. 最佳实践与常见工作流
12.1 提交信息规范
-
采用类似
Conventional Commits
格式:
feat: 新功能
fix: 修复 Bug
docs: 文档变更
style: 格式(不影响代码功能的变动)
refactor: 重构(既不是新增功能,也不是修复 Bug)
test: 增加测试
chore: 构建过程或辅助工具的变动
12.2 常见工作流
- Git Flow
- 典型的分支模型,包含
main
、develop
、feature
、release
、hotfix
等分支。适用于发布周期明确、需要严格版本管理的大型项目。
- 典型的分支模型,包含
- GitHub Flow
- 更轻量的单分支(main)+ Feature 分支模型:开发新功能 -> PR -> 合并 -> 部署。
- GitLab Flow
- 类似 GitHub Flow,但通常和环境/版本分支绑定,如
production
、staging
、dev
。
- 类似 GitHub Flow,但通常和环境/版本分支绑定,如
12.3 代码审查 (Code Review)
- 提交 PR 后,团队成员可以查看改动并提出意见,通过评论或直接在文件行级评论。
- 审查完成后,再由仓库维护者合并;或驳回并要求修改。
12.4 CI/CD 集成
- 在项目中配置 CI/CD(如 GitHub Actions、GitLab CI),每次提交或 PR 都会触发自动构建和测试,保证提交的质量。