git format-patch and git diff

git中则提供了两种patch方案:

用git diff生成的标准patch,可以提供上述的patch命令使用。
用git format-patch生成的git专用patch。
两种patch的比较:

兼容性:很明显,git diff生成的patch兼容性强。如果你在修改的代码的官方版本库不是git管理的版本库,那么你必须使用git diff生成的patch才能让你的代码被项目的维护人接受。
除错功能:对于git diff生成的patch,你可以用git apply –check查看补丁是否能够干净顺利地应用到当前分支中;如果git format-patch生成的补丁不能打到当前分支,git am会给出提示,并协助你完成打补丁工作,你也可以使用git am -3进行三方合并,详细的做法可以参考git手册或者《Progit》。从这一点上看,两者除错功能都很强。
提交信息:由于git format-patch生成的补丁中含有这个补丁开发者的名字,因此在应用补丁时,这个名字会被记录进版本库,显然,这样做是恰当的。因此,目前使用git的开源社区往往建议大家使用git format-patch生成补丁。

git merge 和 git rebase

git merge简要说明

  1. git merge会产生一次新的commit版本,并且此版本会有2个或者更多个父提交,可以通过HEAD^1,HEAD^2,HEAD^n方法来引用此提交的父提交。
  2. git merge是非破坏性的(non-destructive)操作,没有负作用,并且被合并的这些分支都可以git push发布到remote公共仓库中。
  3. 由于每次合并会产生一次新的提交历史,如果主分支非常活跃,就会产生很多这种合并分支的提交历史,会对项目本身的提交历史产生污染。
    git-rebase-test.sh测试脚本

git rebase简要说明

  1. git rebase 会产生一个修改过的很干净的项目提交历史,例如在feature分支上git rebase master,会将feature分支上的提交添加到master分支的最顶端。
  2. git rebase操作有负面效果,影响项目提交历史的安全性(safety)和可追溯性(traceability)。
  3. git rebase -i master可以交互式压缩提交(squash)或者忽略指定提交。
  4. git rebase使用黄金守则: NEVER USE IT ON PUBLIC BRANCHES.
  5. 不要将主分支rebase到特性分支上(don’t rebased master onto your feature branch: git rebase feature)。
  6. 其他开发者提交的新特性和修改(如patch)应该创建一个临时分支apply这些修改,再使用git merge合并修改到主分支上,而不是使用git rebase方式操作,因为rebase操作修改了提交历史,很难追溯哪些提交新增了这些特性和修改。

关于文件大小写

突然发现自己的电脑中,git对文件大小写是不敏感的,执行下面的命令吧

1
2
3
4
# 全局
git config --global core.ignorecase false
# 项目
git config core.ignorecase false

修正文件大小写

受文件系统的影响,直接修改可能会行不通

1
2
git mv filename FileName
# fatal: destination exists

方案1

1
2
git mv filename filename_tmp
git mv filename_tmp FileName

方案2(awesome)

1
git mv -f filename FileName

git本地化操作

很多时候我们会有一些本地化的代码修改操作,却并不想污染到代码仓库,有如下技巧

.git/info/exclude文件中进行文件的跟踪忽略,效果同.gitignore

假定开发人员不会更改文件,此标志用于提高 not-changing 文件夹(如SDK)的性能。
git update-index –skip-worktree

用于命 GIT 不再染指特定文件,即便开发人员可能更改它
git update-index –assume-unchanged

mysql配置远程访问

建立远程访问用户

1
2
3
4
5
GRANT ALL PRIVILEGES ON *.* TO 'YOURUSER'@'%' IDENTIFIED BY 'YOURPASSWORD' WITH GRANT OPTION;
FLUSH PRIVILEGES;
#查看结果:
SELECT * from information_schema.user_privileges where grantee like "'YOURUSER'%";

配置my.cnf,通常是/etc/mysql/my.cnf,找到并注释掉下面语句

1
2
3
bind-address = 127.0.0.1 # 或者改成 bind-address = 0.0.0.0
skip-networking

重启服务器

Bonus-Tip: Revoke Access

If you accidentally grant access to a user, then better have revoking option handy.

1
2
3
4
5
#Following will revoke all options for THEUSER from all machines:
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'THEUSER'@'%';
#Following will revoke all options for THEUSER from particular IP:
mysql> REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'THEUSER'@'1.2.3.4';

Its better to check information_schema.user_privileges table after running REVOKE command.

If you see USAGE privilege after running REVOKE command, its fine. It is as good as no privilege at all. I am not sure if it can be revoked.

那些概念

全局变量的缺点

