B.4 Git 版本控制

MacOS 上用 Homebrew 安装 git-delta

brew install git-delta

只考虑 Ubuntu 18.04 环境下的三剑客 Git & Github & Gitlab

summary(git2r::repository())
## Local:    devel /home/runner/work/masr/masr
## Remote:   devel @ origin (https://github.com/XiangyunHuang/masr)
## Head:     [ce51067] 2021-05-11: 注释掉 NLP
## 
## Branches:         1
## Tags:             0
## Commits:          5
## Contributors:     2
## Stashes:          0
## Ignored files:   11
## Untracked files: 74
## Unstaged files:   0
## Staged files:     0
## 
## Latest commits:
## [ce51067] 2021-05-11: 注释掉 NLP
## [a3423ce] 2021-05-10: 感觉是缓存出了问题了
## [7b486dc] 2021-05-10: 注释掉 Python 和 R 环境互调环境变量绘图的示例
## [8cde3fe] 2021-05-10: 移除 posterior 和 cowplot
## [8a93f72] 2021-05-10: 注释掉从 sklearn 导入 iris 数据

仓库 masr 哪些人给我点赞加星了

library(gh)
my_repos <- gh("GET /repos/:owner/:repo/stargazers", owner = "xiangyunhuang", repo = "masr", page = 1)
vapply(my_repos, "[[", "", "login")
 [1] "dddd1007"        "boltomli"        "JackieMium"      "AXGL"            "fyemath"        
 [6] "rogerclarkgc"    "swsoyee"         "joegaotao"       "YTLogos"         "Accelerator086" 
[11] "yimingfish"      "gaospecial"      "shenxiangzhuang" "shuaiwang88"     "LusiXie"        
[16] "llxlr"           "TingjieGuo"      "oiatz"           "XiaogangHe"      "xwydq"          
[21] "guohongwang1"    "yinandong"       "algony-tony"     "XiangyunHuang"   "perlatex"       
[26] "talegari"        "hao-shefer"      "zhouyisu"        "tsitong"         "liuyadong" 
Git 代码版本管理

图 B.6: Git 代码版本管理

Jeroen Ooms 开发的 gert 包实现在 R 环境中操作 Git,我们可以从幻灯片 — Gert: A minimal git client for R 学习重点内容。

library(gert)
Linking to libgit2 v1.0.0, ssh support: YES, https support: YES
Default user: Xiangyun Huang <xiangyunfaith@outlook.com>
library(magrittr)
git_log(max = 10) %>% 
  subset(grepl("Yihui Xie", x = author), select = c("author", "message"))

提供了 git_rm()git_status()git_add()git_commit() 等函数,其中包含 git_reset() 高级的 Git 操作。此外, 还有 git_branch_*() 系列分支操作函数

B.4.1 安装配置

Ubuntu 16.04.5 默认安装的 Git 版本是 2.7.4,下面安装最新版本Git和配置自己的GitHub账户

  1. 根据官网安装指导 https://git-scm.com/download/linux,在 Ubuntu 14.04.5 和 Ubuntu 16.04.5 安装最新版 GIT

    sudo add-apt-repository -y ppa:git-core/ppa
    sudo apt update && sudo apt install git
  2. 配置账户

    git config --global user.name "你的名字"
    git config --global user.email "你的邮件地址"
    touch .git-credentials
    # 记住密码
    echo "https://username:password@github.com" >> .git-credentials
    git config --global credential.helper store

以 Fedora 为例 安装 tig,首先安装必要的依赖,然后从官网下载源码,编译安装,之后切到任意本地 Git 仓库下,输入 tig 就可以看到如图 B.7 所示的样子了

sudo yum install readline-devel ncurses-devel asciidoc docbook-utils xmlto

tig 主要用于查看 git 提交的历史日志

Git 日志查看器

图 B.7: Git 日志查看器

B.4.2 追踪文件

git add .

提交新文件(new)和被修改(modified)文件,不包括被删除(deleted)文件

git add -u

提交被修改(modified)和被删除(deleted)文件,不包括新文件(new),git add --update的缩写

git add -A

提交所有变化,git add --all 的缩写

git init
git remote add origin https://github.com/XiangyunHuang/masr.git
git add -A
git commit -m "添加提交说明"
git push -u origin master

往远程的空的 Github 仓库添加本地文件

B.4.3 合并上流

