Hands-on Git experience

初级命令

创建Git仓库,Git 通过 .git 目录来管理版本历史,初始化命令用来初始化一个新的仓库。在add之前,所有文件改动都在工作区(Working Tree)add之后就在暂存区(Staging Area)commit之后就在版本库(Repository),初始化之后只有master一个主干分支

bash 复制代码
# 初始化命令,让项目文件目录变成一个git版本控制仓库
git init

# 检查当前状态,会输出有哪些文件改动未添加到暂存区
git status

# 是把改动从工作区放到暂存区,用于精确控制一次提交包含哪些内容。
git add xxx

# 提交命令,会把暂存区的内容生成一个不可变的快照,并记录作者、时间和提交信息
git commit 

更新

团队协作中每次本地提交之前核心规则,严格遵守的流程:

bash 复制代码
stash暂存起来 ---> update ---> stash pop -> commit ---> push

git本身没有update,很多IDE集成的update功能其实就是等价于git pull

bash 复制代码
# git pull等价于:

git fetch #只更新远程信息
git merge #下载远程修改并尝试合并

提交

如果说我在某个文件里面将a改成了b,然后commit了,后来发现b不如a,我又把它reset掉了。但是我又发现还是b好,这个时候可以不重新commit,即可快速回到上一次已经commit成功的状态。

bash 复制代码
# 先到reflog找到你的commit hash
git reflog
git reset --hard 你的CommitHash

触类旁通,merge本质上也是一种特殊的commit,当合并回退并不理想时,它也适用这条命令撤销合并回退。

回退

反悔刚才的提交,但代码还想留着改 → 用 git reset --soft

撤销刚才的提交,代码也不要了 → 用git reset --hard

在历史里留下一个'我撤了'的记录 → 才用 git revert

注意:revert不会让代码回到"未提交状态",它会直接生成一个"反向的新提交"。

查询记录

log很像的一个命令叫statusrefloggit log用于查看提交历史,反映项目的正式变更记录;git reflog记录HEAD的每一次移动,用于恢复误操作(如误删分支、误 reset);git status显示当前工作区和暂存区的状态,指导下一步操作。

三者的核心区别在于:log看历史,reflog看操作轨迹,status看当前状态。

bash 复制代码
# 查看提交历史,展示已经持久化到仓库中的 commit 记录。
git log

# 提交多次log内容多会分页显示,比较麻烦,这样可以单页显示
git --no-pager log

# --oneline(压缩显示) --graph(画出分支拓扑图) --all(显示所有分支) --decorate(给commit贴标签显示括号内容)
git log --oneline --graph --all --decorate

未保存修改

一般回退时IDE都会出现已经修改的文件标记为uncommittedChanges,意味着工作区还有这些修改没有操作,要么shelves暂存起来,要么全部丢弃再进行其他git操作。

丢弃

bash 复制代码
# 清空暂存区
git reset

# 清空工作区
git checkout -- .

暂存

stash就是把当前工作区/暂存区的改动临时藏起来,但不生成commit。这让git就不会在有未保存修改时阻止你回退分支节点(如上图阻止你切换分支),在你需要这些暂存起来的修改时,stash pop出来,这样这些改动就不会消失,需要时可以立即重现。

许多IDE用Shelve替代了git原生Stash功能,它并不是git自带的。存和恢复对应的操作就是ShelveunShelve

bash 复制代码
# 存起来
git stash

# 存起来并写备注
git stash push -m "备注"

# 查看stash列表
git stash list

# 恢复并删除stash记录
git stash pop

# 回复但不删除stash记录
git stash apply

# 删除某个stash
git stash drop stash@{1}

# 清空所有stash
git stash clear

恢复但不删除会在list和节点图一直显示一个stash记录:

分支

查询

bash 复制代码
# 查看当前有哪些分支
git branch

新建与删除

如果当前HEAD在要删除分支,git会直接拦截你不让你删除,这个时候需要切换到其他分支再操作。

bash 复制代码
# 新增分支
git branch XXX

# 删除分支
git branch -d XXX
git branch -D XXX

小写d是安全删除,Git 会校验:如果该分支独有代码还没合并到当前分支,就拒绝删除,防止代码丢失。

大写D强制删除。

