Git笔记
本文记录一些常用的git操作和设置技巧。
信任自签名证书
Windows上的git比泛unix系统下要难处理一些,问题包括
- 不使用系统的HTTP代理,
git clone速度可能会慢甚至失败 - 不使用系统的证书存储
在windows terminal里打印git的配置变量
1 | PS C:\Users\martin> git config --list --show-scope |
第8行http.sslcainfo是git信任的证书,第16行设置git使用代理端口。
我司有一个私有Gitlab实例作代码版本管理,gitlab通过nginx反向代理提供服务。因为只在内网里开发,所以无法获得公共签发的TLS证书。
其实我讨了一个巧把Gitlab配置在域名
gitlab.xuanlingasset.com,而我司其实注册了xuanlingasset.com根域名,所以原则上其实Gitlab是可以假设在公网上的。但一方面是为了安全,另一方面公网访问的需求不大,我司用蒲公英的内网穿透实现远程开发的需求。我司在这个域名上只有一个邮件服务,购置云服务器也不是用来做web服务而是做交易的。
无奈只能自签发一张证书,配置nginx上代理的所有web服务都用这种自签名证书,然后配置公司内的机器信任。
这里有个容易踩坑的地方,如果
1 | git config --global http.sslcainfo /path/to/cert |
把http.sslcainfo指向自签名证书,这时global层和system层都存在这个变量,你可能会遇到一个问题:克隆自己的服务器上的仓库没问题,但是克隆Github上的仓库会报类似“无法找到ssl证书”的错误。
最好的解决方案是,打开git默认的系统证书bundle(C:/Program Files/Git/mingw64/ssl/certs/ca-bundle.crt),其实里面就是一串证书写在一个文件里
1 | -----BEGIN CERTIFICATE----- |
把自签名证书(.crt)文件用任意文本编辑器打开,把证书内容复制然后粘贴在ca-bundle.crt,移除刚添加的global变量
1 | git config --global --unset http.sslcainfo |
可以正常克隆公共和私有仓库了。
处理异常”warning: redirecting to “
出现这个错误,是因为配置Remote的时候,忘记在网址的最后加上”.git”了,比如https://git.example.com/abc/xyz而不是https://git.example.com/abc/xyz.git。那么解决也很简单
1 | git remote set-url origin https://git.example.com/abc/xyz.git |
Fork Repository的维护流程
当你在Github上发现了感兴趣的项目,可以fork下来到自己的仓库
1 | git remote add fork <your repo url> |
然后在本地做出了一些代码修改,commit之后
1 | git push fork main |
在Github上打开fork仓库,在顶部会自动出现一个contribute按钮,点击就会自动创建一个PR给原项目。
另一种情形是,假设你花了一阵子在自己的fork上实现了新feature,这时候距离你的fork已经过去了一段时间,原项目增加了一些 commits,这些commits不在你的fork上存在,你要把原项目的新的commits同步到自己的fork上面,以便你创建PR的时候没有冲突。
1 | # assume your work is on branch private |
Advance search in git history
- Search for commits that changed a line, by matching line pattern
1
git log -S"<pattern>" -- <path>
- Search for commits that changed some lines, by specifing the region of lines
1
git log -L start_line,end_line:<file_path>
- Search for commits that add or remove a file
1
git log --diff-filter=D -- <directory-path>
Peeking the Git Data Model
Unexpectedly, how git data model to represent history is trivial, just object and reference:
- Objects store files and directory structure of a repository;
- References keep track of branches, tags and remotes.
You can peek at the information in an object or reference using git cat-file:
git cat-file -p <commit/ref>
The -p flag is to make git output in human friendly format.