Git Advanced
1 仓库连接
1.1 本地添加远程仓库链接
git init
git branch -M main
git remote add origin git@github.com:*/*.git
1.2 直接克隆远程仓库
git clone url.git
2 分支
2.1 合并冲突
正常合并会是这样
$ git checkout master
Switched to branch 'master'
$ git merge issue2
Updating b2b23c4..8f7aa27
Fast-forward
myfile.txt | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
当同一行被多个分支修改时,会出现合并冲突

要处理git中的合并冲突,有以下几个步骤:
- 使用
git status命令查看哪些文件有冲突 - 使用
git diff命令查看具体的冲突内容 - 打开冲突文件,找到由<<<<<<< ======= >>>>>>>标记的部分
- 根据需要编辑冲突文件,保留或删除不同分支的修改,或者合并它们
- 删除<<<<<<< ======= >>>>>>>标记,保存并关闭文件
- 使用
git add命令将解决了冲突的文件添加 到暂存区 - 使用
git commit命令提交合并结果
2.2 快进合并
当一个分支是另一个分支的直接后继时,可以不保留分支记录,直接快进,仿佛这一条分支没有发生过。Git 默认尽可能快进合并
正例:
A --- B (main)
\
C --- D (feature)
--->
A --- B --- C --- D (main, feature)
反例:
A --- B --- E (main)
\
C --- D (feature)
---> × 因为 E 不是 D 的“祖先“
2.3 分支切换
git checkout branch_name
分支切换
2.4 分支变基
git rebase,分支变基的作用是 把一个分支的提交“搬”到另一分支的最前面,使提交历史保持 线性,方便追踪与协作。

历史线性,同时 C, D 仿佛是 E 之后才开发的
A --- B --- E (main)
\
C --- D (feature)
--->
A --- B --- E --- C' --- D' (feature)
但要注意不要对共享分支做 rebase,例如常见的 develop, main,正确的做法是
git checkout feat
git rebase main
3 删除文件
直接从 windows 资源管理器删除文件是可以的,但是 git版本库的信息未更新, git会认为含有这个文件,需要 git add deleted.file
建议 Git GUI 或者 git rm 命令
4 回档文件
Git 提供了多种方法来 恢复或回档文件,取决于你想恢复的状态:工作区、暂存区还是历史提交。
4.1 回档工作区文件(未暂存修改)
如果文件在工作区修改过,但还没有 git add 暂存,可以使用:
git restore <file>
例子:
```bash
echo "hello world" > test.txt
git status
# 修改未暂存
git restore test.txt
# test.txt 被恢复到上一次 commit 的状态
4.2 回档暂存区文件(已 git add)
如果你已经 git add 了文件,但想撤销暂存:
git restore --staged <file>
- 功能:取消暂存,将修改保留在工作区
- 示例:
git add test.txt
git restore --staged test.txt
git status
# test.txt 从暂存区移除,但修改仍在工作区
4.3 恢复文件到某个提交状态
如果想将文件回退到 历史某个 commit 的状态:
git restore --source <commit> <file>
- 示例:
git log --oneline
# 查到 commit 1234abcd 是目标版本
git restore --source 1234abcd test.txt
- 功能:将 test.txt 回退到 commit
1234abcd的状态
注意:
--source可以是提交哈希、分支名或 tag。
4.4 丢弃所有未提交的修改
如果想丢弃 工作区和暂存区 的所有修改:
git restore --staged --worktree .
或者旧版本 Git:
git reset --hard
5 回退版本
5.1 基础概念
- HEAD:当前版本(最新提交)
- ~:向上回退 n 个提交(默认 1)
- ^:指定父提交(多用于 merge 提交)
--hard会丢弃工作区和暂存区修改--soft/--mixed可保留修改
5.2 回退操作
5.2.1 回退到上一个版本
git reset --hard HEAD~
5.2.2 回退多个版本
git reset --hard HEAD~2
5.2.3 回退到指定提交
git log --pretty=oneline # 查看提交记录
git reset --hard <commit-id>
5.3 ^ 与 ~ 的区别
| 符号 | 用法 |
|---|---|
~ |
连续回退 n 个提交,例如 HEAD~2 |
^ |
指定父节点,多用于 merge,例如 HEAD^2 |
示例:
M 有多个“祖先”,^1 表示第一个祖先 B,^2表示第二个祖先 D
A --- B --- M (merge)
\ /
C--D
HEAD^ -> B
HEAD^2 -> D
HEAD~2 -> A

6 git标签
git tag -a <tagname> -m <tag message> ,tag 也需要以 commit 提交,如果提交时没有文件更新,那么提交会失败,所以应当保证进行了文件操作后,加上 tag,然后一起提交
git add *
git commit -m "*"
**git tag -a beta-v0.0.0.1 -m "init"git push`
git tag -n 可以显示标签的列表和注解。
git tag -n
apple first commit
banana 连猴子都懂的Git
7 git日志
如果在log命令添加 --decorate选项执行,可以显示包含标签资料的历史记录。
git log --decorate
commit e7978c94d2104e3e0e6e4a5b4a8467b1d2a2ba19 (HEAD, tag: apple, master)
Author: yourname <yourname@yourmail.com>
Date: Wed Jul 18 16:43:27 2012 +0900
first commit
8 git分支流与项目开发
8.1 简单版本
- 本地 dev 分支提交到远端开发分支
- 本地 main 分支同步远端 main 分支,即拉取下来
- 本地 dev 分支下 rebase main(不能反过来,会导致主分支被 rebase ,产生混乱),并解决 rebase conflict
- 本地 dev 分支 pr 到远端 main 分支
B站码农高天:pull rebase解决main版本领先问题,然后每一次commit之后,分支是否应该删除呢?可以删除,但不建议。
一个热评:合并前不要去git merge并且提交前使用rebase -i 去压缩提交次数。

8.2 复杂版本
- 结合 pull request的方式去做Code Review。
- 如下图所示,我们的程序刚创建时只有默认的master分支,也就是节点A,这时我们需要进行功能版本的开发,于是从A节点签出一个Develop分支,这时就有了节点B,于是产品需要开发新功能时,从B,C的时间节点签出了D,E进行功能开发,功能开发完成后相继有了节点F,G,然后将完成的新功能合并到Develop分支上,有了节点H,然后需要发布,签出到Release分支,有了节点I,然后进行测试,测试中发现Bug,由程序员修复,进而有了J,K节点,然后测试完成,将预发布合到Develop和Master分支上,得到了节点L,M,M节点需要打上相应的tag,标记是一个发布版本,然后项目上线,上线后出现紧急Bug,需要签出到HotFix分支,进行修复,修复后将代码签入Develop和Master分支。其中Feature、Release、HotFix完成合并到Develop和Master后需删除对应的分支。
9 Trick
- 网速较慢时,--depth=1 能够使得只克隆最近一次的提交
- 网速较慢时,ssh连接一般有帮助
- ssh 连接
cd ~/.ssh
ls id_rsa.pub 观察有无
ssh-keygen -t rsa -C "your_mail@google.com"
ssh -T git@github.com
Hi ***! You've successfully authenticated, but GitHub does not provide shell access.
10 命令备忘
git config- 设置用户名和邮箱地址,用于Git提交时记录。
- 例子:
$ git config --global user.name "John Doe"和$ git config --global user.email johndoe@example.com
.gitignore- 设置文件的忽略规则,让一些文件不会被记入仓库的更改中。
.gitattributes- 设置文件的属性。
git init- 把当前目录变成Git仓库。
- 例子:
$ git init
git clone- 克隆远程仓库到本地。
- 例子:
$ git clone https://github.com/libgit2/libgit2
git status- 查看当前仓库的状态(有哪些文件修改了,有哪些文件暂存了等)。
- 例子:
$ git status
git add- 将修改的文件提交到暂存区。
- 例子:
$ git add file.cpp或$ git add .
git commit- 提交更新,将暂存区的文件快照永久性存储到Git目录。
- 执行命令后会弹出文本编辑器,用于编辑提交说明。
- 例子:提交更新命令,后面通常会跟随提交说明。
git checkout- 还原文件到上一个提交时的状态。
- 例子:
$ git checkout file.cpp
git rm- 从Git仓库中删除文件。
- 注意:这也会在磁盘中删除文件,除非使用
--cached选项。
11 学习资源
git工作流 | 码农高天
[猴子都能懂的git入门]
Simple Git tutorial for beginners | Nulab