git clone --depth=5 https://github.com/XiangyunHuang/cosx.org.git
git submodule update --init --recursive

查看远程分支

cd cosx.org
git remote -v
origin  https://github.com/XiangyunHuang/cosx.org.git (fetch)
origin  https://github.com/XiangyunHuang/cosx.org.git (push)
# 添加上流分支
git remote add upstream https://github.com/cosname/cosx.org.git
# 查看远程分支
git remote -v
origin  https://github.com/XiangyunHuang/cosx.org.git (fetch)
origin  https://github.com/XiangyunHuang/cosx.org.git (push)
upstream        https://github.com/cosname/cosx.org.git (fetch)
upstream        https://github.com/cosname/cosx.org.git (push)
# 获取上流 commit 并且合并到我的 master 分支
git fetch upstream
git merge upstream/master master
git push origin master

B.4.4 大文件支持

sudo apt install git-lfs
git lfs install
git lfs track "*.psd"
git add .gitattributes
git commit -m "track *.psd files using Git LFS"
git push origin master

这玩意迟早需要你购买存储空间,慎用

B.4.5 新建分支

git checkout -b stan     # 新建 stan 分支
git branch -v            # 查看本地分支 stan 前有个星号标记
git pull --rebase git@github.com:XiangyunHuang/cosx.org.git master
# 同步到远程分支 stan
git push --set-upstream origin stan
git push origin master:stan

git add .
git commit -m "balabala"
git push --set-upstream origin stan

本地新建仓库推送至远程分支

git remote add origin https://github.com/XiangyunHuang/notesdown.git
git add .
git commit -m "init cos-art"
# 此时远程仓库 notesdown 还没有 cos-art 分支
git push origin master:cos-art

位于 Github Git Community Book 中译本

B.4.6 创建 Github Pages 站点

基于 GitHub Pages 创建站点用于存放图片和数据

  1. 在Github上创建一个空的仓库,命名为 uploads,没有 readme.md 和 LICENSE
  2. 在本地创建目录 uploads
  3. 切换到 uploads 目录下
git init 
git checkout -b gh-pages
git remote add origin https://github.com/XiangyunHuang/uploads.git

添加图片或者数据,并且 git add 和 commit 后

git push --set-upstream origin gh-pages

这样仓库 uploads 只包含 gh-pages 分支,数据地址即为以日期为分割线

https://xiangyunhuang.github.io/uploads/data/eqList2018_05_18.xls

B.4.7 博客主题

初始化博客网站

git subtree add --squash --prefix=themes/hugo-lithium \
  git@github.com:yihui/hugo-lithium.git master

在 Github 创建新的空仓库,本地创建空的目录 xiangyun

cd xiangyun
git init
git remote add origin https://github.com/XiangyunHuang/xiangyun.git

git add .gitignore
git commit -m 'upload' 
git push --set-upstream origin master

git subtree 将另外一个仓库收缩为当前仓库的一个目录,且只产生一条提交记录

# 子库分支
git subtree add --squash --prefix=themes/hugo-xmag \
  -m "add hugo-xmag" git@github.com:yihui/hugo-xmag.git master 
# 或者子库分支
git subtree add --squash --prefix=themes/hugo-xmag \
  -m "add hugo-xmag" https://github.com/yihui/hugo-xmag.git master 

# 移除 git subtree 添加的 hugo 主题
git filter-branch --index-filter 'git rm --cached --ignore-unmatch -rf themes/hugo-xmag' --prune-empty -f HEAD

B.4.8 修改远程仓库的位置

有时候我们将自己的仓库转移给别人/组织,或者我们将远程仓库的名字改变了,这时候需要修改远程仓库的位置。比如最近我将博客仓库从 https://github.com/XiangyunHuang/xiangyun 转移到 https://github.com/rbind/xiangyun

转移前

git remote -v
origin  https://github.com/XiangyunHuang/xiangyun.git (fetch)
origin  https://github.com/XiangyunHuang/xiangyun.git (push)

转移命令

git remote set-url origin https://github.com/rbind/xiangyun.git

转移后

git remote -v
origin  https://github.com/rbind/xiangyun.git (fetch)
origin  https://github.com/rbind/xiangyun.git (push)

B.4.9 统计代码仓库的提交量

比如统计之都的主站仓库,提交量最大的20个人