全局变量的优点是使用方便。 其缺点也是明显的,这里指针对两点说明

  • 不能保证值的正确性;因为其作用域是全局,所以程序范围内都可以修改它的值,如果出现错误非常难以发现。

  • 如果在多线程中使用全局变量,你的程序将会错的一塌糊涂。多线程会修改另一个线程使用的全局变量的值,如果不注意,一旦出错后果不堪设想。所以在这种情况下万不得意不要使用全局变量。

  • 增加了模块的偶合

  • 全局变量保存在静态存贮区,程序开始运行时为其分配内存,程序结束释放该内存。与局部变量的动态分配、动态释放相比,生存期比较长,因此过多的全局变量会占用较多的内存单元。

  • 全局变量破坏了函数的封装性能。前面的章节曾经讲过,函数象一个黑匣子,一般是通过函数参数和返回值进行输入输出,函数内部实现相对独立。但函数中如果使用了全局变量,那么函数体内的语句就可以绕过函数参数和返回值进行存取,这种情况破坏了函数的独立性,使函数对全局变量产生依赖。同时,也降低了该函数的可移植性。

  • 全局变量使函数的代码可读性降低。由于多个函数都可能使用全局变量,函数执行时全局变量的值可能随时发生变化,对于程序的查错和调试都非常不利。

全局函数 静态方法

global method适合定义一种与任何对象无紧密联系的服务

static method适合定义与对象类型关系密切,但是与单一对象不十分密切的服务。

函数副作用&纯函数

在计算机科学中,函数副作用指当调用函数时,除了返回函数值之外,还对主调用函数产生附加的影响。例如修改全局变量(函数外的变量)或修改参数。

函数副作用会给程序设计带来不必要的麻烦,给程序带来十分难以查找的错误,并降低程序的可读性。严格的函数式语言要求函数必须无副作用。

如果一个函数通过隐式(Implicit)方式,从外界获取数据,或者向外部输出数据,那么,该函数就不是纯函数,叫作非纯函数(Impure Function)。

php中的异常与错误

异常是指程序运行中不符合预期情况以及与正常流程不同的状况。错误则属于自身问题,是一种非法语法或者环境问题导致的、让编译器无法通过检查设置无法运行的情况。

php只有在你throw 一个异常后,才能用try…catch来捕获异常(一般情况下如此,也有部分异常可以自动捕获)。

历史原因导致php的异常处理是不足的,绝大多数情况下,无法自动抛出异常,必须使用if…else先进行判断,再手动抛出异常。

1
2
3
4
5
6
7
8
9
10
11
12
13
function customError($errno, $errstr, $errfile, $errline)
{
//自定义错误处理是,手动抛出异常
throw new Exception($errstr);
}
set_error_handler('customError', E_ALL | E_STRICT);
try {
$a = 5/0;
} catch (Exception $e) {
echo '错误信息:', $e->getMessage();
}

fetal error这样的错误无法捕获,也无法在发生后恢复流程处理,但是可以使用register_shutdown_function()函数在程序终止或die时触发一个函数,给程序带来一个短暂的回光返照。在php4时,不支持析构函数,也常用于模拟实现析构函数。

Parse error级别的错误,除了修改ini文件,将错误信息写到日志中,什么也做不了。

无论是错误还是异常,都可以使用handler接管系统已有的处理机制。

git 命令

删除远程分支

1
2
3
4
# As of Git v1.7.0, you can delete a remote branch using
git push origin --delete <branch_name>
# which is easier to remember than
git push origin :<branch_name>

git用得时间多了,会变慢。 那么可以用下面的命令优化一下

1
2
git gc - Cleanup unnecessary files and optimize the local repository
git-repack - Pack unpacked objects in a repository

那些git命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
git push origin test:test # 提交本地test分支作为远程的test分支
git push --tags # 上传所有标签
git remote set-url --push [name] [newUrl] # 修改远程仓库
git pull [remoteName] [localBranchName]
git push [remoteName] [localBranchName]
git merge [name] # 将名称为[name]的分支与当前分支合并
git rebase [name] #会将[name]分支的代码合并过来,并按照提交的顺序排序(衍合指定分支到分支到当前分支)
git merge-base branchA branchB #查看2分支的公共节点
git diff $(git-merge-base A B) B
# 按时间逆序列出提交对象,常用于查找涉及到某些文件的提交的hash
git rev-list
git shortlog
# 查看在branch上的,但不在master上的记录
git log branch --not master
git fsck --lost-found //检查丢失的提交
git ls-files --stage //可以显示出索引的内容
git checkout . //撤销所有修改
git clean -xfd //连 gitignore 的untrack 文件/目录也一起删掉
git branch --merged | xargs git branch -d //删除已经合并的分支
# list all ignored files in this project
git ls-files --other --ignored --exclude-stanard
# reset and preserve uncommitted local changes
git reset --keep $COMMIT
# create a new tracking branch based on a remote branch
git checkout --track $UPSTREAM/$REMOTE_BRANCH

View a file in a different Git branch without changing branches

1
2
3
4
git checkout $REVISION -- $FILE
git checkout $REVISION -- "*" switch all files without changing brnaches
git show $REVISION:$FILE
git checkout --orphan $BRANCH

Make an existing Git branch track a remote branch

