1 - Git 实用技巧:如何将某个 Commit 导出为 Patch 补丁

在日常团队协作或跨仓库代码同步时,我们经常需要将某个特定的代码提交(Commit)提取出来,分享给他人或应用到另一个项目中。Git 提供了强大的 format-patch 工具,可以完美保留原提交的作者、时间、提交说明等元数据。 本文将为您介绍几种最常用的 Git 导出及应用 Patch 的场景。

1. 核心命令:导出单个特定 Commit

如果您知道某个 Commit 的哈希值(Commit ID),可以使用以下命令将其单独导出为一个 .patch 文件:

git format-patch -1 <commit-id>

参数说明:

  • :替换为您实际的提交哈希值(例如 abcd123)。
  • -1:表示仅导出当前这一次提交。如果不加 -1,Git 会默认导出该 Commit 之后的所有提交。

2. 常见使用场景扩展## 导出最近一次提交 (HEAD)

如果您刚完成一次提交,想立刻将其转为补丁:

git format-patch -1 HEAD

批量导出区间内的多个提交

如果您想将 commit-A 到 commit-B 之间的所有修改打包(包含 B,不包含 A):

git format-patch <commit-A>..<commit-B>

规范输出:导出到指定文件夹

默认情况下,补丁文件会生成在当前目录下。如果提交较多,建议规范输出到特定目录:

git format-patch -1 <commit-id> -o /path/to/directory

3. 接收方如何应用 Patch?

拿到 .patch 文件后,接收方有两个命令可以选择,具体取决于是否需要保留提交历史记录:

方案 A:保留完整历史(推荐)

如果您希望在新的仓库里完美复现这个 Commit(包括原作者、提交时间和提交信息):

git am < 0001-xxx.patch

方案 B:仅应用代码修改(不留历史)

如果您只想把代码改动应用到当前工作区,后续自己重新填写 Commit 信息:

git apply < 0001-xxx.patch

总结

  • 使用 git format-patch -1 快速提取单个补丁。
  • 使用 git am 恢复补丁并完美保留提交日志。

2 - Gitignore 规则总结

官方文档:https://git-scm.com/docs/gitignore

Gitignore 文件用于指定 Git 应该忽略哪些文件和目录,不将它们纳入版本控制。

放置位置

  • 项目根目录: 规则适用于整个仓库。
  • 子目录: 规则适用于该子目录及其所有子目录。

规则语法

  1. 空行或以 # 开头的行:被视为注释,会被忽略。
    # 这是一个注释
    
  2. 标准 glob 模式匹配
    • *:匹配零个或多个字符。
    • ?:匹配一个任意字符。
    • []:匹配括号中任意一个字符。
  3. 匹配目录:在模式末尾添加斜杠 / 来指定只匹配目录。
    temp/      # 忽略名为 temp 的目录及其所有内容
    
  4. 排除模式(否定):在模式前加 ! 来取消忽略。如果一个文件被前面的规则忽略了,但又被排除模式匹配,它将不被忽略。
    *.log       # 忽略所有 .log 文件
    !important.log # 但不忽略 important.log
    
  5. 开头斜杠 /:将模式锚定到 .gitignore 文件所在的目录。如果 .gitignore 在项目根目录,则锚定到项目根目录。
    /build      # 只忽略项目根目录下的 build 目录,不忽略 src/build
    
  6. 双星号 **
    • **/:匹配任意深度的文件或目录。**/logs 忽略任意目录下的 logs 目录。
    • pattern/**:匹配指定目录下的所有文件和子目录。docs/** 忽略 docs 目录下的所有文件和子目录。
    • a/**/b:匹配 a 目录下的任意深度的 b 文件或目录。例如,a/b, a/x/b, a/x/y/b

匹配顺序与优先级

  • 后来居上: .gitignore 文件中后出现的规则会覆盖先出现的规则。
  • 层级优先: 子目录中的 .gitignore 文件中的规则会覆盖父目录中的 .gitignore 文件中的规则。
  • 否定规则: 否定模式 (!) 重新包含先前被忽略的文件。被 ! 规则重新包含的文件不会再被同一个 .gitignore 文件中后续的规则排除。

注意事项

  • 已跟踪文件: 一旦文件已经被 Git 跟踪(即已经提交过),.gitignore 规则将不再对其生效。你需要使用 git rm --cached <file> 命令从 Git 索引中移除该文件,然后 Git 才会开始忽略它。

示例

# 忽略所有 .log 文件
*.log

# 忽略根目录下的 build 目录
/build

# 忽略 node_modules 目录及其内容
node_modules/

# 忽略所有 temp 目录,无论深浅
**/temp/

# 忽略所有 .txt 文件,但保留 important.txt
*.txt
!important.txt

