git不要慌,别人会的咱们也得会~~

1,557 阅读7分钟

说一千,道一万,不如来一图。😊 sourcetree

说再多,不如再来一图。🎉 sourcetree_attribute

PS: 当别人问你,你会 git 吗?你内心回答 "会",
别人再一次问你你真的会 git 吗?你可能会愣了一下,算 "会" 吧?
自信心一下就没有了😂,你是否有跟我一样的经历呢?🤔️
如果你是 git 大佬,咱们在这就可以打住了。如果你有像笔者的经历 那咱们接着往下看。

首先 git 的伟大是她把我们的代码分为以下几个区:

  • 工作区
  • 未暂存‘区’
  • 贮藏区
  • 暂存区

工作区:就是你电脑的具体位置
未暂存‘区’:你只要文件一修改,这个文件就会马上跑到未暂存‘区’
贮藏区:在未暂存‘区’或暂存区通过 git stash 命令将正在修改的文件放在"隐蔽"处
暂存区:从未暂存‘区’通过 git add 命令让文件到达暂存区

讲那么多,还是有点抽象,咱们结合上面第一张 sourcetree 图,再来一张关系图,请看👇
git_relation

PS:上面关系图出现了,本地仓库和远端仓库,是什么玩意儿?🤔

如果你有一点点的 git 基础的话,她就是一个 git 分支,通俗的理解就是一个文件夹。
本地仓库和远端仓库本质没区别,只是位置放的地方不同而已,一个是放本地一个是放在远端服务器上。

以上都是一些概念性的东西,如果你还觉得有些抽象,接下来咱们用真实的场景来一一举例。