1
2
3
4
5
6
7
8
9
10
git branch -u $UPSTREAM/$REMOTE_BRANCH $LOCAL_BRANCH
git branch --set-upstream-to=$UPSTREAM/$REMOTE_BRANCH
git push -u $UPSTREAM $REMOTE_BRANCH
git remote add $UPSTREAM <remote-url>
git fetch $UPSTREAM
git branch -f --track $LOCAL_BRANCH $UPSTREAM/$REMOTE_BRANCH
# OR:
git branch --set-upstream $LOCAL_BRANCH $UPSTREAM/$REMOTE_BRANCH

diff changes only among certain file(s)

1
2
3
4
git diff $BRANCH1 $BRANCH2 -- $FILE1 $FILE2
(branch1 is optional and your current branch (the branch you are on) will be considered by default if branch1 is not provided)
git diff $REVISION $FILE

other command

1
2
3
4
5
6
7
8
9
10
bisect #Find by binary search the change that introduced a bug
grep #Print lines matching a pattern
git log --since="two weeks ago" --until="two days ago"
git log --since=four.days --until=two.days
git instaweb
git ls-tree #view git tree view
git rm -rf . # Delete everything in the orphan branch
git stash save --keep-index # stash only unstaged files
git merge --squash $BRANCH
git rev-parse --abbrev-ref HEAD #判断当前分支

列出当天某人的所有提交记录

1
git log --author=AUTHOR --oneline --since="6am" --graph --all --decorate

Find the nearest parent branch of the current git branch

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#!/usr/bin/env zsh
branch=`git rev-parse --abbrev-ref HEAD`
git show-branch | ack '\*' | ack -v "$branch" | head -n1 | sed 's/.*\[\(.*\)\].*/\1/' | sed 's/[\^~].*//'`
# How it works:
# 1| Display a textual history of all commits.
# 2| Ancestors of the current commit are indicated
# by a star. Filter out everything else.
# 3| Ignore all the commits in the current branch.
# 4| The first result will be the nearest ancestor branch.
# Ignore the other results.
# 5| Branch names are displayed [in brackets]. Ignore
# everything outside the brackets, and the brackets.
# 6| Sometimes the branch name will include a ~2 or ^1 to
# indicate how many commits are between the referenced
# commit and the branch tip. We don't care. Ignore them.

or

1
2
branch=`git rev-parse --abbrev-ref HEAD`
git show-branch -a 2>/dev/null | grep '\*' | grep -v "$branch" | head -n1 | sed 's/.*\[\(.*\)\].*/\1/' | sed 's/[\^~].*//'

iTerm2奇淫技巧

control + a
回到行首。这个对于用过unix系统的童鞋来说再熟悉不过。

control + e
有了回到行首,当然不能错过光标回到行尾,写文章,打命令,这两个快捷键都是用的很频繁的。

control + w
删除之前一个单词。这个快捷键是我意外发现的,既然有删除之前一个单词,我觉得应该会有删除后面一个单词,但我至今没发现,如果你会请告诉我,重金打赏。

control + u
清除当前行。

control + p
上一条命令。

control + k
删除命令行文本到末尾。

control + l
清屏。

control + r
搜索命令历史。这个也是我经常用的快捷键,有时候你忘了正行命令,用这个命令很不错的,当然history | grep ** 会更有用些。

前一标签页
+ shift + Left

后一标签页
+ shift + Right

配置linux服务器常用命令

安装lnmp

1
2
3
4
5
6
7
8
9
sudo LC_ALL=en_US.UTF-8 add-apt-repository ppa:ondrej/php
sudo apt install -y language-pack-en-base
locale-gen en_US.UTF-8
sudo apt -y install php7.1
sudo apt install -y php7.1-fpm php7.1-mysql php7.1-curl php7.1-xml php7.1-mcrypt php7.1-json php7.1-gd php7.1-mbstring
sudo apt install mysql-server-5.7
sudo apt install nginx
sudo apt install redis-server php-redis

安装composer

1
2
3
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php -r "if (hash_file('SHA384', 'composer-setup.php') === 'e115a8dc7871f15d853148a7fbac7da27d6c0030b848d9b3dc09e2a0388afed865e6a3d6b3c0fad45c48e2b5fc1196ae') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"\nphp composer-setup.php
php -r "unlink('composer-setup.php');"

配置 www \ www-data 用户权限

1
2
3
4
5
sudo -Hu www-data ssh-keygen -t rsa -C "entimm@gmail.com"
sudo chown -R www-data:www-data /var/www/
sudo visudo
sudo passwd www-data
vim /etc/passwd

安装ohmyzsh

1
2
apt install zsh
sh -c "$(curl -fsSL https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"

安装配置node环境

1
2
3
4
5
curl --silent --location https://deb.nodesource.com/setup_4.x | bash -
apt install -y nodejs
npm install -g gulp
npm install -g bower
echo '\n#alias for cnpm\nalias cnpm="npm --registry=https://registry.npm.taobao.org \\n --cache=$HOME/.npm/.cache/cnpm \\n --disturl=https://npm.taobao.org/dist \\n --userconfig=$HOME/.cnpmrc"' >> ~/.zshrc && source ~/.zshrc