最近计划好好改改自己的主题,因为随便修改文件现在主题代码给我改的十分难看了,这里加一点那里加一点,出了问题也不知道是哪的问题。于是想到了自己吃灰多年的 Github 账号,知道这个平台后我便时不时在上面“关注”觉得可能会用到的仓库。“关注”的方式我采用粗暴的 Fork 的方式,因为 Star 了之后发现自己的仓库并没有变化。当然,现在我知道了 Star 才是关注大部分项目的正确方式,Fork 下来吃灰等于占用 Github 资源。于是前段时间我将自己 Fork 的近一百个仓库点完 Star 后一股脑删除了。Github 大概没有考虑过像我这种弟弟会有一次删除许多个仓库的需求,都没有这种功能。我还是谷歌了一个一次性删除多个仓库的工具,需要先在 Github 创建 Access Token,详细点的在文末有写。

这里以我 Fork 的仓库 Typecho-Theme-VOID 为例,记录一下自己在本地学习 Git 操作的步骤等,做个备忘先。

简单

最简单的方法就是在 Windows 上安装 Github 的客户端了,拉取提交都通过桌面端来实现,剩下的编辑文件交给 VSCode 等。

但是我觉得这样没有发挥 VSCode 的全部功能啊,还多花了一点点时间在学习 Github 桌面端上。大家都说最适合开发的环境是 Linux,所以我正好利用前两天装的 WSL 来尝试本地开发和 Git 操作。这里以 WSL Ubuntu 为例记录我的一些配置过程,顺便做个 Git 备忘。

安装

在国内 Linux 配置里不可或缺的一步就是添加中国镜像源,ArchLinux 在 /etc/pacman.d/mirrorlist ,Ubuntu 在 /etc/apt/sources.list。列出网上找的清华镜像源、中科大镜像源、阿里云镜像源。

Ubuntu 镜像源
# Tsinghua Mirrors
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic main restricted universe multiverse
deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse
deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse
deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-security main restricted universe multiverse
deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-security main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-proposed main restricted universe multiverse
deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-proposed main restricted universe multiverse

# USTC Mirrors
deb https://mirrors.ustc.edu.cn/ubuntu/ bionic main restricted universe multiverse
deb-src https://mirrors.ustc.edu.cn/ubuntu/ bionic main restricted universe multiverse
deb https://mirrors.ustc.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse
deb-src https://mirrors.ustc.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse
deb https://mirrors.ustc.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse
deb-src https://mirrors.ustc.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse
deb https://mirrors.ustc.edu.cn/ubuntu/ bionic-security main restricted universe multiverse
deb-src https://mirrors.ustc.edu.cn/ubuntu/ bionic-security main restricted universe multiverse
deb https://mirrors.ustc.edu.cn/ubuntu/ bionic-proposed main restricted universe multiverse
deb-src https://mirrors.ustc.edu.cn/ubuntu/ bionic-proposed main restricted universe multiverse

# Ali Mirrors
deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse

接下来是更新系统,安装一些必要组件 git nodejs npm,顺便整了个 alias 的 cnpm 。

sudo apt-get update && sudo apt-get upgrade

sudo apt-get install git

curl -sL https://deb.nodesource.com/setup_13.x | sudo -E bash -
sudo apt-get install -y nodejs

sudo apt-get npm

alias cnpm="npm --registry=https://registry.npm.taobao.org \
 --cache=$HOME/.npm/.cache/cnpm \
 --disturl=https://npm.taobao.org/mirrors/node \
 --userconfig=$HOME/.cnpmrc"

Git 设置

这部分包括设置名字邮箱、还有获取 Github Commit 时高逼格的 verified signature 验证标志!也就是官方说的“提交签名验证”,需要 Git 版本 2.0.0 及更高版本。不管项目写的怎么样,提交一定要有牌面。

# 设置 Git 使用的用户名和邮箱
git config --global user.name '<username>'
git config --global user.email '<emailaddress>'

# 创建版本库:克隆或者本地初始化
git clone <giturl>
git init

# 设置记录提交时仓库地址和用户名、密码
git config credential.helper store

然后是验证标志的获取,Windows PowerShell 和 Ubuntu 的安排方式类似。重点是生成自己的 GPG 密钥对。先安装一个 GnuPG 客户端,Windows 可以用 Gpg4win ,Ubuntu 更新完系统也自带 gpg 包。