正向流程 👉

  1. 工作区--->未暂存‘区’(任意修改文件内容

git_unsave

  1. 未暂存‘区’/暂存区--->贮藏区
git stash

git_stash

或保存贮藏区时,名称可以自定义

git stash save <name>

git_stash_name

  1. 贮藏区--->未暂存‘区’
git stash pop

git_stash_pop

或指定贮藏区内容

git stash pop stash@{<index>}

git_stash_pop_index

  1. 未暂存‘区’--->暂存区
git add .

git_add

或指定文件路径

git add index.html

git_add_xxx

  1. 暂存区--->本地仓库
git commit -m 'fix:xxx'

git_commit_xxx

逆向流程(顺序) 👈

  1. 本地仓库--->暂存区
git reset --soft HEAD^

git_reset_soft

或者另一种写法

git reset --soft HEAD~1

git_reset_soft_index

  1. 暂存区--->未暂存‘区’
git reset HEAD

git_reset_head

或指定文件路径

git reset HEAD <fileUrl> 

git_reset_head_url

或使用 git restore --staged

git_restore_staged

  1. 未暂存‘区’--->工作区
git checkout .

git_checkout_all

或者指定路径

git chckout -- <fileUrl>

git_checkout_url

或者使用 git restore

git_restore

逆向流程(跳序) 🤣

  1. 本地仓库--->未暂存‘区’
git reset --mixed HEAD^

git_reset_mixed

或者另一种写法

git reset --mixed HEAD~1

git_reset_mixed_index

  1. 本地仓库--->指定commit
git reset --hard <sha>

git_reset_hard_sha

除了以上一些正向/逆向流程,还有一些常规命令

  1. 拉取数据(将远端代码分支同步到本地代码分支)
git pull

git_pull

  1. 推送数据(将本地代码分支推送到远端代码分支)
git push

git_push

  1. 获取远端分支(将远端分支代码同步到本地)
git fetch

git_fetch

  1. 拷贝一份指定分支的副本
git checkout -b <name> <source_branch>

git_checkout_copy

如果不指定拷贝谁,默认就是拷贝当前分支

git checkout -b <copy_name>

git_checkout_copy_default

  1. 合并分支(将某个分支合并到当前分支)
git merge <source_branch>

git_merge

另外,git merge命令还支持一些选项,用于控制合并的行为。其中一些常用的选项包括:

  • --no-ff:禁用 fast-forward 合并策略,强制 git 创建一个新的合并提交。
  • --squash:将合并结果压缩为一个提交,并且不会保留源分支的提交历史。
  • -m :指定新的合并提交的提交信息。

例如,如果你想要禁用 fast-forward 合并策略并创建一个新的合并提交,可以执行以下命令:

git merge --no-ff <source_branch>

git_merge_noff_2

git_merge_noff_1

如果你想要将合并结果压缩为一个提交,并指定合并提交的提交信息,可以执行以下命令:

git merge --squash <source_branch>
git commit -m "Merge:xxx"

git_merge_squash

注意,当你使用 --squash 选项时,需要使用 git commit 命令手动提交合并结果。因为该选项会禁止 git 自动创建合并提交。

  1. 变基分支
git rebase <source_branch>

将指定的分支 变基 到当前的分支上

git_rebase_1

解释: 从 master 分支拉出一个 base 分支并提交一了一个叫 'base' 的 commit,
切换分支到 master 分支并再拉出一个 base1 分支并提交了一个叫 'base1' 的 commit,
然后切换分支到 base, 这时用 git rebase base1 ,楼上图👆,我们获得的结果如下👇

git_rebase_2

根据上面的解释,我们用一摸一样的操作再来一遍,这一次我们把 rebase 换成 merge
你会发现 commit 的顺序正常了,并且多生成了一个 merge 的 commit

git_rebase_3

还有一个操作对于个人分支值得推荐的操作 git rebase -i

PS:可以对之前提交的连续多个 commit 进行合并、批量修改注释、丢弃等操作

git rebase -i <sha>

git 从指定 commit 对应的位置的下一个 commit 到最后一个 commit 之间进行操作👇

git_rebase_i

注意: 这边的 commit 是按时间的升序从上到下排列

git_rebase_e

命令缩写含义
pickp保留该commit
rewordr保留该commit,但需要修改该commit的注释
edite保留该commit, 但我要停下来修改该提交(不仅仅修改注释)
squashs将该commit合并到前一个commit
fixupf将该commit合并到前一个commit,但不要保留该提交的注释信息
execx执行shell命令
dropd丢弃该commit

git_rebase_ee

git_rebase_n

也可以自己指定两个 commit 之间的操作

git_rebase_i_1

我们来修改第2个、第3个

重整区间:大于第一个指定 commit 到 小于等于第二个指定 commit 🐒 区间范围: commit_start < 重置内容 <= commit_end

git rebase -i ec4a997 d35198b

git_rebase_i_2

  1. 用一个新的 commit 来撤销之前提的 commit
git revert -n <sha>

git_revert_1

返做 fix:2

git_revert_2

接着我们看到以下内容

git_revert_3

命令缩写含义
--edit-e提交前编辑提交信息(默认)
--no-commit-n不创建提交,返做的内容回到暂存区
--continue--continue继续还原
--skip--skip跳过冲突提交
--abort--abort取消还原
  1. 删除分支
git branch --delete <source_branch>

如果正常删除不了,我们可以强制删除对应的分支 git branch -D <source_branch>
备注:git branch -D 是 git branch --delete --force 的简写。

git_branch_delete

  1. 给分支 commit 打标签

PS:有两种类型的标签: 轻量标签(lightweight)、附注标签(annotated)
【轻量标签】:只是某个 commit 的引用,可以理解为是一个 commit 的别名
【附注标签】:是存储在git仓库中的一个完整对象,包含打标签者的名字、电子邮件地址、日期时间以及其他的标签信息。 它是可以被校验的,可以使用 GNU Privacy Guard (GPG) 签名并验证。

git tag <tag_name> <sha>

git_tag

查看提交日志 git log --oneline git_tag_list

查看 tag 列表 git taggit tag -lgit tag --list

git_tag_l

删除 tag

git tag -d <tag_name>

git_tag_delete

创建一个 附注标签

git tag -a <tag_name> <sha> -m <remark_info>

git_tag_a

说明: -a : 理解为 annotated 的首字符,表示 附注标签
-m : 指定附注信息
git tag -a 标签名称 -m 附注信息 :直接给当前的提交版本创建一个 【附注标签】
git tag -a 标签名称 提交版本号 -m 附注信息 :给指定的提交版本创建一个【附注标签】

显示 tag 信息

git show <tag_name>

git_tag_show

git 进阶 ✨

  1. 将指定的 commit 合进当前分支
git cherry-pick <sha> <sha> <sha>...

git_cherry_pick

  1. 查看文件的具体位置最后是被谁修改过(查到写 bug 的人😆)
git blame -L <row>,<column> <fileUrl>

git_blame

  1. 修改 git 名称和邮箱
# 查看邮箱和用户名
git config --list
# 修改邮箱
git config --global --replace-all user.email “你的邮箱”
# 修改用户名
git config --global --replace-all user.name “你的用户名”
  1. 修改上一次提交的 commit 备注信息
git commit --amend

git_commit_amend

  1. 查看当前的差异
git diff

git_diff_1 git_diff_2

git diff 主要是查看 未暂存‘区’ 的差异
还有 git diff --cached 用于查看 暂存区 的差异

git_diff_cached_1 git_diff_cached_2

  1. 查看 git 下一个动作可以做什么 🚶
git status

git_status

遇到的坑 🕳️

  1. 新建一个文件,命令删除不了可以试试以下命令👇

git_clean

git clean -f

git_clean_f

或 新建一个目录带文件删除不了,可以这样删除👇

git clean -fd

git_clean_fd

git 提交规范 🚩

每当我们在提交 commit 的时候,有些人会不知道写什么备注就乱写,其实是有规范的, 例如以下写法 👀

git commit -m 'feat:xxx'
  • feat: 添加功能
  • fix: 修复问题
  • style: 修改样式
  • perf: 性能优化
  • refactor: 代码优化,重构
  • chore: 改变构建流程,依赖
  • docs: 写文档
  • merge: 合并
  • test: 测试

谢谢您观看到这 🚌,如果有错误请帮忙指出,十分感谢 🌹