Git

个人信息

git1

一般工作流

git2
git3
git4

diff

git5

删除重命名分支切换创建

git6

提交到远程

git7

fetch pull rebase

  1. git fetch

举例:

git fetch origin

这个命令会从远程仓库 origin 拉取所有更新,但不会改变你当前分支的代码。

远程 origin/main:
A --- B --- C --- R1 --- R2

本地 main:
A --- B --- C --- L1

远程追踪分支 origin/main:  指向 R2

  1. git pull

举例:

git pull origin main

从远程 originmain 分支拉取代码并合并到当前分支。

          L1
          |
A --- B --- C --- R1 --- R2
               \       /
                --- M  (合并提交)

本地 main HEAD -> M

  1. git rebase

举例:

git fetch origin
git rebase origin/main

先抓取远程最新代码,然后把当前分支的修改,放到 origin/main 最新提交之后,相当于“更新基础”了。

远程 origin/main:
A --- B --- C --- R1 --- R2

本地 main:
A --- B --- C --- R1 --- R2 --- L1'

但是你本地的提交可能与远程提交的R1 R2有冲突,但一般只有在极少数冲突情况下需要手动解决

如果你的提交和远程提交修改了同一个地方,rebase 会提示冲突,需要你手动解决冲突。

解决完冲突后,继续执行 git rebase –continue,完成变基。


总结对比:

命令 作用 是否合并到当前分支 是否产生合并提交 适用场景
git fetch 拉取远程最新代码,不改变本地代码 查看远程更新,准备后续操作
git pull 拉取并合并远程代码到当前分支 可能 快速同步远程最新代码
git rebase 变基,把当前分支基于另一个分支更新 保持提交历史整洁,线性化代码历史

模拟fetch rebase pull

好的!我用一个具体的模拟例子,用命令行交互的形式,演示 git fetchgit pullgit rebase 的典型流程和效果。方便你更直观理解。


场景假设


  1. 初始状态
# 本地仓库
git log --oneline

# 输出:
C (HEAD -> main) 本地提交L1
B
A

# 远程仓库 origin/main 最新提交比本地多两个
# 远程代码比本地多了 R1 和 R2 两个提交
# 远程分支状态(假设你本地未同步):
origin/main:
E (R2)
D (R1)
B
A

  1. git fetch
git fetch origin

# fetch 只是更新远程追踪分支,不影响本地 main
git log origin/main --oneline

# 输出:
E (origin/main)
D
B
A

git log main --oneline

# 输出:
C (main)
B
A

说明origin/main 更新了远程最新提交,main 还是原来的状态。


  1. git pull
git pull origin main

# 实际等于 fetch + merge,合并远程 main 到本地 main

# 可能会生成一个新的合并提交 M

git log --oneline

# 输出:
M (HEAD -> main) 合并提交
C (本地提交)
E (origin/main)
D
B
A

说明main 分支包含了远程最新提交和本地提交,并生成了一个合并提交 M


  1. git fetch + git rebase

先 fetch:

git fetch origin

然后 rebase:

git rebase origin/main

# git 会把本地提交 C(L1)暂存起来,把 main 基底切换到 origin/main 最新提交 E
# 然后把 C 重新应用到 E 之后

git log --oneline

# 输出:
C' (HEAD -> main) 变基后的本地提交(内容同C)
E (origin/main)
D
B
A

说明


  1. 如果遇到冲突
git rebase origin/main

# 途中如果出现冲突,Git 会提示:

CONFLICT (content): Merge conflict in file.txt
# 需要手动解决冲突,编辑冲突文件

# 解决完后:

git add file.txt
git rebase --continue

# 继续变基直到完成

如果本地没有commit 然后 git fetch新内容后,执行git rebase会提示

root@ser745692301841:/dev_dir/note# git rebase
error: cannot rebase: You have unstaged changes.
error: Please commit or stash them.

这个错误的意思是:

你当前工作区有 未暂存(unstaged)的修改,Git 为了防止这些改动丢失或冲突,不允许你直接执行 git rebase

解决方法有两个:

  1. 提交当前修改
git add .
git commit -m "保存当前修改,准备rebase"
git rebase ...
  1. 暂存当前修改(stash)
git stash save "临时保存修改,准备rebase"
git rebase ...
git stash pop  # rebase完成后恢复修改

为什么要这样?

root@ser745692301841:/dev_dir/note# git rebase
error: cannot rebase: You have unstaged changes.
error: Please commit or stash them.
root@ser745692301841:/dev_dir/note# git stash save "临时保存修改,准备rebase"
Saved working directory and index state On main: 临时保存修改,准备rebase
root@ser745692301841:/dev_dir/note# git rebase origin/main
Successfully rebased and updated refs/heads/main.
root@ser745692301841:/dev_dir/note# git stash pop
On branch main
Your branch is up to date with 'origin/main'.

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   convert_md_to_html.sh

no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (f869fb6c69bad5bec7aa96ed8401bb9c3a297c7d)
root@ser745692301841:/dev_dir/note# git log --oneline
04a4909 (HEAD -> main, origin/main, origin/HEAD) feat: version control tool
f8cb14e update: 目录整理
4b9fccb feat: 必知必会 整理目录

给你详细解释一下 git stash savegit stash pop 在 Git 背后做了什么。

git stash save "说明信息"

这个命令的作用是:

具体背后发生的事:

git stash pop

这个命令的作用是:

背后发生的事:

命令 背后原理 作用
git stash save 创建临时提交,把修改存到 stash 栈顶 保存当前改动,恢复干净工作区
git stash pop 取出 stash 栈顶提交,应用到工作区 恢复之前保存的修改,并从 stash 中删除