git 学习笔记 之 服务器上的 Git

原书中文版网址: here

为什么需要远程 git repo? 共享, 合作, 集成, 备份?
本地 repo <- pull, push -> 远程 repo
远程 repo 没有人在开发 -> no work directory -> so bare repository -> just need files in .git folder
git repo 所管理的所有东西, 都是 .git 目录下的文件 -> 它根据 git 自己定义的组织结构存在

架设 "git server" -> 通信 -> 选择协议 (file, ssh, http/https, git).

file 本地共享, 方便, 不安全, 灾难备份, 有时候许挂载;
ssh 同时支持 读, 写的网络协议, ssh 最常见, 安全, 基于用户名密码访问, 不利于共享, 和匿名访问;
git 自带的守护线程(9418), 需要 git-daemon-export-ok 文件, 没有加密&授权机制, 要么全部允许推送, 要么全部不允许;
http/https 简便, 便于分享, 需要 post-update hook, 如果需要推送 -> WebDAV, 端口常见, 效率低

"git server" 的关键点在于管理用户权限, ssh for each user? or shared account? or LDAP integratoin?

gitosis 可以帮我们管理 authorized_keys 中所有的 public key;
貌似Gitolite 更强大, 管理的细节竟然到了某 branch, refs 了.

服务器上的 git, 而不是 git server

上周看到 ddwrt 的 repo 中有 git, 就突发奇想, 是不是可以在路由器上搭一个 git server.
后来发现, 其实并没有 git server, 只有 server 上的 git.

首先, git 维护的是 .git 目录下面的所有文件和文件夹, repo 之间 push/pull 的效果是: .git 目录下面文件的相互 copy.
服务器上的 git 默认是没有监听线程的, 所以如果你 push, 其实是把文件 copy 到 server 上的某个 .git 文件夹下面. 一般我们用的还是 ssh 协议, 其实类是你 ssh 登录到 server, 然后用 vi 写 .git 文件夹下的文件.

所以最简单的 "git server" 是你在一个大家都可以访问的 server 初始化一个存放 .git 文件夹下所有文件的目录. 然后开放 ssh 协议, 凡是能够 ssh 登上这台 server 的人, 可以可以 push. pull 就是完全 copy 下来.

之所以有 git server 的惯性思维, 是因为我们经常用 github, gitlab 这样的 git web 管理 server, 是这些 web server 给了我们一个浏览我们 git 保存的历史版本的工具.

除了 github, gitlab (免费)之外, 还有一些比较方便的共享 repo 的方法 8 ways to share your git repository

另外: 服务器上的 Git - 协议

git 学习笔记<Version Control With Git>

好记性不如烂笔头, 今天理解并记住, 并不保证下次想用的时候还能理解

  1. git object store 存储4类: blob, tree, commit, tag;
  2. blob 存储的是文件的内容, 并被压缩, 算出 hash 为160bit, 40位16进制数字, 前2位作为文件夹名, 后面做文件名;
  3. git 是以内容寻址的, 只要内容一样, 生成的 blob 对象是一个;
  4. tree 相当于 linux 文件系统的 node, 存储系统某个文件夹结构. 它指向该文件夹下面的 blob 文件和 文件夹 tree;
  5. git cat-file -p [commit id | hash value] 可以看commit, tree, blob 的内容;
  6. 当某文件改变之后, 如果 commit, 那么该文件将会出现一个新的 blob 对象, 那么它上面文件夹对应的 tree 也会为了反映新的变化, 而出现一个新的 tree, 对应的, 递归向上, 直到 git 管理的顶层文件夹, 对应的 tree 都会出现新的一份. 没有改变的文件/文件夹的 hash 值没变, 那么他们对应的 blob 和 tree 都没有变, 新的 tree 还是指向它文件夹下的这些原有而没变的blob, tree 对象.
  7. 每个 commit 仅仅指向最顶层的 tree 对象, 每次有新的 commit, 最顶层的 tree 都会有新的一份. 并且每个 commit 都会指向它之前的 commit, 称之为 parent commit;
  8. 因为每个 commit 都指向最顶层的 tree, 那么顺藤摸瓜, 每个 commit 都能顺着顶层的 tree 找到当时的所有文件/文件夹的 snapshot;
  9. index/stage/cached 要么指向 HEAD 指向的 blob/tree, 要么指向 add 的 blob/tree;

goagent 代理访问 https 网站 出现的问题

遇到2种问题

  1. 证书不正确的问题

如下图, 报告证书不正确, 这种直接 继续 就好了

请输入图片描述

虽然能继续, 可是还有可能出现页面全乱掉的问题, 如下图. 原因是 CSS/JS 文件在 CDN 或者其它域名上, 所以找到 "其它" 域名, 在另外的窗口打开, 同上, 也点击 继续, 再回到原来页面刷新, 页面就恢复了.

请输入图片描述

  1. 证书不信任的问题 Error Type: HSTS failure

如下图, 浏览器认为不是真正的网站, 直接Block 了. 

请输入图片描述

点击详情, 如下图. 竟然说 facebook 要 chrome block 的, 那么也可以认为这是 chrome 对某些网站做的优化.(可是 chrome 并没有 block google 的 https 网站). 

请输入图片描述

**如何化解?**

添加 goagent 的 CA 到系统信任的 CA 列表. 下图是我的 chrome 在 MAC 上面的操作. (chrome 是使用的系统根证书列表)
找到 chrome 设置, 然后是 https/SSL 管理证书
请输入图片描述
MAC 下自动打开 keychain, 导入证书到 system, 我这个截图有点问题, 实际是导入的 system 下面
请输入图片描述
导入的时候, 选择 always trust
请输入图片描述
导入之后, 重新打开这个证书, 点 Trust 下三角, 然后再次确认 always trust. 就可以了
请输入图片描述