另外如果中途存在mergerebase这类操作未完成,会强制中断,提示:

需要merge/rebase+--abort彻底终止这类交互式变基中途状态,才可以删除。

恢复已删除分支

删除了分支怎么办?可以用reflog找回。git reflog是引用日志,记录本地仓库所有HEAD移动记录。普通 git log 只能看分支上存在的提交;git reflog 能看到已经被删除、回滚、覆盖、丢弃的提交,是救丢失代码的神器。但它本身不会记录删除分支这一操作,可以找到被删除分支最后一次提交的commit ID,结合branch命令找回。

bash 复制代码
# 例如9e65c29 是被删除分支最后一次提交的commit hash
git branch feature 9e65c29

合并

合并时往往需要进入vim编辑提交信息,mergerebase一样。

bash 复制代码
# 合并分支
git merge XXX
# 合并分支时发生冲突 回退
git merge --abort
# 合并分支时冲突能够解决 继续合并
git merge --continue

merge

merge合并极大概率发生冲突,需要先编辑文件保留想要的代码,必须先add再继续合并否则会报错,再merge --continue(需要进入vim填写提交信息,i开始编辑 esc退出 :wq结束),或者commit也行,二选一。如果有多个commit节点发生冲突需要来回继续确认、解决冲突好几次,无法处理这么多冲突也可以--abort一口气放弃回到合并之前。

目前分支状态:

在develop上合并master时:

在master上合并develop时:

操作不同分支进行合并,操作分支会变到最左侧,被合并分支会有弯头指向最左侧操作分支。有意思的是,只是执行checkout操作,没有提交修改,左侧依然是最近一次提交修改的分支,只要切换了分支并有实际改动,最左侧才会立即变成操作分支。

分支A merge了分支B,只相当于A提了一次修改,B依然保持独立不受A的影响,B的上一次提交并不是这次,这次提交只针对A来说。

rebase

merge是"把两条线接在一起",rebase是"把一条线挪到另一条线的屁股后面"。rebase也叫变基操作。

rebase之前:

rebase之后:

merge 会保留完整的历史拓扑,并生成一个新的 merge commit,适合团队协作和公共分支;rebase 会把当前分支的提交移动到目标分支的最新提交之后,使历史呈线性结构,适合本地整理提交,但由于会改写历史,不适合已推送的公共分支。

撤回合并

Git允许你改自己的过去,但不允许你改别人的过去。已经push的代码可能已被同事拉取,已成为既定历史事实,你的拯救方式只能是基于当前反向修改你之前的代码,成为一次新的commit。

核心原则:

没 push → 用 git reset --hard HEAD~1(当前HEAD的前一个提交,1是相对前1个提交点)

已 push → 用 git revert -m 1 commitHash(m1指的就是操作分支的前一个提交点)。

在 merge 冲突尚未解决时,可以使用 git merge/rebase --abort 直接放弃本次合并。

摘抄

很多时候,某个分支为了某个bug打了补丁,但其他分支也想要这个修复,就需要摘抄过来,颗粒度不同于合并,需求更小,这个时候cherry-pick就上场了。

bash 复制代码
merge = 把整棵桃树搬过来
rebase = 把桃树嫁接到另一棵树上
cherry-pick = 只摘一颗桃子

Cherry-pick 是"精准投送提交"的工具,适合救火、纠错、局部合流,不适合大规模合并。

相关推荐
Co_Hui2 小时前
Git 基本使用
git
cooldream20092 小时前
AI 时代,Git 应该怎么学
人工智能·git
柒和远方4 小时前
V053: 从 Git 回退到 AI 工程治理:Vibe Coding 的 Harness 工作流与质量阀门
git·vibecoding
炸膛坦客6 小时前
Git 和 GitHub:(五)一文给出常用 Git 命令,持续更新中......
git·github
触底反弹17 小时前
Vibe Coding 不写 Git,等于悬崖边飙车
人工智能·git·面试
泡沫冰@18 小时前
基于Git、Jenkins、Podman、ECS的CI/CD实践
git·jenkins·podman
zfoo-framework19 小时前
git拦截大于5M文件
git
马里马里奥-1 天前
VS Code Git 工作树:解锁多分支并行开发新体验
git
2401_853448231 天前
Git安装流程和基础使用步骤
git·github