git rebase

简介

在Git中,用两种方法将两个不同的branch合并。一种是通过git merge,一种是通过git rebase。然而,大部分人都习惯于使用git merge,而忽略git rebase。本文将介绍git rebase的原理、使用方式及应用范围。

git merge 做些什么

当我们在开发一些新功能的时候,往往需要建立新的branch。

在上图中,每一个绿框均代表一个commit。除了c1,每一个commit都有一条有向边指向它在当前branch当中的上一个commit。

图中的项目,在c2之后就开了另外一个branch,名为experiment。在此之后,master下的修改被放到c4 commit中,experiment下的修改被放到c3 commit中。

如果我们使用merge合并两个分支
$ git checkout master
$ git merge experiment

得到的commit log如下图所示

我们看到,merge所做的事情实际上是:

  1. 首先找到masterexperiment中最新的commit的最近公共祖先,在这里就是c4c3的最近公共祖先c2
  2. experiment分支上在c2以后的所有commit合并成一个commit,并与master合并
  3. 如有合并冲突(两个分支修改了同一个文件),首先人工去除重复。
  4. 在master上产生合并后的新commit

git rebase做些什么

rebase所做的事情也是合并两个分支,但是它的方式略有不同。基于上例描述,rebase的工作流程是

  1. 首先找到masterexperiment中最新的commit的最近公共祖先,在这里就是c4c3的最近公共祖先c2
  2. experiment分支上在c2以后的所有commit*全部移动到*master分支的最新commit之后,在这里就是把c3移动到c4以后。

由于git的每一个commit都只存储相对上一个commit的变化(或者说是差值,delta)。我们通过移动c3到master,代表着在master上进行c3相应的修改。为了达成这一点,只需在experiment分支上rebase master
$ git checkout experiment
$ git rebase master

需要注意的是,rebase并不是直接将c3移动到master上,而是创建一个副本。我们可以通过实际操作发现这一点。在rebase前后,c3的hash code是不一样的。

rebase前的commit log是
* 1b4c6d6 (master) <- c4
| * 66c417b (experiment) <- c3
|/
* 972628d

rebase后的commit log是
* d9eeb1a - (experiment) <- c3'
* 1b4c6d6 - (master) <- c4
* 972628d

可以发现c3的hash code从66c417b变到了d9eeb1a

在这之后,我们只需要在master上进行一次前向合并(fast-forward merge)
$ git checkout master
$ git merge experiment

rebase之后的commit log呈线性,更加清晰。此时如果experiment分支不再被需要,我们可以删除它。
$ git branch -d experiment

何时使用

我们一般只在本地开发的时候rebase一个自己写出来的branch。

谨记,千万不要rebase一个已经发布到远程git服务器的分支。例如,你如果将分支experiment发布到了GitHub,那么你就不应该将它rebasemaster上。因为如果你将它rebasemaster上,将对其他人造成麻烦。

总结

git rebase帮助我们避免merge带来的复杂commit log,允许以线性commit的形式进行分支开发。

awk使用

awk 处理数据挺方便的,整理下使用方法。

先看下最简单的用法

下面是数据,文件名pic.csv

10371029    130657404  33250828600
10375462   0  32754488348
10401830   130670653  33301943326
10490532   130818323  33390650001,33390638503
10492736   130808000  33392915994,33392923278,33392951671,33392965894
10501933   130847315  33426734671,33426784141,33426741368
10520323   130871605  33474622551
10561441   130900744  33569740772
10563686   130931058  33572560455,33572597666,33572625609
10594334   130933942  33595945445,33595930712
10609164   130968431  33625612546
10623734   130960850  33655945376
10625513   130985226  33659411835,33659434639
10662700   131036062  33748007817
10688362   131050019  33802663455
10744503   131143877  33909572401,33909557630
10749313   131138769  33912184752
10777611   131181015  33975768553
10790647   131192937  34013919173,34013904105,34013909379
10790833   131198786  34014605153,34014654005,34014895558,34014920756
10799709   131213531  34039005481
10805941   131221289  34048620033,34048637653
10806145   131228025  34049593438,34049617769,34049618566,34049596717
10837378   131259345  34138112374,34138156606
10847268   131293940  34163393641,34163387864

只看前两列

awk '{print $1,$2}' pic.csv

数据过滤,只看第一列数字为10847268

awk ' $1==10847268' pic.csv

内建变量
说到了内建变量,我们可以来看看awk的一些内建变量:

$0 当前记录(这个变量中存放着整个行的内容)
$1~$n 当前记录的第n个字段,字段间由FS分隔
FS 输入字段分隔符 默认是空格或Tab
NF 当前记录中的字段个数,就是有多少列
NR 已经读出的记录数,就是行号,从1开始,如果有多个文件话,这个值也是不断累加中。
FNR 当前记录数,与NR不同的是,这个值会是各个文件自己的行号
RS 输入的记录分隔符, 默认为换行符
OFS 输出字段分隔符, 默认也是空格
ORS 输出的记录分隔符,默认为换行符
FILENAME 当前输入文件的名字

awk  -F: '{print $1,$3,$6}' OFS="\t" /etc/passwd
root    0       /root
bin     1       /bin
daemon  2       /sbin
adm     3       /var/adm
lp      4       /var/spool/lpd
sync    5       /sbin

如果把文件第一列用逗号分隔,可以用

awk 'ORS="," {print $1}' pic.csv

SwitchyOmega插件的使用

好多小伙伴使用Shadow穿墙后就使用默认的设置,这样很麻烦,尤其是在公司使用内网的情况下,来回切换,我就简单说下如何设置。

首先Shadow 启动后会在本地建立一个1080的端口,用于代理。只要设置socket5代理用这个端口就行了,所以我们大可以关掉软件自带的代理模式,保持清爽,设置如下,取消勾选启用系统代理。

AB5001AC-0E4F-4DB3-9C75-3F92BE7DD055

然后安装Chrome浏览器,安装SwitchyOmega插件 去应用商店下载或在https://github.com/FelisCatus/SwitchyOmega/releases 下载

然后开始设置了。

首先设置一个模式,使用Shadow代理,选择新建情景模式,设置如下

641f6412121e5c4b4a8106d621e897b4

设置好后就可以设置自动代理了,选择自动切换,设置如下:

 

00E69715-7B5A-42A7-9608-F6705BA97E02

Autoproxy 链接为

https://raw.githubusercontent.com/calfzhou/autoproxy-gfwlist/master/gfwlist.txt

然后就可以愉快的上网了。

CAFD1AB5-0422-48CE-BCE8-8EFEC74436AD

遇到不能翻墙的网站,别着急,选择右上角的那个图标,设置如下

C699E952-A991-4F32-9B74-DDEC0EC6AECB

3A01272F-25FF-41E2-B53A-4A01654277BF

然后这个网站以后访问就走代理了。

很方便吧。