Git 学习笔记

语言类型:工具类

来源: 极客时间

包含一些常用的 Git 命令和概念的解释

对指定域名(如 GitHub)设置代理

Git 设置和取消指定域名代理_夏天了啊的博客-CSDN博客

1
2
3
4
5
6
7
8
9
10
11
# 以下使用 socks5 代理
git config --global http.https://github.com.proxy socks5://127.0.0.1:1086
git config --global https.https://github.com.proxy socks5://127.0.0.1:1086

# 以下使用 http 代理
git config --global http.https://github.com.proxy http://127.0.0.1:1087
git config --global https.https://github.com.proxy https://127.0.0.1:1087

# 取消代理
git config --global --unset http.https://github.com.proxy
git config --global --unset https.https://github.com.proxy

Git log -N --oneline --all --graph

查看版本演变历史

  1. 可以使用 -n {NUM} 或者直接 -{NUM} 方式查看前 {NUM} 项记录
  2. --oneline 可以以简洁的方式展示
  3. --graph 可以展示树形结构
  4. --all 可以展示全部分支
  5. 可以执行 git help --web 通过浏览器查看所有命令详细说明

Git 中 commit/tree/blob 之间关系图

关系图

Git 中每个文件/文件夹都是一个 tree,只有内容是 blob

tree和blob区别

Git commit -am 'msg'

通过 -am 参数可以直接添加文件到 Git,而略过暂存区

Git tag xxxx aaaa

对某个 commit 打标签操作

分离头指针的情况需要注意

Detached HEAD 状态如果不创建 branch 或者 tag,后续基于该状态的修改都会被丢弃

Git branch -D xxxx

可以通过 -D 强制删除未 fully merged 的分支

Git commit --amend

修改最后一次提交的 commit 的 message 信息

Git rebase -i xxxx

变基操作,-i 表示交互式,通过 VI 编辑文件来达到修改 commit 信息的目的,其中 xxxx 应该是修改的最高父节点

Git diff --cached

检查当前 HEAD 和暂存区的文件区别

Git diff HEAD HEAD^

可以通过 HEAD 等方式指代标识符,其中 ^ 代表父节点,~ 代表上 N 层目录,例如 git diff HEAD HEAD^^ 的含义与 git diff HEAD HEAD~2 是一样的,都表示比对当前 HEAD 和他的爷节点(父节点的父节点)

Git diff -- xxxx

可以通过 -- xxxx 指定比对某个文件的差异

Git reset HEAD

可以将所有文件从暂存区撤回

Git checkout -- xxxxx

可以将工作区的 xxxx 文件恢复成暂存区的内容

Git reset HEAD -- xxxx

可以将指定的 xxxx 文件从暂存区撤回

Git reset --hard xxxx

可以强制将 HEAD 指针变更为指定 commit,需要慎用,因为所有子 commit 都会丢失

Git diff branch1 branch2 -- xxxx

可以通过指定分支名和文件名比较不同 commit 的差异

个人理解:实际上 branch 也好,tag 也罢,都是对某个 commit 做的一个 mark,如果某个 commit 没有任何 mark,则会被 Git 清理掉

Git rm xxxx

可以直接将文件在 Git 的暂存区删除

Git stash

可以将目前工作区的修改暂时藏起来

Git stash apply

可以将之前藏起来的工作区内容恢复,并且内容依旧在 stash list 中

Git stash pop

可以将之前藏起来的工作区内容恢复,但是内容不在 stash list 中

Git 备份的协议

Git备份
哑协议与智能协议区别

Git clone --bare file:///PATH/TO/PROJECT/.git BACKUP.git

--bare 指定克隆裸仓库而不提取工作区内容并克隆到远程目录

Git remote add xxx URL

添加指定远端 URL

Git push --set-upstream NAME BRANCH

推送指定上游 {NAME} 的指定分支 {BRANCH}

Git fetch NAME BRANCH

从远端 NAME 拉取指定分支 BRANCH

Git merge --allow-unrelated-histories NAME/BRANCH

可以将本地与远端的非关联的分支合并到一起,Merge 可以解决非 FAST-FORWARDS 类型,将本地和远端合并

Git merge

可以直接合并以下情况的 commit:

  1. 不同人修改了不同的文件
  2. 不同人修改了同一个文件的不同行
  3. 不同人一个人修改了文件名,另一个人修改了文件内容

针对于不同人修改了不同的文件名,执行 git merge 的时候会报冲突,需要手工解决,一般是通过 git addgit rm 解决问题

严格禁止的命令

  1. git push -f origin BRANCH

    该操作会导致以本地强行覆盖线上内容,可能导致其他人的工作成果丢失

  2. git rebase

    对集成分支千万不要执行变基操作,可能会导致其他人开发后的代码结果与线上分支产生较大差异,需要逐个 merge 或者校对,增加了他人不必要的工作量

GitHub 使用技巧

  1. 可以通过使用类似搜索引擎的搜索方式搜索,in:readme 可以实现从 README 搜索
  2. 可以通过 starts:>1000 搜索加星大于 1000 的数量
  3. 具体详细使用方式,可以通过高级搜索实现

Git Flow 模型

  1. 不具备主干开发能力
  2. 预定的发布周期
  3. 非敏捷团队
Git Flow模型

GitHub Flow

  1. 不具备主干开发能力
  2. 随时集成随时发布,测试通过后立即就可以发布
  3. 敏捷团队
GitHub Flow

GitLab Flow

  1. 不具备主干开发能力
  2. 无法控制发布时间,但是需要持续集成
  3. 需要对外发布不同版本,并进行多版本维护
GitLab Flow生产分支
GitLab Flow多分支
GitLab Flow发布分支

GitHub 针对不同情况合并的区别

原始 commit 情况

Commit信息

合并需求:Beijing 分支 -> Master 分支

Merge 的后的情况

Merge后结果

Squash 后的情况

Squash后结果

Rebase 后的情况

Rebase后结果

汇总说明

类型 合并情况 说明
Merge 创建 1 个 merge commit,可以看到引用到 Beijing 分支,直接执行了合并 适用于同应用多适配的情况,处理冲突只需要执行一次即可。例如开发某个驱动,不同型号的分支最终都要合并到主干
Squash 创建 1 个 merge commit,该 commit 包含全部 Beijing 分支和 Master 分支的区别 适用于团队主干开发方式,每个 feature 都会合并到主干并且新功能基于主干开发
Rebase 创建 个 merge commit,包含全部 Beijing 分支和 Master 分支的区别,所有 commit 信息都会被保留 适用于团队主干开发,主要与 squash 方式区别就是更加的细节,可能一个 feature 包含多个关键点,更便于追踪某个点

Git rerere

rerere 是指 reuse recorded resolution,它允许你让 Git 记住解决一个块冲突的方法,当下次遇到相同冲突时,Git 会帮你自动解决它,详情参见 Git 工具

可以通过执行 git config --global rerere.enabled true 开启 rerere 模式,然后通过手工解决第一次冲突后,执行 commit,继而回退到 HEAD 的父节点,然后 rerere 就可以生效了,再次遇到相同冲突会自动处理