Git 分支与远程仓库基础教学总结
1. Git 分支基础
什么是分支(Branch)?
- 分支是对项目某个提交状态的指针。
- 用于并行开发、多人协作和代码版本隔离。
常用分支命令
命令 | 作用 |
---|---|
git branch |
查看本地分支 |
git branch -r |
查看远程分支 |
git branch -a |
查看本地和远程分支 |
git branch <name> |
创建新分支(基于当前分支) |
git checkout <name> |
切换分支 |
git checkout -b <name> |
创建并切换新分支 |
git branch -vv |
查看分支详情及远程追踪状态 |
git branch --set-upstream-to=origin/dev dev |
设置本地分支追踪远程分支 |
补充常用命令:
命令 | 作用 |
---|---|
git branch -d <name> |
删除本地分支(安全删除) |
git branch -D <name> |
强制删除本地分支 |
git push origin --delete <name> |
删除远程分支 |
git switch <name> |
切换分支(新版本推荐) |
git switch -c <name> |
创建并切换分支(新版本推荐) |
2. 分支创建与内容
- 执行
git branch dev
创建的dev
分支,是当前分支的一个副本。 - 新分支内容、文件和提交记录与当前分支一致,不是空的。
- 只有使用
git checkout --orphan
或在空仓库时才会出现空分支。
详细说明:
- 新创建的分支包含当前分支的完整历史记录
- 分支指针指向当前提交,但可以独立发展
- 分支之间共享历史提交,直到它们开始分叉
3. 远程仓库与 origin
什么是远程仓库?
- 远程仓库是托管代码的服务器版本,通常在 GitHub、Gitee 等平台。
origin
是什么?
origin
是 Git 本地对远程仓库的默认别名。- 当你克隆仓库时,Git 会自动把远程地址赋予
origin
。 - 本地使用
origin
来简化对远程仓库的引用。
例子:
git clone https://github.com/user/repo.git
- 远程地址自动命名为
origin
- 使用时写
git fetch origin
,git push origin master
等
自定义远程名:
git remote add gitee git@gitee.com:user/repo.git
git fetch gitee
补充远程仓库管理命令:
# 查看远程仓库
git remote -v
# 重命名远程仓库
git remote rename origin old-origin
# 删除远程仓库
git remote remove origin
# 修改远程仓库地址
git remote set-url origin https://new-url.git
4. 本地分支与远程分支关系
- 本地分支是你本地的开发分支。
- 远程分支以
origin/branch-name
的形式存在,表示远程仓库的状态快照。 - 使用
git fetch
更新本地远程分支信息。 - 使用
git pull
从远程分支拉取并合并代码。
分支关系图示:
本地仓库 远程仓库
┌─────────────┐ ┌─────────────┐
│ main │◄────────────┤ main │
│ dev │◄────────────┤ dev │
│ feature │ │ │
└─────────────┘ └─────────────┘
▲
│
┌─────────────┐
│ origin/main │ ← 远程跟踪分支(只读)
│ origin/dev │
└─────────────┘
5. 设置分支追踪(关联)
git branch --set-upstream-to=origin/dev dev
- 设置本地
dev
分支追踪远程origin/dev
。 - 作用:简化后续的
git pull
和git push
操作,不用每次写远程和分支名。 - 不会改变本地代码内容,只是建立关联关系。
其他设置追踪关系的方法:
# 方法1:创建分支时直接设置追踪
git checkout -b dev origin/dev
# 方法2:推送时设置追踪关系
git push -u origin dev
# 方法3:使用 switch 命令(推荐)
git switch -c dev origin/dev
6. 同步操作命令总结
命令 | 作用 | 是否修改代码 |
---|---|---|
git fetch |
拉取远程分支最新信息,不合并代码 | 否 |
git pull |
拉取并合并远程代码到当前分支 | 是 |
git push |
推送当前分支代码到远程分支 | - |
详细的同步操作:
命令 | 完整形式 | 作用 | 使用场景 |
---|---|---|---|
git fetch |
git fetch origin |
获取远程所有分支的最新状态 | 查看远程更新但不合并 |
git pull |
git fetch + git merge |
获取并合并到当前分支 | 同步远程最新代码 |
git push |
git push origin <branch> |
推送当前分支到远程 | 上传本地修改 |
git push -u origin <branch> |
推送并设置追踪关系 | 推送新分支到远程 | 第一次推送新分支 |
7. Git Pull 合并策略配置 ⭐️
问题背景
当你执行 git pull
时遇到 “divergent branches” 错误,需要指定合并策略。
一次性配置解决方案
全局配置(推荐):
# 设置默认使用 merge 策略(保留分支历史)
git config --global pull.rebase false
# 或者设置默认使用 rebase 策略(线性历史)
git config --global pull.rebase true
# 或者设置仅允许快进合并(最安全)
git config --global pull.ff only
仓库级配置:
# 仅对当前仓库生效(去掉 --global)
git config pull.rebase false
三种策略详细对比
策略 | 配置命令(永久) | 等价命令 (一次性) | 优点 | 缺点 | 适用场景 |
---|---|---|---|---|---|
合并策略 | git config --global pull.rebase false |
git pull --no-rebase |
保留完整历史,安全 | 历史图复杂,有合并提交 | 团队协作,需要保留分支信息 |
变基策略 | git config --global pull.rebase true |
git pull --rebase |
线性历史,简洁 | 改写提交历史,可能有风险 | 个人开发,追求简洁历史 |
快进策略 | git config --global pull.ff only |
git pull --ff-only |
最安全,不产生额外提交 | 有分叉时会失败 | 严格的线性开发流程 |
临时覆盖配置
即使设置了全局配置,也可以临时使用其他策略:
# 临时使用合并策略
git pull --no-rebase
# 临时使用变基策略
git pull --rebase
# 临时使用快进策略
git pull --ff-only
查看当前配置
# 查看 pull 相关配置
git config --global --get pull.rebase
git config --global --get pull.ff
# 查看所有配置
git config --global --list | grep pull
推荐配置方案
对于新手:
git config --global pull.rebase false
git config --global push.default simple
对于有经验的开发者:
git config --global pull.rebase true
git config --global push.default current
8. 常见问题总结
问题 | 解决方法 |
---|---|
git branch -r 没有显示新建的远程分支 |
运行 git fetch 更新远程分支列表 |
设置 --set-upstream-to 会不会修改代码? |
不会,仅设置本地远程追踪关系 |
origin 可以改名吗? |
可以,使用 git remote rename |
git pull 提示需要指定合并策略 |
使用 git config 一次性设置策略 |
补充常见问题:
问题 | 解决方法 | 说明 |
---|---|---|
推送被拒绝 rejected |
先 git pull 再 git push |
远程有新提交,需要先同步 |
本地分支落后远程分支 | git pull 或 git rebase origin/branch |
同步远程最新代码 |
误删本地分支 | git checkout -b <branch> origin/<branch> |
从远程分支重新创建 |
清理无效的远程分支引用 | git remote prune origin |
删除本地已不存在的远程分支引用 |
9. 额外知识点
代码撤销操作
git restore 1.txt` 未git add 1.txt 撤销 `git checkout 1.txt
git restore --staged 1.txt
未git commit 1.txt 撤销
git reset --soft 1.txt
撤销
完整的撤销操作总结:
修改状态 | 撤销命令 | 旧版本命令 | 说明 |
---|---|---|---|
工作区修改(未add) | git restore <file> |
git checkout <file> |
恢复到最后一次提交状态 |
暂存区修改(已add) | git restore --staged <file> |
git reset HEAD <file> |
取消暂存,修改仍在工作区 |
已提交(commit) | git reset --soft HEAD^ |
- | 撤销提交,修改回到暂存区 |
已提交(commit) | git reset --mixed HEAD^ |
git reset HEAD^ |
撤销提交,修改回到工作区 |
已提交(commit) | git reset --hard HEAD^ |
- | 完全撤销提交和修改 |
HEAD^
vs HEAD~
表达式 | 含义 |
---|---|
HEAD^ |
当前提交的父提交(第一个父) |
HEAD~1 |
当前提交的第 1 代祖先 |
HEAD~2 |
当前提交的第 2 代祖先 |
详细说明:
HEAD^
和HEAD~1
在大多数情况下是等价的- 在合并提交中,
HEAD^1
表示第一个父提交,HEAD^2
表示第二个父提交 HEAD~n
总是沿着第一个父提交向上追溯 n 代
10. 实际操作示例以及解决方案
示例:完整的分支操作流程
ubuntu@VM-16-2-ubuntu:~/workspace$ git clone git@gitee.com:aoziq/test.git
Cloning into 'test'...
remote: Enumerating objects: 7, done.
remote: Counting objects: 100% (7/7), done.
remote: Compressing objects: 100% (7/7), done.
remote: Total 7 (delta 1), reused 0 (delta 0), pack-reused 0 (from 0)
Receiving objects: 100% (7/7), done.
Resolving deltas: 100% (1/1), done.
ubuntu@VM-16-2-ubuntu:~/workspace/test$ git branch -a
* master //星号 * 表示你当前所在的本地分支是 master
remotes/origin/HEAD -> origin/master //这是远程仓库的 HEAD 指向了 origin/master,意味着远程默认分支是 master。
remotes/origin/dev //这是远程仓库 origin 上的 dev 分支
remotes/origin/master //这是远程仓库 origin 上的 master 分支
ubuntu@VM-16-2-ubuntu:~/workspace/test$ git branch -vv
* master 877ab87 [origin/master] A //git clone的时候本地master自己绑定到了origin/master分支
ubuntu@VM-16-2-ubuntu:~/workspace/test$ git remote -v //用来查看本地配置的远程仓库地址
origin git@gitee.com:aoziq/test.git (fetch) //说明你本地仓库配置了一个远程仓库,名字叫 origin。
origin git@gitee.com:aoziq/test.git (push) //远程仓库的地址是 git@gitee.com:aoziq/test.git
ubuntu@VM-16-2-ubuntu:~/workspace/test$ git branch dev //创建本地分支dev,分支内容和master的一摸一样
ubuntu@VM-16-2-ubuntu:~/workspace/test$ git branch -a
dev
* master
remotes/origin/HEAD -> origin/master
remotes/origin/dev
remotes/origin/master
ubuntu@VM-16-2-ubuntu:~/workspace/test$ git branch -vv
dev 877ab87 A //现在还没有绑定到远程origin/dev上
* master 877ab87 [origin/master] A
ubuntu@VM-16-2-ubuntu:~/workspace/test$ git branch --set-upstream-to=origin/dev dev //使得本地dev绑定到远程origin/dev
Branch 'dev' set up to track remote branch 'dev' from 'origin'.
ubuntu@VM-16-2-ubuntu:~/workspace/test$ git branch -vv //绑定成功
dev 877ab87 [origin/dev] A
* master 877ab87 [origin/master] A
ubuntu@VM-16-2-ubuntu:~/workspace/test$ git checkout dev //切换到本地dev分支上
Switched to branch 'dev'
Your branch is up to date with 'origin/dev'.
# 在这里应该先配置合并策略!
ubuntu@VM-16-2-ubuntu:~/workspace/test$ git config pull.rebase false
ubuntu@VM-16-2-ubuntu:~/workspace/test$ git pull
# 现在不会再提示需要指定合并策略了
ubuntu@VM-16-2-ubuntu:~/workspace/test$ git log --oneline --graph --all
* 15b0755 (origin/dev) ← 远程 dev 分支
* 92608c4 ← dev 分支的独立提交(远程 dev 有,你的本地 dev 没有)
| * 16dc489 (HEAD -> dev, origin/master, origin/HEAD, master) ← 你的本地 dev、origin/master 等都在这个提交
|/
* 877ab87 A
* 715bea0 Initial commit
冲突处理流程
处理冲突的完整流程:
合并策略冲突处理:
git pull # 如果已配置策略,直接拉取 # 解决冲突(手动编辑文件) git add <冲突文件> # 标记冲突已解决 git commit # 完成合并提交
变基策略冲突处理:
git pull # 如果已配置变基策略 # 解决冲突(手动编辑文件) git add <冲突的文件> # 标记冲突已解决 git rebase --continue # 继续变基 # 或者 git rebase --abort # 放弃变基
临时保存修改的方法
如果你不想现在提交,只是临时保存一下本地更改,可以用 stash
:
git stash
git pull
git stash pop
完整的 stash 操作:
命令 | 作用 | 说明 |
---|---|---|
git stash |
保存当前修改 | 工作区和暂存区都会被保存 |
git stash save "message" |
保存并添加描述 | 便于识别不同的stash |
git stash list |
查看所有stash | 显示stash列表 |
git stash pop |
恢复最新stash并删除 | 恢复后从stash列表中移除 |
git stash apply |
恢复最新stash但不删除 | stash仍保留在列表中 |
git stash drop |
删除最新stash | 不恢复,直接删除 |
git stash clear |
清空所有stash | 删除所有保存的stash |
11. 最佳实践和工作流程建议
初始化仓库时的推荐配置
# 用户信息配置
git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"
# 合并策略配置(选择一种)
git config --global pull.rebase false # 推荐新手使用
# 推送策略配置
git config --global push.default simple
# 其他有用的配置
git config --global init.defaultBranch main
git config --global core.autocrlf input # Linux/Mac
# git config --global core.autocrlf true # Windows
分支命名规范
main/master
:主分支,用于生产环境develop
:开发分支,用于集成测试feature/功能名
:功能分支,如feature/user-login
bugfix/问题描述
:修复分支,如bugfix/login-error
hotfix/紧急修复
:热修复分支,如hotfix/security-patch
团队协作最佳实践
- 保持分支整洁
- 定期删除已合并的分支
- 使用
git remote prune origin
清理远程分支引用
- 提交规范
- 每次提交解决一个具体问题
- 写清楚的提交信息
- 提交前先运行测试
- 同步策略
- 开始工作前先
git pull
- 推送前先
git pull
- 使用
git fetch
查看远程更新
- 开始工作前先
常用工作流程
# 1. 开始新功能开发
git checkout main
git pull origin main
git checkout -b feature/new-feature
# 2. 开发过程中定期同步
git add .
git commit -m "WIP: 实现新功能的第一部分"
git fetch origin
git rebase origin/main # 或者 git merge origin/main
# 3. 完成开发后推送
git push -u origin feature/new-feature
# 4. 创建 Pull Request/Merge Request
# 5. 合并后清理
git checkout main
git pull origin main
git branch -d feature/new-feature