【Git 学习笔记_11】第五章 在 Git 仓库存入附加信息(上)

第五章 在 Git 仓库存入附加信息

相关主题

  • 添加第一条 Git 笔记
  • 按类别区分 Git 笔记
  • 从远程库读取 Git 笔记
  • 推送 Git 笔记到远程库
  • commit 版本添加标签

Git 最强大的一个特性,在于它的提交历史 永不可改变 。这意味着任何试图篡改仓库历史的行为,对于其他克隆该仓库的人来说 都是可见的 。这一特性也给开发者带来些许困扰,尤其是需要在已经发布的提交记录中修改版本注释信息的时候。正是由于 git 历史的不可变更性,git 笔记(notes)才应运而生。本质上,git 笔记是 refs/notes/commits 引用的附加版。笔记内容既可以在执行 git log 命令时,随提交信息一同展示出来,也可以发布到远程仓库供其他人获取笔记。

5.1. 添加第一条 Git 笔记

本节将在已发布的版本中添加附加信息。如果直接修改目标版本,则 commit 的哈希值也会变动。以 jgit 库为例,先演示直接修改历史版本的效果,再给出使用 git 笔记的演示方案。

bash 复制代码
# Clone repo
$ git clone https://git.eclipse.org/r/jgit/jgit chapter5
$ cd chapter5 
# Checkout a new branch based on stable-3.2
$ git checkout -b notesMessage  --track origin/stable-3.2
# Check HEAD hash: f839d383e6fbbda26729db7fd57fc917fa47db44
$ git log -1 
# Edit commit message, add 'Update MANIFEST files'
$ git commit --amend
# Check HEAD hash: f942f7b58238b5aaac566038a7d67e0cb6a02fe1
# commit hash diverged
$ git log -1 
# See the change via status
$ git status
# via gitk
$ gitk origin/stable-3.2 HEAD

结果如下:(版本结构已发生变化)

这时使用 git notes 就可避免:

bash 复制代码
# Resume
$ git reset --hard origin/stable-3.2
# Add a git note
$ git notes add -m 'Update MANIFEST files'
# Check git log (f839d383e6fbbda26729db7fd57fc917fa47db44)
$ git log -1
commit f839d383e6fbbda26729db7fd57fc917fa47db44 (HEAD -> notesMessage, origin/stable-3.2)
Author: Matthias Sohn <matthias.sohn@sap.com>
Date:   Wed Dec 18 21:16:13 2013 +0100

    Prepare post 3.2.0 builds

    Change-Id: Ie2bfdee0c492e3d61d92acb04c5bef641f5f132f
    Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>

Notes:
    Update MANIFEST files
# Check status (not diverged)
$ git status
# (No changes)

虽然 git notes 没有在原记录上直接修改(像 --amend 那样),但也实现了对历史提交信息进行增补,且不影响原有的树形版本结构。

拓展