3 - Git

  1. 𝗴𝗶𝘁 𝗱𝗶𝗳𝗳 : Show file differences not yet staged.
  2. 𝗴𝗶𝘁 𝗰𝗼𝗺𝗺𝗶𝘁 -𝗮 -𝗺 "𝗰𝗼𝗺𝗺𝗶𝘁 𝗺𝗲𝘀𝘀𝗮𝗴𝗲": Commit all tracked changes with a message.
  3. 𝗴𝗶𝘁 𝘀𝘁𝗮𝘁𝘂𝘀 : Show the state of your working directory.
  4. 𝗴𝗶𝘁 𝗮𝗱𝗱 𝗳𝗶𝗹𝗲_𝗽𝗮𝘁𝗵:Add file(s) to the staging area.
  5. 𝗴𝗶𝘁 𝗰𝗵𝗲𝗰𝗸𝗼𝘂𝘁 -𝗯 𝗯𝗿𝗮𝗻𝗰𝗵_𝗻𝗮𝗺𝗲: Create and switch to a new branch.
  6. 𝗴𝗶𝘁 𝗰𝗵𝗲𝗰𝗸𝗼𝘂𝘁 𝗯𝗿𝗮𝗻𝗰𝗵_𝗻𝗮𝗺𝗲: Switch to an existing branch.
  7. 𝗴𝗶𝘁 𝗰𝗼𝗺𝗺𝗶𝘁 –𝗮𝗺𝗲𝗻𝗱:Modify the last commit.
  8. 𝗴𝗶𝘁 𝗽𝘂𝘀𝗵 𝗼𝗿𝗶𝗴𝗶𝗻 𝗯𝗿𝗮𝗻𝗰𝗵_𝗻𝗮𝗺𝗲: Push a branch to a remote.
  9. 𝗴𝗶𝘁 𝗽𝘂𝗹𝗹 : Fetch and merge remote changes.
  10. 𝗴𝗶𝘁 𝗿𝗲𝗯𝗮𝘀𝗲 -𝗶: Rebase interactively, rewrite commit history.
  11. 𝗴𝗶𝘁 𝗰𝗹𝗼𝗻𝗲 : Create a local copy of a remote repo.
  12. 𝗴𝗶𝘁 𝗺𝗲𝗿𝗴𝗲 : Merge branches together.
  13. 𝗴𝗶𝘁 𝗹𝗼𝗴 –𝘀𝘁𝗮𝘁: Show commit logs with stats.
  14. 𝗴𝗶𝘁 𝘀𝘁𝗮𝘀𝗵 : Stash changes for later.
  15. 𝗴𝗶𝘁 𝘀𝘁𝗮𝘀𝗵 𝗽𝗼𝗽: Apply and remove stashed changes.
  16. 𝗴𝗶𝘁 𝘀𝗵𝗼𝘄 𝗰𝗼𝗺𝗺𝗶𝘁_𝗶𝗱: Show details about a commit.
  17. 𝗴𝗶𝘁 𝗿𝗲𝘀𝗲𝘁 𝗛𝗘𝗔𝗗~𝟭: Undo the last commit, preserving changes locally.
  18. 𝗴𝗶𝘁 𝗳𝗼𝗿𝗺𝗮𝘁 -𝗽𝗮𝘁𝗰𝗵 -𝟭 𝗰𝗼𝗺𝗺𝗶𝘁_𝗶𝗱: Create a patch file for a specific commit.
  19. 𝗴𝗶𝘁 𝗮𝗽𝗽𝗹𝘆 𝗽𝗮𝘁𝗰𝗵_𝗳𝗶𝗹𝗲_𝗻𝗮𝗺𝗲: Apply changes from a patch file.
  20. 𝗴𝗶𝘁 𝗯𝗿𝗮𝗻𝗰𝗵 -𝗗 𝗯𝗿𝗮𝗻𝗰𝗵_𝗻𝗮𝗺𝗲: Delete a branch forcefully.
  21. 𝗴𝗶𝘁 𝗿𝗲𝘀𝗲𝘁 : Undo commits by moving branch reference.
  22. 𝗴𝗶𝘁 𝗿𝗲𝘃𝗲𝗿𝘁 : Undo commits by creating a new commit.
  23. 𝗴𝗶𝘁 𝗰𝗵𝗲𝗿𝗿𝘆 -𝗽𝗶𝗰𝗸 𝗰𝗼𝗺𝗺𝗶𝘁_𝗶𝗱: Apply changes from a specific commit.
  24. 𝗴𝗶𝘁 𝗯𝗿𝗮𝗻𝗰𝗵 : Lists branches.
  25. 𝗴𝗶𝘁 𝗿𝗲𝘀𝗲𝘁 --𝗵𝗮𝗿𝗱: Resets everything to a previous commit, erasing all uncommitted changes

小技巧

在所有提交中查找某个关键字:

git grep "近亲" $(git rev-list --all .)

4 - Latency Numbers Every Programmer Should Know

在线预览地址:Latency Numbers Every Programmer Should Know

From Google SRE book

OperationTime in nsTime in ms (1ms = 1,000,000 ns)
L1 cache reference1
Branch misprediction3
L2 cache reference4
Mutex lock/unlock17
Main memory reference100
Compress 1 kB with Zippy2,0000.002
Read 1 MB sequentially from memory10,0000.010
Send 2 kB over 10 Gbps network1,6000.0016
SSD 4kB Random Read20,0000.020
Read 1 MB sequentially from SSD1,000,0001
Round trip within same datacenter500,0000.5
Read 1 MB sequentially from disk5,000,0005
Read 1 MB sequentially from 1Gbps network10,000,00010
Disk seek10,000,00010
TCP packet round trip between continents150,000,000150

Therefore, it is possible to read:

  • sequentially from HDD at a rate of ~200MB per second
  • sequentially from SSD at a rate of ~1 GB per second
  • sequentially from main memory at a rate of ~100GB per second (burst rate)
  • sequentially from 10Gbps Ethernet at a rate of ~1000MB per second

Back of the Envelope Calculations

Quick tips: Use numbers based on the decimal system to run numbers in your head. Sample calculation:

  • What is the overall latency of retrieving 30 256kB images from one server?

Naïve design: do all the work on one machine - dominated by disk seek time.

Reads required to generate page30 images / 2 disks per machine = 15
Time to read one image from HDD(256KB / 1MB) * 5 ms + 10 ms seek = 11.28 ms
Approximate time to generate results15 reads * 11.28 ms = 169.2 ms

One HDD-based server can generate 1000 ms / 169.2 ms ~= 5 result pages per second.

5 - Kafka

6 - Web authorization

7 - Memory allocation