# 列出已有密钥对
gpg --list-secret-keys --keyid-format LONG

# 生成新的 GPG 密钥对
gpg --full-generate-key
# 所需的密钥长度必须是 4096 ,默认无过期时间
# 输入邮箱必须是 Github 通过验证的邮箱

# 列出刚刚生成的密钥对
gpg --list-secret-keys --keyid-format LONG

# /root/.gnupg/pubring.kbx
# ------------------------
# sec   rsa4096/56B2DB9B34B4590E 2020-04-12 [SC]
#       A9DE6480E89677DBA12556B056B2DB9B34B4590E
# uid                 [ultimate] monsterxcn <[email protected]>
# ssb   rsa4096/28DD194C879EB3FA 2020-04-12 [E]
# 
# 输出中 sec rsa4096/ 后的即为密钥 ID ,如 56B2DB9B34B4590E

# 以 ASCII 封装格式打印 GPG 密钥 ID
gpg --armor --export 56B2DB9B34B4590E

# 复制输出中以下标志和之间所有内容
# -----BEGIN PGP PUBLIC KEY BLOCK-----
#           ... ... ...        
# -----END PGP PUBLIC KEY BLOCK-----

Github > Settings > SSH and GPG Keys 中导入这个 Key ,生效好像有一会延时,等一小会再尝试签名提交。通常设置了签名密码时每次签名提交需要验证密码,使用第二段中后三行调试即可。

# 设置 Git 使用该 ID 的 GPG 密钥并开启提交签名
git config --global gpg.program gpg
git config --global user.signingkey 56B2DB9B34B4590E
git config --global commit.gpgsign true

# 配置 GPG ,后面三行调试用
gpg --version
test -r ~/.bash_profile && echo 'export GPG_TTY=$(tty)' >> ~/.bash_profile
echo 'export GPG_TTY=$(tty)' >> ~/.profile
echo "test" | gpg --clearsign
export GPG_TTY=$(tty)
echo "test" | gpg --clearsign

# 查看 Git 的 GPG 配置
git config -l | grep gpg

# 显示如下即可
# commit.gpgsign=true
# gpg.program=gpg

好啦,快来开始验证签名 Commit 一次!

git commit -S -m 'add: verified signature'
git push

# 看到官方说明还有验证 tag ,还没懂是怎么用的,这里也记录下来
# 后一个是验证验证签名的 tag
git tag -s <tag>
git tag -v <tag>

Git 日常

Git 的日常就是本地和远程仓库之间不断地 pull push 。要管理分支标签还有好多命令,备忘录开始:

