对git 熟悉时,常用操作
Git
开源的分布式版本控制系统,用于跟踪文件的变更,尤其是源代码的变动
【记录代码变更,含所有版本历史,支持多人协作】
认识三个核心概念
1.工作区 开发者开发代码、文件的所在目录 【两种状态:未跟踪(Untracked)” 或 “已修改(Modified)】
2.版本库 /Repository 又叫仓库,.git 目录下的index文件 (.git/index)中,开发者本地仓库。he【工作区有一个隐藏目录 .git ,它不算工作区,而是Git的版本库】 git的核心
3.暂存区 stage或index 提交到版本库的文件修改,相当于一个 “提交预览区”
代码流转过程:
作区 →(git add
)→ 暂存区 →(git commit
)→ 版本库
各种命令
添加到暂存区 git add 命令
添加一个或多个文件到暂存区: git add [file1] [file2] ...
添加指定目录到暂存区,包括子目录: git add [dir]
添加当前目录下的所有文件改动到暂存区:git add .
添加到本地仓库中 git commit 命令 -m 添加的注释/说明
commitId - 对象哈希值
创建文件 touch file1 此时在工作区,需要 git add file1 放入暂存区
提交【暂存区全部内容】到本地仓库中:git commit -m "message"
提交【暂存区指定文件】到仓库区:git commit [fi le1] [ file2] ... -m "message"
查看提交日志 更改的详情
git log 显示 commitId + 提交者+ 提交日期 + 注释
git log --oneline 只显示 commitId + 注释
查看 Git 对象的底层命令 git cat-file [选项] <对象哈希值>
git cat-file -p 1d32ac49f6
-t:查看对象类型(commit、tree、blob、tag)
-s:查看对象大小(字节)
-p:以可读格式显示对象内容
-e:验证对象是否存在(无输出表示存在)
查看上次提交之后到现在是否对文件进行修改。 git status
【同时显示工作区和暂存区的文件状态】****
想看修改的内容 git diff 文件 【 - 代表删 , + 代表增 】
git diff HEAD 显示工作区+暂存区 vs 本地仓库HEAD的全部差异
git diff HEAD 文件全路径 针对某个文件显示 差异常用:
git diff 文件名 # 此时会显示【工作区相对于暂存区的修改】,不是与本地远程文件对比
# 查看两个分支的差异(例如 main 和 dev 分支)
git diff main dev
# 查看两个提交之间的差异
git diff 提交哈希1 提交哈希2
# 查看当前分支与远程分支的差异(例如与 origin/main)
git diff origin/main
# 查看本地当前分支的 file1 与远程 uat 分支的 file1 的差异
git diff origin/uat -- file1
# 如果本地不在目标分支(例如当前在 dev_01,想比较本地 uat 分支与远程 uat 分支的 file1)
git diff uat origin/uat -- file1
创建分支
初始:git branch dev_01; dev_01 会继承当前所在分支的所有内容
问题:我想直接 创建分支dev_02, 但是 基于 远程的 uat分支,此时本地分支是dev_01?
操作:git branch dev_02 origin/uat 基于远程uat创建本地分支 dev_02,但是没切换到 dev_02;
git checkout -b dev_02 origin/uat 创建完切换到dev_02分支 [新版git git switch -c dev_02 origin/uat]
版本回退
操作 原理 历史记录 适用场景
git reset 直接删除提交记录,移动 HEAD 指针 历史被改写,提交记录消失 本地未推送的错误提交
git revert 创建一个新提交,撤销指定提交的修改 保留原有提交,新增一个 "撤销提交" 已推送到远程的公共提交
git reset --hard HEAD~1 # 回退到上一个版本(删除最近1次提交) 【不可逆,git log 不可看,除非记得哈希值 commitId】
git reset --hard <commit-hash> # 回退到指定哈希值的版本
--hard:彻底删除修改(工作区和暂存区都重置)。
--soft:保留工作区和暂存区的修改(仅移动 HEAD)。
风险:如果已将提交推送到远程分支,使用 reset 会导致本地与远程历史不一致,强行推送会覆盖远程分支(git push -f),可能导致他人代码丢失注意:A → B → C → [git revert B] # 历史记录中新增一个撤销B的提交 a,ab,abc -> 此时撤销/还原b的修改 最终为:ac
总结:回退本质 版本库中的内容回退,工作区、暂存区是否回退 由命令参数控制
建议:涉及远程 用 revert ,只是自己本地分支,不涉及他人代码 用reset
合并分支
git checkout uat ; git merge dev_xx; 此时uat含有 本地分支 dev_xx最新的内容
问题:我的本地 分支 dev_01 ,想拉取 远程uat分支最新的数据。合并到我的本地分支
git checkout dev_01; # 先切换到本地 dev_01分支git fetch origin uat; # 更新远程分支 uat 代码
git merge oringin/uat; # 合并远程uat代码 到本地 dev_01 分支
如有冲突,解决完在提交。最后推送本地远程 git push origin dev_01;
合并完删除分支 【注意只能在其他分支下删除当前分支】
删除本地 git branch -d dev_01;
若dev_01上有未合并的修改,不让删除,防止误删除 ,此时强制删除命令 git branch -D dev_01;
删除远程 git push origin --delete dev_01; # 删除远程dev_01 分支
注意:删除完分支,最好做个清理缓存动作
git fetch --prune # 清理本地缓存的已删除远程分支
合并冲突
在XX文件中有一行 on the dev 的内容,现在我想在dev_01分支下修改它为 on the dev1 branch,在master分支下修改为 on the master branch。此时我们合并分支,就会出现是留下了dev_01分支下写的内容还是master分支下修改的内容呢?这个就是合并冲突的问题。
注意:本地切到 maser本地分支,merge dev_01 时,会出现 CONFLICT 冲突/争执 需要开发者手动去处理
比如<<<<<<<HEAD 你好======= 你不好 >>>>>>> 来表示不同的分支内容。HEAD到======= 即 你好 是 本地分支下修改的的代码,=======到>>>>>>> dev1都是dev1分支下修改的代码
关键点 出现 HEAD 指的是本地分支
手动解决完,再次进行一次提交就可以了 [删除<<<<===>>> , on the dev1 branch]
代表 我保留了 on the master branch
*** git log --graph --abbrev-commit 图形化方式展示提交历史
注意:正常合并 分支,里面没冲突时,删掉合并的分支dev_01,此时 git log --graph --abbrev-commit 看不到文件修改咋来的,是dev_01改动,还是master改的?其实没啥,但是我想保留这种记录,遗迹。好办命令: git merge --no-ff -m "merge dev_01" dev_01; 这种是【强制禁用 Fast forward 模式。那么就会在 merge 时生成一个新的 commit ,这样, 从分支历史上就可以看出分支信息】
bug分支
问题:正在本地dev_01分支开发代码,突然 uat分支有bug 【bugfix_xx】,或者 生产有问题 【hotfix_xx,repair_xx】,怎么解决?
1.本地分支暂时没修改任何代码, 直接创建 git checkout -b bugfix_01 origin/uat;
2.本地分支改的有代码 ep:切换 git checkout dev_02,此时dev_01上修改的代码,在dev_02 分支下也可以看到,开发者不想看到,避免后面提交 将其也提交了。
操作:先执行 git stash 暂存代码到 【储存空间】,工作区干干净净,再 git checkout dev_02,修改代码即可。
问题:接上述问题我都改完了,想接着开发dev_01分支上代码?【从储存空间将之前改的内容还原出来】
操作:
1.git stash list/查看暂存列表 ;
2.git stash pop # 恢复最近一次暂存并删除该暂存记录(常用) 或者 git stash apply # 恢复最近一次暂存(stash@{0}),暂存记录仍保留
如需恢复指定暂存,可加上编号:git stash apply stash@{1}
问题:恢复后改完代码,暂存记录不想要了?
操作:git stash drop stash@{0} # 删除指定暂存 ;git stash clear # 清空所有暂存
标签管理 标记代码库中关键节点【发布版本、项目重要时期的节点】
对某次 commit 的添加一个标识,相当于起了一个别名。因为commitId太难记了,我只容易记得tag 【有意义,比如你的功能名,方便回退/回溯 版本】
创建标签: git tag -a v1.0 -m "正式发布 v1.0版本"# -a: 表示创建附注标签,# -m: 标签的说明信息
问题:我想给之前某个提交打标签,当时忘记打了。记住指定当时提交的哈希值/commitId
操作: 1.git log --oneline 查看历史提交记录,获取哈希值
2.git tag -a v0.1 abc5fg2d -m "修复xx功能版本"
查看标签: git tag查看标签详情: git show v1.0 [标签名] 只是看的当时添加的注释
标签打在本地,如何推送远程分支:git push origin v1.0.0 # 推送单个标签到远程 ;git push origin --tags # 推送所有本地未推送的标签到远程
查看标签对应的代码:git checkout v1.0 【只是让你看,不建议直接修改】
基于标签创建新分支:git checkout -b fix-v1.1 v1.0.0 【从标签创建一个新分支,在分支上进行修改】 这时可以修改代码
删除标签: 本地 git tag -d v1.0.0
远程 1.git tag -d v1.02. git push origin --delete v1.0 # 先删除本地,再推送删除指令
详细git介绍 参考文章GitHub简述+git配置+git命令操作_github配置-CSDN博客