以跟踪,未跟踪文件详情:
lifecycle

2.6 打标签

轻量标签与附注标签的区别

轻量标签很像一个不会改变的分支————它只是某个特定提交的引用,它本质上是将提交校验和存储到一个文件中。
而附注标签是存储在 Git 数据库中的一个完整对象, 它们是可以被校验的,其中包含打标签者的名字、电子邮件地址、日期时间, 此外还有一个标签信息,并且可以使用 GNU Privacy Guard (GPG)签名并验证。 通常会建议创建附注标签,这样你可以拥有以上所有信息。
如果你只是想用一个临时的标签, 或者因为某些原因不想要保存这些信息,可以用轻量标签。

7.7 重置揭密

三颗树

| 树 | 用途 | | —- | —- |

| HEAD | 上一次提交的快照,下一次提交的父结点 |

| Index | 预期的下一次提交的快照 |

| Working Directory | 沙盒 |

下图就是这三棵树的工作流程:
三棵树工作流程
当初始化一个 Git 仓库时,这三棵树长这样:
git_init
通过几次提交,就成了这样
git_commit

Git reset 与 Git checkout 对比

|

| HEAD | Index | Workdir | WD Safe? (磁盘安全) | | —- | —- | —- | —- | —- |

| Commit Level | | | | |

| reset --soft [commit] | REF | NO | NO | YES |

| reset [commit] | REF | YES | NO | YES |

| reset --hard [commit] | REF | YES | YES | NO |

| checkout | HEAD | YES | YES | YES |

| File Level | | | | |

| reset [commit] | NO | YES | NO | YES |

| checkout [commit] | NO | YES | YES | NO |

7.8 高级合并

revert 的注意事项

revert 在还原合并分支提交时,有一些需要注意的点。
想来看一个案例:现在有两个分支:mastertopic,且两分支已经合并
意外的合并提交
你可以使用 git reset --hard HEAD~ 来很好的返回这次合并。但是该提交已经被传到云上,为了照顾你的队友,你选择使用 revert

  1. $ git revert -m 1 HEAD

这里 -m 1 是为了和 C6 保持一致,如果换成 -m 2 那就和 C4 保持一致了
在 `git revert -m 1` 后的历史
第一个需要注意的点是,你现在无法合并了

  1. $ git merge topic
  2. Already up-to-date.

因为 topic 已经成了 master 分支的子节点,所以会显示目前没有什么要合并的(你可以选择 rebase topic ,他会将 C5C6 变基到 C4 的后面)
如果你继续在 topic 上提交代码,并合并到 master 分支上,Git 只会引入被还原的合并 之后 的提交(如下图所示,只有 C7 的修改引入了 C8,而 C3C4 没有)
含有坏掉合并的历史
解决这个最好的方式是撤消还原原始的合并,这样你想要引入被还原出去的修改。但会提交看起来会更加复杂

  1. $ git revert ^M
  2. [master 09f0126] Revert "Revert "Merge branch 'topic'""
  3. $ git merge topic

在重新合并一个还原合并后的历史
在本例中,M^M 抵消了。 ^^M 事实上合并入了 C3C4 的修改,C8 合并了 C7 的修改,所以现在 topic 已经完全被合并了。

7.11 子模块

请点这里

8.2 Git 属性

基于路径的设置项被称为 Git 属性,可以在你的目录下的 .gitattributes 文件内进行设置(通常是你的项目的根目录)。如果不想让这些属性文件与其它文件一同提交,你也可以在 .git/info/attributes 文件中进行设置。
.gitattributes

  1. // 把所有 pbxproj 文件当成二进制文件
  2. *.pbxproj binary
  3. // 所有匹配 .docx 模式的文件都应该使用 "word" 过滤器。 "word" 过滤器需要自己配置
  4. *.docx diff=word
  5. // 所有匹配 .png 模式的图片都应该使用 "exif" 过滤器。
  6. *.png diff=exif
  7. // 对 filter 属性设置 "indent" 过滤器来过滤 *.c 文件
  8. *.c filter=indent
  9. // 不想在使用 git archive 创建的压缩包中包含 test/ 子目录或文件,但想把它们纳入项目的版本管理中
  10. test/ export-ignore
  11. // 在项目中包含一个叫做 LAST_COMMIT 的文件, 并在运行 git archive 的时候自动向它注入最新提交的元数据(可以直接使用 git log 中 pertty=format 中的处理器)
  12. LAST_COMMIT export-subst
  13. // 配置 database.xml 使用自定义的 ours 策略
  14. database.xml merge=ours

设置在 .gitattributes 中的文件,不会尝试转换或修正回车换行(CRLF),运行 git showgit diff 时,也不会比较或打印该文件的变化。
配置过滤器

  1. # 配置 "word" 过滤器,其中 docx2txt 是可执行命令,也可以是自己创建的 shell 文件
  2. $ git config diff.word.textconv docx2txt
  3. # 配置 "exif" 过滤器,其中 exiftool 是可执行命令
  4. $ git config diff.exif.textconv exiftool
  5. # 配置 "indent" 过滤器在 smudge 和 clean 时分别该做什么
  6. $ git config filter.indent.clean indent(此处,也可以是一个脚本文件)
  7. $ git config filter.indent.smudge cat(或一段命令)
  8. # 自定义虚拟合并策略为 ours ,这样会让该文件保持主干分支中的原始版本
  9. git config merge.ours.driver true

自定义过滤器真的很强大。不过注意的是,因为 .gitattributes 文件会随着项目一起提交,而过滤器(不会,所以过滤器有可能会失效。

8.3 Git 钩子

请看这里

10.1 内部原理

从根本上来看,Git 是一个内容寻址文件系统。
对于一个全新的 git 版本库来说 .git 目录下的内容为:

  1. $ ls -F1
  2. branches/ ->
  3. config -> 包含项目的配置选项
  4. description -> GitWeb 程序使用
  5. HEAD -> 当前被检出的分支,如果不是分支,那就是分离 HEAD 情况
  6. hooks/ -> 包含服务端或客户端的钩子脚本
  7. info/ -> 包含一个全局性排除文件,用于放置不希望记录在 .gitignore 文件中忽略模式
  8. objects/ -> 存储所有的数据内容
  9. +--- info -> 索引文件,包含了包文件的偏移信息
  10. \--- pack -> 包目录,将对象进行打包。包文件可以通过索引文件快速定位任意指定对象
  11. refs/ -> 存储指向数据(分支、远程仓库和标签等)的提交对象的指针
  12. # 以下是第一次创建并不会有,但是在后续的使用中会出现
  13. index -> 保存暂存区信息
  14. └── 49b077972391ad58037050f2a75f74e3671e92
  15. ├── info
  16. └── packs
  17. └── pack

在 Git 中,都用 zlib 压缩的内容来写入磁盘上的某个对象