git
默认情况下,克隆的远程仓库会被命名为 origin
shell
git remote remove origin
# 移除默认的远程仓库 origin
git remote add origin https://github.com/CS144/minnow.git
# 添加一个新的远程仓库 origin,指向自己的 GitHub 仓库
git branch -M main
#将当前分支重命名为 main(如果默认分支是 master,这一步会将其改为 main)
git push -u origin main:
# 将本地的 main 分支推送到远程仓库 origin,并设置 origin/main 为上游分支(-u 参数的作用)
# 之后可以直接使用 git push 和 git pull,而不需要指定远程分支
git remote add upstream https://github.com/CS144/minnow.git
# 添加一个新的远程仓库 upstream,指向原始的上游仓库
# 保留与上游仓库的连接,以便后续可以拉取上游的更新
git remote -v
# 查看远程仓库列表
git fetch upstream(前面设置的https://github.com/CS144/minnow.git,将仓库改为upstream名,origin是git clone后默认的名;) branch_name
# 拉取upstream的分支名
git branch -d <branch_name>
# 删除已经合并的本地分支
git branch -D <branch_name>
# 强制删除本地分支
git merge upstream/check1-startercode
# 将上面拉取的upstream/check1-startercode合并到本地分支main中
git 提交
A <- B<- C(main)
- A是第一次提交;
- B是第二次提交;
- C是第三次提交;
- 当前C是最新一次的提交,所以main分支当前指向了C
git 创建新分支
假设现在 基于main分支创建了一个 新分支 feature:
shell
git checkout -b feature
-
feature
分支也指向提交C
,并且继承了C
的所有父提交(B
和A
) -
在
feature
分支上开始新的工作,比如修改文件并提交:A <- B <- C (main) \ D (feature)
-
通过创建
feature
分支,可以在不影响main
分支的情况下进行新的开发 -
完成工作后,可以将
feature
分支合并回main
分支,或者继续在feature
分支上开发
git 合并分支merge
git merge 命令合并两个分支时,Git 会尝试将两个分支的历史记录整合到一起
假设有以下提交历史:
A <- B <- C (main)
\
D <- E (feature)
main
分支的最新提交是C
feature
分支的最新提交是E
- 它们的共同祖先是提交
A
执行 git merge feature
(在 main
分支上合并 feature
分支)时,Git 会创建一个新的合并提交 F
:
A <- B <- C <- F (main)
\ /
D <- E <- (feature)
- 合并提交
F
有两个 parent 节点:- 第一个 parent 是
C
(main
分支的最新提交) - 第二个 parent 是
E
(feature
分支的最新提交)
- 第一个 parent 是
- 通过
F
,Git 可以同时访问main
和feature
分支的所有历史记录
git rebase
Git 中另一种合并分支的方法;通过"重新定位"提交记录来创造更线性的提交历史
-
找到当前分支和目标分支(通常是 main 或 master)的共同祖先
-
将当前分支上新增的提交提取出来,保存为临时文件
-
将当前分支指向目标分支的最新提交
-
将提取的提交逐个重新应用到目标分支的最新提交之后
A <- B <- C (main) \ D <- E (feature)
Rebase之后:
A <- B <- C <- D' <- E' (feature)
(main)
HEAD
使用git checkout <commit-has>
可以让HEAD
直接指向某个提交记录,从而分离HEAD
^操作符
^
操作符 用于访问某个提交记录的 父节点
假设:
C0 <- C1 <- C2 <- C3 (main)
-
main
分支的最新提交是C3
git checkout main^
-
此时
HEAD
会指向C2
git checkout main^^
- 此时,
HEAD
会指向C1
切换分支的父节点
git branch -f main C6
- 强制将
main
分支指向提交记录C6
git branch -f
用于强制移动分支的指向- 将
main
分支移动到提交记录C6
,无论main
分支之前指向哪里
git checkout HEAD~1
- 将
HEAD
移动到当前提交记录的第一个父节点
git branch -f bugFix HEAD~1
强制将 bugFix 分支指向当前 HEAD 的父节点
reset 和 revert 撤回
假设原始提交链条:
C0 <- C1 <- C2 <- C3 (HEAD -> main)
执行 git reset C1
后:
C0 <- C1 (HEAD -> main)
C2
和 C3
被丢弃(但内容可能保留在工作目录,取决于 reset
的模式)
--soft
:仅移动分支指针,保留工作目录和暂存区的修改--mixed
(默认):移动分支指针,并重置暂存区,但保留工作目录的修改--hard
:彻底丢弃所有修改,分支指针、暂存区和工作目录全部回退
git revert
:撤销某个提交
假设原始提交链:
C0 <- C1 <- C2 <- C3 (HEAD -> main)
执行 git revert C3
后:
C0 <- C1 <- C2 <- C3 <- C4 (HEAD -> main)
C4 是一个新提交,内容是撤销 C3 的更改
此时:++C4
的内容与 C2
相同++
git cherry-pick
- 复制提交:将某个提交的更改应用到当前分支,生成一个新的提交
- 选择性合并:只合并某个分支上的特定提交,而不是整个分支
- 将修复 bug 的提交从开发分支应用到生产分支
假设以下提交历史:
C0 <- C1 <- C2 (main)
\
C3 <- C4 <- C5 (feature)
现在:将 feature
分支上的提交 C4
应用到 main
分支
git checkout main
git cherry-pick C4
-
结果:
C0 <- C1 <- C2 <- C4' (main) \ C3 <- C4 <- C5 (feature)
C4'
是C4
的副本,++内容与C4
相同,但哈希值不同++
UI交互式变基 Interactive Rebase
Git 中一种高级操作,通过 git rebase -i
命令触发。它允许你以更精细的方式修改提交历史,例如重写、合并、拆分或删除提交
git rebase -i <目标提交>
git pull
git pull
就是 git fetch 和 git merge 的缩写
git pull --rebase; git push
如果远程仓库被别人提交了一次,本地的o/main没有更新,就无法push到远程仓库;
此时:
- 拉取远程仓库的新更新;
- 然后将本地的一次提交,合并后再push