除了通过 git notes add 新增一个 git 笔记,还可以强制替换(-f)、追加(append)、编辑(editgit 笔记:

bash 复制代码
# force to add notes (replace the old one)
$ git notes add -f -m "Update MANIFESTS files for next version"
# append content to a note
$ git notes append -m "Verified by John Doe"
# Show in the log via --notes
$ git log --oneline --notes
f839d383e (HEAD -> notesMessage, origin/stable-3.2) Prepare post 3.2.0 builds
Notes:
    Update MANIFESTS files for next version

    erified by John Doe

# Edit a note (this would replace the old note with 'John Doe')
$ git notes edit -m 'John Doe'
The -m/-F/-c/-C options have been deprecated for the 'edit' subcommand.
Please use 'git notes add -f -m/-F/-c/-C' instead.
# git notes edit without any arguments would be the same as git notes add
$ git log --oneline --notes -1
f839d383e (HEAD -> notesMessage, origin/stable-3.2) Prepare post 3.2.0 builds
Notes:
    John Doe

更多子命令,详见 git help notes

小结

  1. git notes edit -m 的用法已被淘汰,Git 推荐使用 git notes add 来替换 git notes edit
  2. 决定 commit 哈希值的三个因素:
    1. 版本内容(the content in the commit)
    2. 父级版本(the parents of the commit)
    3. 提交信息(the commit message)

5.2 按类别区分 Git 笔记

正如上一节提到的,git 笔记本质上是一个命名空间为 refs/notes/ 的引用,默认展示在 git log 中的是 refs/notes/commits 引用。此外还可以自定义笔记类别,如 featureImplementeddefectalsoCherryPick 等等,以便对笔记统一归类管理。

本例的演示场景:假设在项目中修正了一个缺陷(defect),产生了一个 commit 版本,同时还对受该缺陷影响的其他版本做了同步修复。示例将新建一个 git 笔记类型 refs/notes/alsoCherryPick,用来说明当前版本如果要被 cherry-pick 到其他分支,那么应该同时将 alsoCherryPick 中提到的相关 commit 版本一并带上,因为它们都是对同一缺陷的修复。

bash 复制代码
# Checkout new branch
$ git checkout -b notesReferences --track origin/stable-3.1
# List commits for use
$ git log -10 --oneline
da6e87bc3 (HEAD -> notesReferences, origin/stable-3.1) Prepare post 3.1.0 builds
16ca725b3 (tag: v3.1.0.201310021548-r) JGit v3.1.0.201310021548-r
c6aba9966 Fix order of commits in rebase todo file header
5a2a2222e Prepare post 3.1.0 RC1 builds
6f0681eb9 (tag: v3.1.0.201309270735-rc1) JGit v3.1.0.201309270735-rc1
a065a06c2 Attempt to fix graph layout when new heads are introduced
b4f07df35 Prepare re-signing pgm's ueberjar to avoid SecurityException
aa4bbc67b Use full branch name when getting ref in BranchTrackingStatus
570bba5e7 Ignore bitmap indexes that do not match the pack checksum
801aac579 Merge branch 'stable-3.0'

# Add notes for current HEAD
$ git notes add -m "test note"
# Select a commit (570bba5) categoried as alsoCherrypick
$ git notes --ref alsoCherryPick add -m "570bba5" b4f07df
# Check in the log view with --notes
$ git log -1 b4f07df --notes=alsoCherryPick
# config the alsoCherryPick notes' reference by default
$ git config notes.displayRef "refs/notes/alsoCherryPick"
# config to show all notes with all categories
$ git config notes.displayRef 'refs/notes/*'
# Test to add a new note with category of 'defect'
$ git notes --ref defect add -m "Bug:24435" b4f07df
# Check to see whether or not defect content is displayed
$ git log -1 b4f07df --oneline --notes
b4f07df35 Prepare re-signing pgm's ueberjar to avoid SecurityException
Notes:
    test note1

Notes (alsoCherrypick):
    570bba5

Notes (defect):
    Bug:24435

小结

  1. 添加 git notes 默认归类到 refs/notes/commits,可随 git log 一并展示;
  2. 如果使用 git log --oneline,则显示对应的 git notes 需要带 --notes 标记;
  3. git log 显示自定义类型的 notes,有两种方式:
    1. git log 后加 --notes=<categoryName>
    2. 修改 git 配置项:git config notes.displayRef 'refs/notes/<catName>'git config notes.displayRef 'refs/notes/*'
      拓展

签出分支时,联想到 git 笔记引用与其他远程跟踪分支引用的相似性,可以在本地直接签出 refs/notes 分支:

bash 复制代码
$ git checkout -b myNotes notes/alsoCherryPick
Switched to a new branch 'myNotes'
$ ls
b4f07df357fccdff891df2a4fa5c5bd9e83b4a4a
$ cat b4f07df357fccdff891df2a4fa5c5bd9e83b4a4a
570bba5

可见,将 notes 引用作远程跟踪分支时,该分支下的文件,其文件名为指定类别的 notes 所指向的目标 commit 的哈希值,文件内容为 git 笔记内容。

值得一提的是,经实测,签出某个 notes 引用后,对应的分支并不会自动更新该引用下的文件列表(当有多个同一类别的 note 时,该目录就有相同数量的文件),只能删除分支后重新签出。

相关推荐
晨犀1 小时前
超详细Git基本命令使用(二)
大数据·git·elasticsearch
欣慰的三叶草(● ̄(エ) ̄●)1 小时前
Tower for Mac Git客户端管理软件
git·macos·svn·git客户端·tower
程序者王大川1 小时前
【MySQL】索引优化:怎么通过IN查询2000个参数?
数据库·学习·mysql
Cosmos复调2 小时前
黑马JavaWeb开发笔记07——Ajax、Axios请求、前后端分离开发介绍、Yapi详细配置步骤
java·前端·笔记·vscode·ajax·yapi·软件工程
wuziNO_12 小时前
C++ 基础学习
c++·学习·算法
犬余2 小时前
Kafka入门:从零开始了解分布式流处理平台
笔记·分布式·学习·kafka
增删改查农民工2 小时前
Datawhale AI夏令营第五期学习!
人工智能·学习
mit6.8242 小时前
[Linux#47][网络] 网络协议 | TCP/IP模型 | 以太网通信
linux·运维·网络·笔记·网络协议
萍宝贝2 小时前
13.JS学习篇-ES6 React 项目模板
前端·javascript·学习·react.js·es6
speop2 小时前
【笔记】数据结构——8月27日
数据结构·笔记·算法