Git示例
WebHook代码自动部署
linux文件权限问题
- 修改需要执行的.sh脚本对应的目录为777
# 假设所有脚本都位于:/runtime/shell下
chmod -R 777 /www/wwwroot/api.foo.com/runtime/shell/- .sh脚本内部注意不要使用window系统的换行符\n,否则linux执行会报:
$'\r': command not found
npm和node版本问题
- 建立软连接,防止使用其他版本npm(可能因版本过高,导致执行
npm install或者npm run build报错)
# 此处使用了宝塔安装:PM2管理器,并使用nvm版本切换npm版本至node:v14.19.1、npm:v6.14.16
# 基于此建立的软连接,其他的使用 whereis node 和 whereis npm 寻找自己系统的路径
$ ln -s /www/server/nvm/versions/node/v14.19.1/bin/node /usr/bin/node
$ ln -s /www/server/nvm/versions/node/v14.19.1/bin/npm /usr/bin/npm为Sublime Text 3添加快捷键
- 1)在环境变量Path中添加Sublime Text 3的安装目录,如:
D:\Sublime Text 3 - 2)在命令行窗口(git、cmd),输入:subl,即可快速打开Sublime。
为git设置全局用户信息,并使用Subl命令快速找到该配置文件
# 配置
git config --global user.email "732722725@qq.com"
git config --global user.name "Token"
# 定位到该配置文件
$ subl .gitconfig获取Git的配置信息
git config --list创建一个项目仓库
$ mkdir hpx
$ cd hpx
$ git init
$ ll -a
$ subl .git/config # 打开该仓库的配置文件
$ git config user.name "Token" # 为该仓库指定用户名创建测试文件,并提交到仓库
$ touch index.php # touch命令创建文件,须在该目录不存在该文件才创建
$ touch product.php
$ git add . # 提交到暂存区
$ git commit -m '测试学习' # 提交到仓库
$ git status (显示:On branch master nothing to commit, working tree clean)创建忽略文件.gitignore
$ subl .gitignore # 并增加内容:*.txt
$ touch note.txt # 创建note.txt文件
$ git status # 此时,发现git不提示.txt文件入暂存区
$ ll -a # 验证note.txt是存在的,但被仓库忽略了忽略文件.gitignore的用法
*.txt
!a.txt
注:所有.txt都会被忽略,除了a.txt。空文件夹,会被git忽略。不提示入暂存区
$ mkdir vendor
$ touch vendor/index.php
$ ls vendor
$ git status
# 修改.gitignore,增加:
# /vendor (此时,会忽略vendor所有的文件)
# /vendor/index.php (只会忽略vendor下的index.php,不会限制其它同级文件以及二级目录的文件)
# /vendor/*.php (忽略vendor所有的同级目录下的文件)
# /vendor/**/*.php (忽略整个vendor所有的文件,即包括其二级以上子目录的所有文件,与/vendor等同)忽略文件
有时候我们不想把某些文件纳入版本控制中,比如数据库文件,临时文件,设计文件等 在主目录下建立".gitgnore"文件,此文件有如下规则: 1.忽略文件中的空行或以井号(#)开始的行将会被忽略。 2.可以使用Linux通配符。例如:星号(* )代表任意多个字符,问好(?)代表一个字符,方括号([abc])代表可选字符范围,大括号({string1,string2,...})代表可选的字符串等。 3.如果名称的最前面有一个感叹号(!),表示例外规则,将不被忽略。 4.如果名称的最前面是一个路径分隔符(/),表示要忽略的文件在此目录下,而子目录中的文件不忽略。 5.如果名称的最后面是一个路径分隔符(/),表示要忽略的是此目录下该目录的子目录,而非文件(默认文件或目录忽略)。
#为注释
*.txt # 忽略所有.txt结尾的文件,这样的话上传就不会被选中!
!lib.txt # lib.txt除外
/temp # 仅忽略项目根目录下的TODO文件,不包括其它目录temp
build/ # 忽略build/目录下的所有文件
doc/*.txt # 会忽略doc/notes.txt但不包括doc/server/arch.txtfatal: pathspec 'fileName' did not match any files 解决办法
产生原因:该文件存在于.gitignore文件中,因此不让动! 解决方案:既然知道原因那就好办了
- 将文件从.gitignore移除
- 将移除后的.gitigore文件提交(或者将文件提交)
- 我的操作步骤是 a. git add . b.git commit -m ‘这次把信息移除了’ c.git rm fileName
文件就可以正常删除了
删除本地与仓库的文件
$ touch a.txt
$ git add a.txt
$ git commit -m '添加a.txt文件'
$ ls
$ git rm a.txt
$ git commit -m '本地与仓库都删除a.txt'
$ git status只删除仓库文件,不删除本地文件
场景:误上传操作。比如/vendor、/node_modules等根本没必要提交的文件。此时可以将仓库移除(本地保留)
$ touch readme.txt
$ git commit -m '创建readme.txt文件' # 要在.gitignore放开忽略限制,否则提交不成功
$ git rm --cached readme.txt
$ ls # 此时,发现readme.txt文件本地还在,但是仓库已经删除了
$ git status # 显示两个信息,一个是移除readme.txt,一个是readme.txt不在暂存区中
$ git commit -m '删除仓库中的readme.txt' # 提交移除文件
$ git status仅仅删除暂存区里的文件
$ git add readme.txt # 添加到暂存区
$ git rm --cache readme.txt # 撤销错误添加到暂存区里的文件
$ git status查看当前分支所属
$ git branch -vv
$ git config --list查看分支
$ git branch -a # 查看远程分支
$ git branch # 查看本地分支查看当前的远程库
$ git remote # 已经存在的远程分支名
$ git remote -v # 列出详细信息,在每一个名字后面列出其远程url
$ git remote --verbose # 与-v一样
$ git remote add 主机名 远程仓库地址
# 例如:git remote add origin https://github.com/lintong7/SoftSystem.git
$ git remote show origin # 查看对应名称的远程主机的详细信息
$ git remote rm 主机名 # 删除远程主机
$ git remote rename 原主机名 新主机名 # 修改主机名命令git mv用于移动或重命名文件,目录或符号链接
$ touch indexcontroller.php
$ git add .
$ git commit -m 'commit first'
$ git mv indexcontroller.php indexController.php
$ git add .
$ git commit -m 'rename file'
$ git status查看提交历史
$ git log
# 会按提交时间列出所有的更新,最近的更新排在最上面(SHA-1 校验和、作者的名字和电子邮件地址、提交时间,最后缩进一个段落显示提交说明)
$ git log -p -2
# 展开显示每次提交的内容差异,用 -2 则仅显示最近的两次更新
$ git log -U1 --word-diff
# 获取单词层面上的对比(新增加的单词被 {+ +} 括起来,被删除的单词被 [- -] 括起来。在进行单词层面的对比的时候,你可能希望上下文( context )行数从默认的 3 行,减为 1 行,那么可以使用 -U1 选项。)
$ git log --stat # 仅显示简要的增改行数统计
$ git log --oneline # 查看简短的提交信息
# 如:
# 2c1862b (HEAD -> master) rename file
# bc61401 第一次提交
$ git log --oneline -p
$ git log --name-only # 查看哪些文件发生变化
$ git log --name-status # 查看文件修改的类型(添加A|修改M|删除D)
$ git log --pretty=oneline
# 如:
# 2c1862b0b7a8e733016a900837f0c0dd295d1bea (HEAD -> master) rename file
# bc61401235c9490db5c42293b7646e93f4f5c009 第一次提交
# 常用的 --pretty 选项,可以指定使用完全不同于默认格式的方式展示提交历史。比如用 oneline 将每个提交放在一行显示,这在提交数很大时非常有用。另外还有 short,full 和 fuller 可以用。
$ git log --pretty=format:"%h %s" --graph
# 用 oneline 或 format 时结合 --graph 选项,可以看到开头多出一些 ASCII 字符串表示的简单图形,形象地展示了每个提交所在的分支及其分化衍合情况。重写历史
$ git commit --amend # 改变最近一次提交
$ touch news.php
$ git add .
$ git status
$ git commit --amend # 更改最近一次提交的历史信息
$ git log # 发现news.php提交上去了,与最近一次提交合并撤销暂存区
# 首次初始化git,并创建a.php
$ git init
$ touch a.php
$ git add a.php
$ git status
# 首次提交到暂存区,从暂存区中移除到本地环境
$ git rm --cached a.php
$ git status
# 第二次提交到暂存区,撤销
$ git add .
$ git commit -m '添加a.php'
$ vim a.php # 此处随便修改a.php的内容,保存退出
$ git add a.php
$ git reset HEAD a.php
$ git status
$ cat a.php
# 撤销恢复到最开始的状态
$ git checkout -- a.phpalias命令别名
$ cd
$ subl .gitconfig
$ git config --global alias.a add
# 此时即可使用git a .提交代码到暂存区,同理可修改.gitconfig直接加入其它别名,完整如下:
# [alias]
# a = add
# c = commit
# l = log
# s = status
$ git init
$ touch a.php
$ git s
$ git a
$ git lbranch分支的基本操作(查看、创建、切换、合并、删除)
#查看分支
$ git branch # 查看本地分支(列出所有本地分支)
$ git branch -r # 查看远程分支(列出所有远程分支)
# 创建分支
$ git branch [branch] # 创建分支(依然停留在当前分支)
# 本地分支重命名
$ git branch -m oldName newName
# 切换分支
$ git checkout [branch] # 切换分支
$ git checkout -b [branch] # 创建分支,并切换到该分支
# 合并分支
$ git checkout master # 切换到master分支
$ git merge [branch] # 合并指定分支到当前分支(master)
# 删除分支
$ git branch -d [branch-name]
# 删除远程分支
$ git push origin --delete [branch-name]
$ git branch -dr [remote/branch]分支冲突
# 在master主分支下创建index.php并提交
$ git branch ask # 创建分支
$ git checkout -b bbs # 创建并切换到bbs分支
$ vim index.php # 在bbs分支下修改index.php并提交
$ git branch ask # 切换到ask分支
$ vim index.php # 修改index.php并提交
$ git checkout master # 切换到master主分支
$ git merge bbs # 合并bbs分支(成功,master没有修改index.php)
$ git merge ask # 合并ask分支(失败,因为bbs有修改过index.php)
# 此时进入到冲突状态,命令行标注状态:(master|MERGING)
$ vim index.php # 编辑两个分支的冲突部分
$ git add . # 再次提交
$ git commit -m 'succ' # 解决冲突,并提交成功
# 查看合并过的分支
$ git branch --merged
# 查看未合并的分支
$ git branch test # 创建新的分支test
$ git branch --merged # 因为刚刚创建,跟master并没有文件结构区别,所以也显示合并状态
# 切换到test分支,新增a.php并提交,然后回到master分支查看
$ git branch --no-merged # 查看未合并分支,出现test
# 分支的删除1:未合并的删除
$ git branch -d test # 如果是未合并的分支,不允许删除
$ git branch -D test # 强行删除,不考虑是否合并等情况stash临时储存区
# 多分支环境下,假设当前分支存在修改文件,但功能未完成,不想提交代码。此时,可以使用临时储存区
$ git stash # 增加临时储存区(需要文件在版本库,新建未提交不能提交暂存,需要add)
$ git stash list # 显示临时储存区列表
# 显示:stash@{0}: WIP on ask: 4ad1139 ask commit
$ git checkout bbs # 切换成功(不增加到储存区,会切换失败)
# 恢复储存区
$ git stash apply # 需要切换回之前增加临时储存区的分支
# 删除储存区
$ git stash drop stash@{0}
# 以上可先后多次修改文件,多次增加临时储存区。tag标签
$ git tag v0.0.1 #新增标签
$ git tag #查看标签
# 注意:打标签需要遵循稳定版本为主,切勿随意打标签。有利于开发者下载稳定版本代码生成ZIP代码发布压缩包
$ git archive master --prefix='token/' --forma=zip > token.zip #生产zip压缩包
# --prefix是表示在压缩包中添加一层文件夹,一般与仓库名相同即可系统alias
在 `~/.bash_profile` 文件中定义
alias gs="git status"
alias gc="git commit -m "
alias gl="git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit "
alias gb="git branch"
alias ga="git add ."
alias go="git checkout"
命令行直接使用 `gs` 即可以实现 `git status` 一样的效果了。rebase合理优化分支合并
$ git init
# 主分支第一次提交
$ touch master.php
$ ga
$ gc 'master commit'
# 分支ask第一次提交
$ go -b 'ask'
$ touch ask.php
$ ga
$ gc 'ask commit'
# 主分支第二次提交
$ go master
$ touch m2.php
$ ga
$ gc 'm2 commit'
# 切换到ask分支时,由于master已经向前移动,如果不想出现合并分支。则可以使用rebase将ask指向最新的master
$ go ask
$ gl
$ git rebase master
$ gl
# 此时合并ask分支,保证合并后在一条线上,而不是出现两条分支
$ go master
$ gl
$ git merge ask
$ gl关联远程
- 创建本地库并完成初始提交
$ echo "# blog" >> README.md
$ git init
$ git add README.md
$ git commit -m "first commit"- 添加远程仓库
$ git remote add origin git@github.com:lintong7/blog.git- 查看远程库
$ git remote -v- 推送数据到远程仓库
$ git push -u origin master通过 clone 克隆的仓库,本地与远程已经自动关联,上面几步都可以省略。
远程分支拉取到本地分支
$ git fetch origin master
$ git merge FETCH_HEAD # 将拉取下来的最新内容合并到当前所在的分支中
# 将远程主机的某个分支的更新取回,并与本地指定的分支合并,完整格式可表示为:
$ git pull <远程主机名> <远程分支名>:<本地分支名>
$ git pull origin master # 如果远程分支是与当前分支合并,则冒号后面的部分可以省略:注意 git fetch 是将远程主机的最新内容拉到本地,用户在检查了以后决定是否合并到工作本机分支中
git pull 则是将远程主机的最新内容拉下来后直接合并,即:git pull = git fetch + git merge,这样可能会产生冲突,需要手动解决。
本地分支与远程分支进行关联
$ git push --set-upstream origin ask # 本地分支首次提交远程分支,提示需要关联
$ git push origin ask # 已经关联后,第二次起的提交删除远程分支、本地分支
$ git push origin --delete ask # 删除远程分支
$ git branch -a # 查看远程分支
$ git branch -d ask # 删除本地分支自动部署
GitHub设置 WebHook

PHP
项目中添加处理 webhook 的webhook.php文件内容如下,并提交到版本库。
<?php
// GitHub项目 Settings/Webhooks 中的 Secret
$secret = "siuchi";
// 网站目录路径
$path = "/www/wwwroot/abc.siuchi.com";
$signature = $_SERVER['HTTP_X_HUB_SIGNATURE'];
if ($signature) {
$hash = "sha1=".hash_hmac('sha1', file_get_contents("php://input"), $secret);
if (strcmp($signature, $hash) == 0) {
echo shell_exec("cd {$path} && /usr/bin/git reset --hard origin/master && /usr/bin/git clean -f && /usr/bin/git pull 2>&1");
exit();
}
}
http_response_code(404);
?>创建站点
下面示例我使用的是 宝塔 主机面板。 
现在服务器上生成了站点目录 /www/wwwroot/abc.siuchi.com ,因为目录中存在 .user.ini 文件(定义站点可以访问的目录权限),造成不能 clone 代码,将目录随意改名。
**开启 shell_exec **
执行 git pull 指令需要使用 shell_exec 函数,删除 shell_exec 禁用函数后重启PHP。

克隆clone代码
登录服务器并使用 https 协议 clone 项目代码
$ ssh root@abc.siuchi.com -p 22
$ git clone https://github.com/lintong7/SoftSystem.git SoftSystem修改权限
chown -R www .
chmod -R g+s .
sudo -u www git pull现在向GitHub 推送代码后,服务器将自动执行代码拉取,自动部署功能设置完成了。
