# open github website and create your PAT
## copy the token
::create_github_token()
usethis
# set local git configuration
## select 2: Replace these credentials
::gitcreds_set()
gitcreds
# check that your PAT has been successfully stored
::gh_token_help() usethis
3 CI和git
导读:结合个人的常用git操作场景,梳理和总结了常用版本控制技巧,便于随时翻看和使用。
一些有用的自学材料:
Pro git book(Scott Chacon and Ben Straub)
3.1 git配置
配置默认文本编辑器(text editor)。windows党还是自觉使用Notepad吧,免费又熟悉
下载安装Notepad++(默认安装路径)
打开GitBash,并输入如下代码
$ git config --global core.editor "'C:/Program Files (x86)/Notepad++/notepad++.exe' -multiInst -notabbar -nosession -noPlugin"
配置合并检查工具(mergetool)。这个必须要图形化GUI的,p4merge就是一个不错的选择。
下载并安装p4merge。默认安装路径为
"C:Program Files\Perforce\p4merge.exe"
。打开GitBash,并输入如下代码:
$ git config --global diff.tool p4merge
$ git config --global difftool.p4merge.path 'C:\Program Files\Perforce\p4merge.exe'
$ git config --global merge.tool p4merge
$ git config --global mergetool.p4merge.path 'C:\Program Files\Perforce\p4merge.exe'
3.1.1 安装git bash
此步骤必须。
下载git bash到本地电脑
在本地电脑安装git bash——强烈建议默认安装路径。
3.1.2 申请github账号
- 进入github官网申请一个github账号。
建议使用高校邮箱如xxxx@nwsuaf.edu.cn,高校邮箱有福利(可以建立私有仓库啊,完成你的秘密项目)。
记得取一个简单好记的用户名;记得改一个有个性的头像。(后面协作开发项目的时候,可以更方便沟通和交流!)。
- 在Git Bash窗口,并输入如下代码(这是告诉git,我将以如下身份开始git之旅啦!):
$ git config --global user.name "John Doe"
$ git config --global user.email johndoe@example.com
3.1.3 安装文本编辑器Notepad++
此步骤非必须,根据个人爱好而定。
配置默认文本编辑器(text editor)。windows党还是自觉使用Notepad吧,免费又熟悉
下载并在本地电脑安装Notepad++——强烈建议默认安装路径
在Git Bash窗口,并输入如下代码(这是告诉git,我将使用如下的默认文本编辑器):
$ git config --global core.editor "'C:/Program Files (x86)/Notepad++/notepad++.exe' -multiInst -notabbar -nosession -noPlugin"
3.1.4 安装并配置合并检查工具——p4merge
此步骤非必须,看你是不是git重度用户。
配置合并检查工具(mergetool)。这个必须要图形化GUI的,p4merge就是一个不错的选择。
- 下载并在本地电脑安装p4merge。————强烈建议默认安装路径。
windowns系统下默认安装路径一般为
"C:Program Files\Perforce\p4merge.exe"
。
- 在Git Bash窗口,并输入如下代码(这是告诉git,我将使用如下的合并检查工具):
$ git config --global diff.tool p4merge
$ git config --global difftool.p4merge.path 'C:\Program Files\Perforce\p4merge.exe'
$ git config --global merge.tool p4merge
$ git config --global mergetool.p4merge.path 'C:\Program Files\Perforce\p4merge.exe'
3.1.5 检查git配置信息
如果上述步骤都做好了,你可以系统地检查一下是不是git配置都正确(如你所愿)啦!
- 在Git Bash窗口,并输入如下代码(这是告诉git,请列出我所有的git配置信息):
$ git config --list
经验法则:如果git操作中,出现了merge conflict,则需要用到
p4merge
进行冲突解决。
$ git mergetool
3.2 git常用命令
3.2.1 git界面命令
- 如何查看git工作目录?在Git Bash窗口,输入并运行如下代码:
pwd
如何退出当前列表?在Git Bash窗口,输入并运行代码
q
,可以直接退出当前的列表ls。如何退出Git Bash窗口?在Git Bash窗口,输入并运行代码
exit
,可以直接退出git Bash窗口
3.2.2 git查看提交历史
视图化查看提交历史、各个分支的指向以及项目的分支分叉情况:
$ git log --oneline --decorate --graph --all
或者简略查看历史提交记录:
git log --pretty=oneline
3.2.3 git文件及文件夹命令
cd
: change directory的简写,改变目录的意思,就是切换到哪个目录下, 如 cd e:切换 E 盘下面的fff 目录。cd ..
: 回退到上一个目录。我们在写js,引入文件时,.. 表示的就是上一个目录, 所以 cd .. 回退到上一个目录就很好理解了。注意,cd 和两个点点..之间有一个空格,pwd
: print working directory, 打印工作目录,它会显示我们当前所在的目录路径。ls
: list, 列出当前目录中的所有文件, 只不过ll(两个ll)列出的内容更为详细。touch
: 新建一个文件如 touch index.js就会在当前目录下新建一个index.js文件。rm
: remove,删除一个文件, rm index.js 就会把index.js文件删除.mkdir
: make directory 新建一个目录,就是新建一个文件夹. 如mkdir src 新建src 文件夹.rm -r
: 删除一个文件夹, r (recusive 是递归的意思), 删除用的就是递归,先删除文件夹里面的内容,再删除文件夹。 rm -r src 删除src目录。mv
移动文件, mv index.html src index.html 是我们要移动的文件, src 是目标文件夹,当然, 这样写,必须保证文件和目标文件夹在同一目录下.reset
清屏,把git bash命令窗口中的所有内容清空。exit
可以直接退出窗口。
3.3 git仓库管理
3.3.1 基于本地项目创建
- 准备本地电脑上的工作文件夹。例如,在
d
盘新建一个名为project
的文件夹,那么工作文件路径就是d:/project/
。
工作文件夹最好不要设在系统盘,如c盘。——系统重装可能就麻烦了!
文件夹命名不要出现中文。——编程世界中还是乖乖用英语吧!
- 在Git Bash窗口,并输入如下代码(这是告诉git,请进入工作文件夹吧):
git cd /d/project
3.3.2 基于Rstudio的本地项目创建
基本操作:
全新创建本地项目:Rstudio \(\Rightarrow\) File \(\Rightarrow\) New Project \(\Rightarrow\) New Directory
打开刚才创建的R project(
xxx.Rproj
),此时可以使用Rstudio自带的Terminal进行git指令操作。git初始化,完成第一次提交
# 初始化
$ git init -b main
# 添加变动
$ git add .
# 备注变动
$ git commit -m "First commit"
登陆你的github,并创建一个空的远程仓库repo(操作略,注意不要勾选添加任何文件,如gitignore类型或readme!)。并复制仓库地址(例如:
git@github.com:user/your-repo.git
)将本地项目添加并推送到刚才创建的远程github仓库:
# 添加到远程仓库
$ git remote add origin git@github.com:user/your-repo.git
# 当然也可以随时删除
$ git remote rm origin
# 检查并确认
$ git remote -v
# 推送到远程仓库
$git push --set-upstream origin main
3.3.3 克隆(clone)在线仓库
如果你想学习并改进一个已经github在线的公开项目,你可以把它克隆下来:
在github网站上找到自己喜欢的在线仓库,例如:https://github.com/huhuaping/team-students
在Git Bash窗口,并输入如下代码(这是告诉git,请拷贝这个在线仓库吧):
git clone https://github.com/huhuaping/team-students
- 上述操作会在当前工作目录下创建一个名为 “team-students” 的目录,并在这个目录下初始化一个 .git 文件夹。
3.3.4 派生(fork)仓库
如果你想对一个公开项目(例如,https://github.com/huhuaping/team-students )做出自己的贡献,你可以把它fork到你的github账户下。
进入github官方网站,用你的账号密码登陆进去。
在浏览器上新建标签页,找到你感兴趣的公开项目(例如,https://github.com/huhuaping/team-students )。
你也可以直接搜索你感兴趣的任意公开项目
对于这个你感兴趣的公开项目,点击网页上大大的Fork按钮。
这时,你可以在你自己账户下的仓库列表中,看到刚才Fork的你感兴趣的项目。
在Git Bash窗口,并输入如下代码(这是告诉git,请进入工作文件夹吧):
git clone https://github.com/your-account-name/team-students
注意:这里的
your-account-name
是你github账户的用户名——因为你把别人的公开项目(派生)Fork到自己的账户下啦!
- 进入工作文件夹。在Git Bash窗口,并输入如下代码(这是告诉git,请进入工作文件夹吧):
cd /d/projects/team-students
- 新建一个名为
git-intro
的分支(branch),并检出(checkout)到这个分支。——这一步的意义以后再说吧。在Git Bash窗口,并输入如下代码(这是告诉git,请进入工作文件夹吧):
git checkout -b git-intro
3.3.5 项目仓库版本控制
- 对项目代码进行修改和完善。例如,
打开R项目文件
team-students.Rproj
,运行Rstudio 修改其中Rmarkdown文件02-git-team-intro.Rmd
的内容,例如增加一行代码。 保存(save)好修改。
- 暂存(stage)修改。在Git Bash窗口,并输入如下代码(这是告诉git,把这个文件暂存stage起来吧):
git add 02-git-team-intro.Rmd
- 提交(commit)修改。在Git Bash窗口,并输入如下代码(这是告诉git,提交修改,并附注一条信息
add a new line
):
git commit -m 'add a new line'
- 推送(push)修改。在Git Bash窗口,并输入如下代码(这是告诉git,把我们的修改推送到github云端去吧):
git git push origin git-intro
3.4 git分支操作
3.4.1 推送本地新建分支
- 新建并检出到本地分支(local branch)
$ git checkout -b dev
Switched to a new branch 'dev'
- 查看远程分支(remotes)
$ git remote -v
- 设定上游分支(upstream),以后就可直接推送:语法为
git push -u <remote> <branch>
$ git push -u origin feat
$ git push
- 查看上游分支的引用关系
$ git branch -avv
3.4.2 合并分支branch
$ git checkout master
$ git merge hotfix
3.4.3 修改分支名称
缘起:历史上github默认的主分支为
master
,而目前则默认主分支为main
。
相关操作可参看
# 修改本地分支名称
$ git branch -m master main
# 修改远端分支
$ git push -u origin main
# 修改默认设置分支(此步骤也可登陆github账号进行设置)
$ git symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/main
# 删除旧的远端分支
$ git push origin --delete master
3.4.4 删除本地分支
$ git branch -d branch_name
$ git branch -D branch_name
3.4.5 删除远程分支
$ git push <remote_name> --delete <branch_name>
$ git push <remote_name> :<branch_name>
说明:
remote_name
一般为origin
。
3.4.6 无法把本地repo推送到远程repo
这种情形下,直接push会提示如下报错:
git error: failed to push some refs to 'https://github.com/
问题可能有多个:
- 没有进行远程设置。可以通过如下代码查看是否进行了远程设置。
# 正常情况下显示结果如下:
$git remote -v
myOrigin ssh://git@example.com:1234/myRepo.git (fetch)
myOrigin ssh://git@example.com:1234/myRepo.git (push)
# 否则就应该进行远程设置:
$git remote add origin ssh://git@example.com:1234/myRepo.git
- 然后再进行推送:
# origin是远端,master是本地分支
$git push origin master
- 可能还会报错,比如提示远端在本地前面。因此需要pull-merge-mergetool,来实现更新步骤。下面给出处理办法(参看Dealing with non-fast-forward errors):
# 报错信息
! [rejected] master -> master (non-fast-forward)
error: failed to push some refs to 'git@github.com:huhuaping/netlify.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
# 同步远端和本地
$ git pull origin master
# 如果显示冲突conflict,则利用合并工具处理
$ git mergetool
3.4.7 分支push找不到上游分支
如果是本地新建分支,则需要设定上游分支,否则push就会报错:
# 报错信息。
$ git push
fatal: The current branch dev has no upstream branch.
To push the current branch and set the remote as upstream, use
处理办法是:
$ git push --set-upstream origin dev
3.4.8 回到远端状态
回到远端状态(例如,本地已提交,但是push提示合并冲突时,想把本地pull为远端状态)。参看队长问答
git reset --hard origin/<your branch>
如果要撤回到到指定的过往提交(commit)点,则使用命名:
git reset --hard origin/<your branch> e75862c
3.4.9 放弃本地的修改(未提交)
参看队长问答.
#删除remove所有untracked files
git clean -df
#清除clear 所有untracked files
git checkout -- .
#保存痕迹
git stash save --keep-index --include-untracked
# 不保存痕迹
git stash save --keep-index
3.4.10 删除已提交记录中的文件并添加到ignore列表
Rstudio默认会添加一些排除文件给.gitignore(合理的),但是如果用户之前就已经在远端repo上提交过这些排除文件,那么就可能会出现一个烦人的情形:每次打开Rstudio,terminal下使用git status
检查就会提示.Rproj.user/shared/notebooks/paths
。
处理办法就是要彻底在远端先删除这些应该给排除的文件。这样以后才能彻底安心。具体可参看队长问答
First of all your files are already committed so you have to remove it from the repo:
# Once you add files to git, it will keep tracking them,
# so we have to delete them and commit your deletion
git rm -r --cached .Rproj.user/**
# Commit the deleted files
git commit -m "Removed files...."
# now add it to the `.gitignore` and the files will be ignored
echo '.Rproj.user/**' > .gitignore
注意:其中最后一步
echo
可以手动操作,避免错误删除之前正确设定的ignore清单列表!
3.5 git忽略文件
3.5.1 配置文件
工作思路是:
- 在工作目录下新建
.gitigore
文件
$ touch .gitignore
- git bash调用文本编辑工具(windows死粉的notepad++),编辑并设置.gitignore文件
# 配置notepad(64bit system -windows)
$ alias notepad="/c/Program\ Files\ \(x86\)/Notepad++/notepad++.exe"
# 打开编辑器,设置忽略规则
$ notepad .gitignore
- 忽略规则的一个样例
# ignore the whole file directory
data-raw/
# ignore Rproj user info file
.Rproj.user
3.5.2 忽略文件无效及处理办法
有时候.gitignore里虽然进行了修改设定,但并不会马上生效。
此时,问题可能就出在缓存上(cash)(参看My .gitignore file is ignored by git and it does not work,或者参看Gitignore is not Working)。
解决办法是清理缓存-提交:
$ git rm -r --cached .
$ git add .
$ git commit -m "Untracked files issue resolved to fix .gitignore"
场景实例:(两台设备上)git操作时反复出现.Rproj.user/shared/notebooks/paths
处理办法(参考):
# Once you add files to git, it will keep tracking them,
# so we have to delete them and commit your deletion
git rm -r --cached .Rproj.user/**
# Commit the deleted files
git commit -m "Removed files...."
# now add it to the `.gitignore` and the files will be ignored
echo '.Rproj.user/**' > .gitignore
要点:
**
表示文件夹。
3.6 github文件超越容量限制
3.6.1 LFS安装和设定
经验法则:如果项目库中存在大于50M以上单个文件需要上传到github,则应提前设定了LFS,然后再push,否则可能会出现LFS与git(多次提交)之间的冲突,而导致push失败。
挑战的问题:git bash 命令push时,如果单个文件大于50M以上,则会提示推送失败。
参考的解决办法包括:
实际的解决办法为:
- 下载安装git LFS软件
# git bash下确认是否成功安装
$ git lfs install
> Git LFS initialized.
- 配置LFS存储策略
# 追踪大容量文件所在的文件夹
$ git lfs track "data-process/"
- 提交并推送LFS
# 添加所有改动文件夹
$ git add .
# 提交并推送
$ git commit -m "add LFS directory data-process/"
$ git push origin master
- 查看所有设定的LFS文件列表
$ git lfs ls-files --all
3.6.2 LFS记录冲突报错的处理
经验法则:LFS指针回滚,与git commit的指针回滚,不是同一个概念。操作的时候要慎重决定LFS回滚数量n的确定。
如果出现了LFS记录冲突报错,具体原因一般是:git push之前忽视了大文档的存在,然后后面再进行LFS设定。这时,git 多次的commit提交,就会与LFS记录针头产生冲突(即便亡羊补牢后面进行了LFS设定)。此时,git push具体报错信息如下:
# 具体报错信息
remote: error: GH001: Large files detected.
remote: error: Trace: f22735321d76092fa67a1011835dfdcc
remote: error: See http://git.io/iEPt8g for more information.
remote: error: File mySDK.framework/mySDK is 185.09 MB; this exceeds GitHub's file size limit of 100.00 MB
To git@github.com:company/repo.git
! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to 'git@github.com:company/repo.git'
当然,我们也是有办法先将LFS记录文档从git 仓库中先移除(可参看Remove git-lfs from Repository)。具体步骤如下:
步骤1:移除LFS工具,git命令为
$ git lfs uninstall
。步骤2:把LFS记录从仓库中清除,git命令为
$ git filter-branch -f --index-filter 'git rm --cached --ignore-unmatch *.psd' HEAD~18..HEAD
步骤3:提交到远端。git命令为
$ git push
注意:
*.psd
为待移除的LFS文件,可以使用regex表达式;HEAD~18..HEAD
是从之前的n条commit记录中清除关于LFS的设定,在这里n=18,具体以个人的实际git commit情况而定。
3.7 github帐号添加SSH key
许多 Git 服务器都使用SSH公钥进行认证。为了向Git服务器提供SSH公钥,如果某系统用户尚未拥有密钥,必须事先为其生成一份。简单说,如果本地电脑采用SSH key来与服务器对话,就能省去繁复的账号密码输入过程。
3.7.1 确认是否本地存有密钥
首先,你需要确认自己是否已经拥有密钥。默认情况下,用户的SSH密钥存储在其~/.ssh目录下。进入该目录并列出其中内容,你便可以快速确认自己是否已拥有密钥:
$ cd ~/.ssh
$ ls
3.7.2 生成SSH key
打开gitbash,输入如下代码:
$ ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
用自己的github账号邮箱替换上面的邮箱
如果提示文件夹,默认即可,直接按Enter
如果提示密码,不设密码的话,也直接按Enter
确保已经运行密钥:
$ eval $(ssh-agent -s)
把密钥添加到本地代理:
$ ssh-add ~/.ssh/id_rsa
3.7.3 查看并拷贝密钥
默认生成路径下,可以输入如下代码查看密钥:
$ cat ~/.ssh/id_rsa.pub
拷贝到剪贴板:
$ clip < ~/.ssh/id_rsa.pub
# Copies the contents of the id_rsa.pub file to your clipboard
3.7.4 把密钥添加到github账号
账号登陆github
点击头像,下拉点击setting
点击SSH and GPG keys
点击New SSH key 或者 Add SSH key
粘贴密钥
title命名备注
点击 Add SSH key
3.8 Github一机多账号SSH配置
需求情形:一台电脑上,可能需要使用不同的github账号(fangning 以及kevin),分别开展仓库开发和维护工作。
解决办法如下:
(1)分别在本地电脑上给两个github账号配置SSH。具体步骤参看:(节@ref(github-sshkey): github帐号添加SSH key)。需要注意的是:
务必重命名两个私钥,避免覆盖。例如:
~/.ssh/fangning_id_rsa
和~/.ssh/kevin_id_rsa
私钥位置(Windows系统):
C:\Users\win-account\.ssh\
(2)全局配置两个账号的别名关系:
首先,在私钥文件夹下创建(若无)并编辑配置文件:
C:\Users\win-account\.ssh\config
。(先用txt创建,然后删除扩展.txt
)其次,根据上述私钥文件位置编辑配置要求,然后保存:
# Default github account: fangning
Host fangning
HostName github.com
IdentityFile ~/.ssh/fangning_id_rsa
IdentitiesOnly yes
# Other github account: kevin
Host kevin
HostName github.com
IdentityFile ~/.ssh/kevin_id_rsa
IdentitiesOnly yes
(3)打开gitbash
(默认路径下),确保私钥添加到系统代理中:
# 运行私钥代理
$ eval $(ssh-agent -s)
# 添加私钥1
$ ssh-add ~/.ssh/fangning_id_rsa
# 添加私钥2
$ ssh-add ~/.ssh/kevin_id_rsa
(4)测试私钥能与github服务器通讯:
$ ssh -T git@fangning
$ ssh -T git@kevin
如果通讯成功则可以看到:
Hi kevin! You've successfully authenticated, but GitHub does not provide shell access.
(5)设定仓库的git配置文件(注意文件路径:path-of-your-repo/.git/config
):
[remote "origin"]
url = git@fangning:huhuaping/wp-xian.git
fetch = +refs/heads/*:refs/remotes/origin/*
[user]
name = fangning@github.email
email = fangning' github email
此处的重点有三个:一是remote url的别名
git@fangning
,意味着git将会使用这一别名指定下的SSH私钥;二是github仓库地址huhuaping/wp-xian.git
,此处因为fangning是仓库的合作者collaborator,拥有完全权限;三是仓库git用户[user]
,这里设置为fangning,也即意味着其为当前git使用者身份。第三点我们也可以使用git config user.email "fangning@github.email"
,以及git config user.name "fangning' github name"
进行调整。
参考资源:
3.9 Github如何设置personal access token (PAT)
github
更新安全机制,提出了PAT访问方式,以下是基本设置过程:
使用
usethis
包打开一个Rstudio项目(已经git托管)
Github创建PAT token:先在Rstudio 项目 Console中运行
usethis::create_github_token()
,浏览器将会自动登陆你的github网站,并引导进入PAT token设置。PAT token申请:有效期可以自行设定,可以按年度来。设置好后,记得copy token码(后续将无法再看到它),下面将要用到。
本地PAT设置:在Rstudio 项目 Console中运行
gitcreds::gitcreds_set()
,将会引导设置,要求输入PAT token,粘贴之前复制好的token即可。选择”2: Replace these credentials”。完成本地设置。重启Rstudio 项目,检查是否设置成功。
参看资源:Managing Git(Hub) Credentials see
3.10 gitee与github联通
GitHub是全球最大的面向开源及私有软件项目的托管平台,里面不缺乏大神写的优秀的开源项目,可是GitHub有一个致命的弊端,就是国内访问速度太慢了。为了解决这个问题,一个优秀的国产代码托管平台Gitee(码云)应用而生。
下面将重点介绍如何实现一个项目仓库在gitee与github之间无缝联通和同步(相关过程可参看)。
3.10.1 gitee准备
注册gitee账号(操作略)
绑定邮箱
3.10.2 gitee添加SSH key
与前面github的添加过程(见节@ref(#github-sshkey))类似。也可以参看官方说明。
打开并运行
gitbash
查看确认本地密钥情况
# 进入个人user,列出密钥
$ cd ~/.ssh
$ ls
- 生成gitee密钥(按提示完成三次Enter回车)。
# 生成SSH Key,邮箱仅作为识别符
$ ssh-keygen -t ed25519 -C "your_email@example.com"
- 运行密钥并添加到本地:
# 确保已经运行密钥
eval $(ssh-agent -s)
# 把密钥添加到本地代理
$ ssh-add ~/.ssh/id_ed25519
- 查看密钥并拷贝密钥:
# 查看密钥
$ cat ~/.ssh/id_ed25519.pub
# 拷贝到剪贴板
$ clip < ~/.ssh/id_ed25519.pub
登陆gitee网站,在个人账号下添加上述复制的SSH key:安全设置 \(\Rightarrow\) SSH公钥
gitbash
添加主机到本机SSH可信列表
$ ssh -T git@gitee.com
3.10.3 将github仓库与gitee关联
考虑到主要使用github,gitee只是作为备用,因此下面介绍如何将github仓库关联到gitee。
主要步骤如下(相关过程可参看):
确保github和gitee的SSH key都正确配置(参看节@ref(#github-sshkey)和节@ref(#gitee-sshkey))
登陆gitee网站,通过引用github仓库进行gitee仓库创建:新建仓库 \(\Rightarrow\) 点击导入 \(\Rightarrow\) 导入GitHub仓库(需要github授权同意)\(\Rightarrow\) 选择目标仓库,点击
导入
。使用
gitbash
克隆github目标仓库到本地
$ cd your-dir-path/
$ git clone git@github.com:user/your-rep.git
- 修改目标仓库的git配置文件
.git/config
[remote "origin"]
# github 地址
url = git@github.com:user-github/your-repo.git
# gitee 地址
url = git@gitee.com:user-gitee/your-repo.git
fetch = +refs/heads/*:refs/remotes/origin/*
- 此时,已经完成了github与gitee的同步关联。对本地克隆仓库的相关git操作,都会实现二者的同步变动。
3.11 git多设备协同
3.11.1 明确自己git使用的安全环境
github有多重安全条件,用户可以自行决定自己的安全等级。需要注意的是,在多台工作设备下,git需要确认不同设备的使用权限。因此,明确自己的安全环境是多设备工作的第一步:
是否开启两步验证。若开启,在一些重要的安全操作下(登陆账户或删除仓库),就需要获得实时动态密码(token)。动态密码的管理工具包括authy等。
是否设定加密SSH。简单说,如果本地电脑采用SSH key来与服务器对话,就能省去繁复的账号密码输入过程。
3.11.2 多设备git工作的基本流程
条件准备。主力设备A;新设备B;需要异端工作的sharerepo。
主力设备A:对sharerepo已完成工作进行push,上传到云端。add-commit-push三部曲。
新设备B:创建文件夹,并clone云端的sharerepo。
# 明确存放在本地的文件路径
$ cd /j/github/
# clone远程sharerepo到本地文件路径下
$ git clone https://github.com/huhuaping/sharerepo.git
# 进入本地sharerepo
$ cd ./sharerepo
- 工作设备下:pull-edit-add-commit-push 四部曲。
3.11.3 两步验证下如何正确地clone远程repo
- 对于私有仓库,上述方法clone会提示错误。
Repository not found. fatal: repository not found
github托管下,两步验证法要求对新设备B设定私有进入授权码。github账号 ——>setting ——>Developer settings ——> personal access tokens ——> generate new token ——>勾选权限范围 ——> 复制授权码备用。
gitbash中输入如下代码colone私有仓库
# tokens 也就是上述复制备用的授权码。既不是github账户登录密码,也不是两步验证动态码!
$ git clone https://username:tokens@github.com/username/repo.git
3.11.4 最后的忠告
在任何终端设备上工作,最后都要记得对修改进行add-commit-push三部曲操作
云端永远保持最新状态!
3.12 git仓库协作
3.12.1 github的两种协作模式
(1)叉取和拉取模式(fork and pull model)
任何人都可以分叉现有的仓库,并将更改推送到他们的个人分支。您不需要对源仓库的权限来推送到用户拥有的分支。这个模式在开源项目中很受欢迎,因为它减少了新贡献者之间的摩擦,并允许人们在没有预先协调的情况下独立工作
(2)仓库共建共享模式(shared repository model)
协作者被授予对单个共享仓库的推送访问权限,并且在需要进行更改时创建主题分支。这种模式在小型团队和组织在私人项目上协作时更为普遍。
参看:GitHub for collaboration and best practices (page link)
3.12.2 github多人共创协作
(1)基本准备
仓库所有人A创建完成github仓库
协作伙伴B准备好自己的github账号(包括SSH设置)
(2)仓库所有者A邀请协作者B
A进入github 仓库,进入
setting
,点击collaborator
,添加协作者add collaborator
(输入github账号名或邮箱)B查阅自己的github注册邮箱,在收到的邀请信中点击同意接受邀请。
(3)协作者B在自己电脑端使用终端命令(gitbash
),拷贝A创建的源仓库。此时A和B同时具有对仓库的编辑和推送等操作权限。
(3)共创协作过程中,可能会出现“合并冲突”问题,这需要A和B共同商定处理和解决。推荐使用Rstudio
提供的相关冲突解决处理界面。
参考资源:
Chapter 47 Collaborating on RStudio with GitHub bookdown free online
3.12.3 git用户信息配置
(0)查看当前的配置情况:
# list settings
git config --list
(1)对单个仓库单独配置用户信息(Change Username and Email for Single Repository):
- 首先进入仓库的工作母目录下,然后运行如下git命令:
git config user.name "Your Name"
git config user.email "your-email-address@domain.com"
- 上述git配置将会覆盖全局git配置
(2)git用户信息全局配置(Setup Username & Email Globally)
git config --global user.name "Your Name"
git config --global user.email "your-email-address@domain.com"
参考资料:
3.13 git 自动化
3.13.1 git hooks (readme)
在编写R包时,通常会编写一个 README.Rmd 文件,然后将其呈现给 README.md。
问题是我会经常忘记渲染README.Rmd文件(rmarkdown::render('README.Rmd')
),这意味着尽管保持最新,但其他readme.html页面仍旧会落后于更新。
要做到这一点很简单(参看),只需在”.git/hooks”文件夹中创建一个名为”pre-commit”的文件,内容如下:
#!/bin/sh
if [ README.Rmd -nt README.md ]
then
R -e "rmarkdown::render('README.Rmd')"
git add README.md
fi
然后你只需要在Terminal窗口中$ git add .
,就可以自动渲染README.Rmd
文件。
注意
git add .
后会生成”readme.html”文件,因此还需要再add
一遍,然后再commit
,最后push
。
3.13.2 github action
在网页数据抓取中,github action可以实现云端无人值守的自动化数据抓取。
github action 通过.github/workflows/your-action-setting.yaml
文件(可参看我的yaml file)来定义自动化工作流。
下面记录几个经验法则:
(1)github 仓库类型会影响github action的调用权限和使用次数。因此,github 仓库最好是以公开方式(public),而不是私有方式(private)。因为github action对公开型仓库可以无限制使用(参看我的covid19仓库),而对私有仓库则采取定价收费方式。
(2)虚拟机操作系统的选择也很关键。经过测试,使用macos-latest
是一个比较可靠的选择。
jobs:
# This workflow contains a single job called "generate-data"
generate-data:
# The type of runner that the job will run on
runs-on: macos-latest
(3)时间规划要考虑时区问题。cron规则使用的是UTC时间(各种原因可参看博文),而UTC time = Shanghai time - 8 hours
。
name: Scrape covid19 risk area
on:
schedule:
- cron: '30 1,4,7,11,14 * * *'
# UTC time = sahnghai time - 8 hours
- cron: '30 9,12,15,19,22 * * *'
# shanghai time = UTC time + 8 hours
(3)renv的包环境管理可以大大节约环境准备时间。具体而言:第1步进行本地操作。本地电脑上先运行renv,并把所有需要的R包进行安装,renv::snapshot()
保存好所有包记录,然后提交。第2步配置github action .yml
文件。其中的一个关键在于renv的路径配置,不同的操作系统renv路径各不相同(见下表,具体参看renv官网说明)。另一个关键在于,正确指定云端runner调用缓存的R环境,包括R包。
- uses: actions/cache@v2
with:
path: ~/Library/Application Support/renv #~/.local/share/renv
key: ${{ runner.os }}-renv-${{ hashFiles('**/renv.lock') }}
restore-keys: |
${{ runner.os }}-renv-
- name: Install dependencies
run: |
renv::restore()
shell: Rscript {0}
Platform | Location |
---|---|
Linux | ~/.local/share/renv |
macOS | ~/Library/Application Support/renv |
Windows | %LOCALAPPDATA%/renv |
(4)RSelenium进行动态网站抓取。在scrape.R
文件中,可以如常使用RSelenium包进行动态网站内容抓取,但是最好调用Firefox浏览器(chrome浏览器更新会带来了一些bug,例如对网站的访问限制等) 。
- uses: browser-actions/setup-firefox@latest
- run: firefox --version
- name: Scrape the data
run: |
source("scrape-covid19.R", encoding='UTF-8')
shell: Rscript {0}
相关学习资源:
Using Github Actions as a job scheduler for R scripts (see)
RSelenium script via GitHub actions (see twitter)