Git Help
usage: git [--version] [--help] [-C <path>] [-c <name>=<value>]
           [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
           [-p | --paginate | --no-pager] [--no-replace-objects] [--bare]
           [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]
           <command> [<args>]

These are common Git commands used in various situations:

start a working area (see also: git help tutorial)
   clone      Clone a repository into a new directory
   init       Create an empty Git repository or reinitialize an existing one

work on the current change (see also: git help everyday)
   add        Add file contents to the index
   mv         Move or rename a file, a directory, or a symlink
   reset      Reset current HEAD to the specified state
   rm         Remove files from the working tree and from the index

examine the history and state (see also: git help revisions)
   bisect     Use binary search to find the commit that introduced a bug
   grep       Print lines matching a pattern
   log        Show commit logs
   show       Show various types of objects
   status     Show the working tree status

grow, mark and tweak your common history
   branch     List, create, or delete branches
   checkout   Switch branches or restore working tree files
   commit     Record changes to the repository
   diff       Show changes between commits, commit and working tree, etc
   merge      Join two or more development histories together
   rebase     Reapply commits on top of another base tip
   tag        Create, list, delete or verify a tag object signed with GPG

collaborate (see also: git help workflows)
   fetch      Download objects and refs from another repository
   pull       Fetch from and integrate with another repository or a local branch
   push       Update remote refs along with associated objects

'git help -a' and 'git help -g' list available subcommands and some
concept guides. See 'git help <command>' or 'git help <concept>'
to read about a specific subcommand or concept.
一些我可能常用的 Git 命令
git add .                               # 跟踪所有改动的文件,添加到暂存区
git add <file>                          # 跟踪指定的文件,添加到暂存区
git rm <file>                           # 删除文件
git rm --cached <file>                  # 停止跟踪文件但不删除
git commit -m 'title' -m 'discription'
git commit -am 'title'                  # 省去 add 提交
git commit --amend                      # 合并历史提交,用于反复修改
git log                                 # 提交历史
git reset --hard HEAD                   # 撤销工作区所有未提交的文件改动
git reset --hard HEAD~1                 # 回滚一次提交,本地文件内容改变
git reset --soft HEAD~1                 # 回滚一次提交,本地文件内容不变
git revert <commit>                     # 撤销指定的提交
git branch                              # 列出本地分支,当前分支带 * 标志
git branch <newbranch>                  # 创建分支
git branch -d <oldbranch>               # 删除分支
git tag                                 # 列出本地标签,当前标签带 * 标志
git tag <newtag>
git tag -d <oldtag>
git checkout HEAD <file>                # 撤销指定文件的未提交改动
git remote set-url origin <newAddress>  # 远程仓库改名时本地重新设置

git merge <branch>                    # 合并指定分支到当前分支
git rebase <branch>                   # “重新打基础”,似乎是合并所有分支的改动到当前
git fetch <remote>                    # 下载远程分支而不覆盖本地工作区
git pull <remote> <branch>            # 下载远程代码并合并
git push <remote> <branch>            # 上传本地代码并合并
git push <remote> :<branch/tag>       # 删除远程分支/标签

重点名词:

  • 工作区
    在本地能看到的改动代码那个那个目录!
  • 版本库
    工作区里一个隐藏文件夹 .git ,包含了一个默认分支 master 、称为 stage / index 的暂存区和指向 master 的指针 HEAD
  • 暂存区
    .git 文件夹下用来暂存改动的文件的地方

了解了这些应该足够成为一个入门级的 Git 用户了,想成为专家靠这里“支离破碎”的介绍并不能行。Git 的使用是一门学问,简单的命令背后是细致的代码版本管理。期待以后深入了解。正如大神廖雪峰所说:“既然 Git 是一个工具,就没必要把时间浪费在那些‘高级’但几乎永远不会用到的的命令上。一旦你真的非用不可了,到时候再自行谷歌或请教专家也未迟”。

VOID

折腾了几遍后我开始以 AlanDecode 的 Typecho-Theme-VOID 为起点,尝试从源码构建自定义的主题。因为在 Gulp 构建后的 JS 和 CSS 中修改真是要命啊,压缩美化混淆之后再修改…… 睿智行为 233

按照 Readme 初始化时遇到了安装 [email protected] 的报错,搜了一圈在 Stack Overflow 看到有人提出了删除 package-lock.json 和 node-modules 的解决方法,尝试了之后结合前面 cnpm 镜像什么的成功安装好环境。

sudo rm -rf package-lock.json node_modules
sudo npm cache clean --force
sudo npm i --unsafe-perm node-sass

npm install -g gulp
npm install

第一次尝试 Gulp 编译 Sass 混淆 JS ,可以说是十分新鲜了。我室友曾经问我是不是想做一个前端工程师,我的回答还是“应该不吧”,而现在我突然有兴趣想成为一个半吊子的前端了。XDDDD ,不吹了,我想起来我的 CSS JavaScript 还在入门的门外徘徊。我模仿开发者的写法对主题进行一点点的修改,然后 git push 到我的 Github ,希望让自己的 Contributions 稍微实在点绿起来!但是今天突然发现我的 commit 在 Fork 仓库中,记录不会显示在 Contributions ,于是我悄咪咪在 Github 重新导入了仓库,然后顺便在 MIT 协议的基础上添加了前段时间发现的一个娱乐 Licence "Good Luck With That" Public License 。

Contributions 绿起来了呢,开心。

来监工提建议:Test
来仓库提 issue OuO:Typecho-Theme-VOID

其他

简单的一次性删除多个 GitHub Repositories 的方法。[来源]

  • 打开 https://repo-sweeper.herokuapp.com/ ,输入 GitHub 用户名并点击下方的“Generate Access Token”
  • 在新打开的 GitHub Personal Access Tokens 页面“Generate new token”,选中“Public_Repo” and “Delete_Repo”权限并点击“Generate”生成 Token
  • 将上一步新生成的 Token 输入 RepoSweeper 网站中,点击“Generate Repo List”等待生成存储库清单
  • 勾选需要删除的仓库,点击“Delete Repos”一键删除