git shortlog -sn | head -n 20
  153   Dawei Lang
  106   Yihui Xie
  89    Beilei Bian
  46    王佳
  42    雷博文
  39    Ryan Feng Lin
  35    Xiangyun Huang
  32    fanchao
  32    闫晗
  30    Lin Feng
  28    Jiaao Yu
  25    fyears
  24    Yixuan Qiu
  24    Miao YU
  22    Yuxuan Li
  22    qinwf
  20    Alice敏
  19    yanshi
  18    Shuyi.Yang
  13    黄湘云

B.4.10 账户共存

本节介绍如何使 Gitlab/Github 账户共存在一台机器上

如何生成 SSH 密钥见 Github 文档 — 使用 SSH 连接到 GitHub。有了密钥之后只需在目录 ~/.ssh 下创建一个配置文件 config

生成 SSH Key

ssh-keygen -t rsa -f ~/.ssh/id_rsa_github -C "name1@xxx1.com"
ssh-keygen -t rsa -f ~/.ssh/id_rsa_gitlab -C "name2@xxx2.com"

将 GitHub/GitLab 公钥分别上传至服务器,然后创建配置文件

touch ~/.ssh/config

配置文件内容如下

#
# Github
#
Host github.com // 个人的代码仓库服务器地址
HostName github.com
User XiangyunHuang
IdentityFile ~/.ssh/id_rsa_github

#
# company
#
Host xx.xx.xx.xx //
IdentityFile ~/.ssh/id_rsa_gitlab

配置成功,你会看到

ssh -T git@xx.xx.xx.xx
Welcome to GitLab, xiangyunhuang!

ssh -T git@github.com
Hi XiangyunHuang! You've successfully authenticated, but GitHub does not provide shell access.

B.4.11 回车换行

CR (Carriage Return) 表示回车,LF (Line Feed) 表示换行,Windows 下用回车加换行表示下一行,UNIX/Linux 采用换行符 (LF) 表示下一行,MAC OS 则采用回车符 (CR) 表示下一行

git config --global core.autocrlf false

B.4.12 子模块

  • 添加子模块到目录 templates/
git submodule add git://github.com/jgm/pandoc-templates.git templates
  • 移除子模块

https://stackoverflow.com/questions/1260748/how-do-i-remove-a-submodule/

B.4.13 克隆项目

git clone --depth=10 --branch=master --recursive \
    git@github.com:XiangyunHuang/pandoc4everything.git

B.4.14 创建 PR

git pull --rebase git@github.com:yihui/xaringan.git master
# then force push to your master branch

参考 https://github.com/yihui/xaringan/pull/107

I don’t recommend you to use your master branch for pull requests, because all commits will be squashed before merging, e.g. c2c2055 Then you will have some trouble with syncing your master branch with the master branch here (your choices are (1) delete your repo and fork again; or (2) force push; either option is not good). For pull requests, I recommend that you always use different branches for different pull requests.

B.4.15 修改 PR

之前一直有一个思想在阻止自己,就是别人的 repo 我是不能修改的,但是在这里,我拥有修改原始仓的权限,那么别人的复制品衍生的分支,我也有修改权限

git fetch origin refs/pull/771/head:patch-2
# 771 是 PR 对应的编号
git checkout patch-2

# 你的修改

git add -u
git commit -m "描述你的修改"

git remote add LalZzy https://github.com/LalZzy/cosx.org.git

git push --set-upstream LalZzy patch-2

整理自统计之都论坛的讨论 https://d.cosx.org/d/420363

  1. GitHub/Git 小抄英文版 https://www.runoob.com/manual/github-git-cheat-sheet.pdf
  2. GitHub/Git 小抄中文版 https://github.github.com/training-kit/downloads/zh_CN/github-git-cheat-sheet/
  3. Github 秘籍 https://github.com/tiimgreen/github-cheat-sheet/blob/master/README.zh-cn.md
  4. Git 简明指南 https://rogerdudler.github.io/git-guide/index.zh.html
  5. Git 奇技淫巧 https://github.com/521xueweihan/git-tips
  6. Git 官方书籍 https://git-scm.com/book/zh/v2
  7. Git 时代的 VIM 不完全使用教程 http://beiyuu.com/git-vim-tutorial
  8. 最佳搭档:利用 SSH 及其配置文件节省你的生命 https://liam.page/2017/09/12/rescue-your-life-with-SSH-config-file/