参考:阮一峰-远程操作详解
参考:阮一峰-工作流
SSH
为 Secure Shell 的缩写,是一种网络协议,用于计算机之间的加密登录,如果一个用户从本地计算机,使用ssh协议登录另一台远程计算机,我们可以认为这种登录是安全的,即使被中途截获,密码也不会泄露。ssh之所以安全,因为他采用公钥加密
过程:
- 远程主机收到用户的登录请求,把自己的公钥发给用户,
- 用户使用这个公钥,将登陆密码加密后,发送给远程主机,
- 远程主机用自己的私钥,解密登录密码,如果密码正确,就登录成功。
但也有安全隐患,如果有人截获了登录请求(第一步),然后冒充远程主机,将伪造的公钥发送给用户,那么用户就很难辨别真伪。因为不像https协议那样,ssh协议的公钥是没有证书中心ca公证的,也就是说,都是自己签发。
可以设想,如果攻击者插在用户与远程主机之间(比如公共的wifi区域),用伪造的公钥,获取用户的登录密码,再用这个密码登录远程主机,那么ssh的安全机制就荡然无存。也是中间人攻击(Man-in-the-middle attack)
ssh分客户端openssh-client 和openssh-server,如果只是想登陆别人的机器,ssh只需安装openssh-client(ubantu 有默认安装),如果要想使本机开放ssh服务就需要安装openssh-server。
ssh root@67.218.147.xxx 意思是,安全脚本连接系统用户是root,服务器地址是67.218.147.xxx, ssh默认连接的端口是22,如果想修改端口,需要加 ssh -p 端口号 root@67.218.147.xxx 而ip地址可以通过设置hostname来改变。如上图中root@djch 但连接的时候,不建议这样,ip更加高效。
openSSL
https是一种协议,等于http + TLS(由于历史原因,SSL3.0之后就被TLS1.0替代了) openSSL是一套开源工具集(注意:HTTPS与OpenSSL就是iPhone与富士康的关系。)。
SSL是Secure Sockets Layer(安全套接层协议)的缩写,可以在Internet上提供秘密性传输。Netscape公司在推出第一个Web浏览器的同时,提出了SSL协议标准。其目标是保证两个应用间通信的保密性和可靠性,可在服务器端和用户端同时实现支持。已经成为Internet上保密通讯的工业标准。
SSL能使用户/服务器应用之间的通信不被攻击者窃听,并且始终对服务器进行认证,还可选择对用户进行认证。SSL协议要求建立在可靠的传输层协议(TCP)之上。SSL协议的优势在于它是与应用层协议独立无关的,高层的应用层协议(例如:HTTP,FTP,TELNET等)能透明地建立于SSL协议之上。SSL协议在应用层协议通信之前就已经完成加密算法、通信密钥的协商及服务器认证工作。在此之后应用层协议所传送的数据都会被加密,从而保证通信的私密性。
git相关
工作区:就是我们本地的目录,还没有被 git 管理 暂存区:git 开始管理,只是还没有提交到分支上 commit: commit 后就将暂存区的内容提到分支上了,如果此时在 git push 则把本地修改同步到远程
本地配置多git账户
经常情况下,我们一个电脑需要配置多个账户,比如公司的仓库和自己的github账号。
# 可以查看自己配置邮箱和name
git config --global --get user.name
git config --get user.name
git config --global --get user.email
git config --get user.email
# 重置
git config --global --unset user.name
# 重新赋值
git config --global user.name dujc
配置git的时候会使用git config,那么git config、git config –global、git config –system之前有何区别呢?
- 执行 git config -e 后,控制台打印的是当前目录下的.git/config文件
- 执行 git config -e –global 后,控制台打印的是用户家目录.git/config文件
- 执行 git config -e –system 后,控制台打印的是整个电脑系统的.git/config文件
如果同时配置了这三种文件,那优先级就是:git config > git config –global > git config –system,也就是优先以项目录里的配置为准。因此想要设置什么级别的,只需添加对应的标识即可(global,system)
与仓库联系,一般我们都是通过秘钥方式,也就是本地生成一对秘钥(一般用用邮箱即可),然后公钥放在远程(比如github),本地存放私钥。秘钥生成完以后,因为我们一台电脑既要连gitlab又要连gihub,因此生成的秘钥不能重名,另外就是需要一个配置文件,将两份秘钥分别指向不同的远程地址;
密钥生成
每个SSH用户都有自己的known_hosts
文件,此外系统也有一个这样的文件,通常是/etc/ssh/ssh_known_hosts
,保存一些对所有用户都可信赖的远程主机的公钥。id_rsa.pub
是本机的公钥,id_rsa
是本机的私钥。
# ~/.ssh 目录是一些密钥信息
# 若不添加任何信息可以直接执行下面命令,然后一路回车,
# 此时会生成id_rsa,id_rsa_pub,只需要将后者拷贝到远程对应服务器即可
ssh-keygen
# 但是若想一台电脑建立多个ssh连接,则需要为每个秘钥生成不同的名字
ssh-keygen -t rsa -C "your_mail@example.com" -f ~/.ssh/my_example_rsa
# -t 后面跟秘钥的类型,这里是rsa
# -C 是密钥的注释,一般在生成的秘钥最后面
# -f 因为默认都会生成同样的秘钥名字,这里相当于重命名
# 此时会在~/.ssh目录生成my_example_rsa和my_example_rsa.pub两个文件
# 只需将my_example_rsa.pub拷贝到远程
# 还需要在~/.ssh目录增加(若没有)config文件,然后里面配置如下信息
#------------
# missfresh-gitlab(这是区分不同的用户名,自定义即可)
Host gitlab.missfresh.net
HostName gitlab.missfresh.net
PreferredAuthentications publickey
IdentityFile ~/.ssh/missfresh-gitlab-rsa
# 配置文件参数
# Host : 别名,随便取
# HostName : 如果要登录的主机名为git@gitlab.missfresh.net:xxx.git,则Host为:gitlab.missfresh.net
# User : 登录名,最好用账户邮箱
# PreferredAuthentications: 优先使用哪个方式验证,支持秘钥(publickey)和密码(password)方式
# IdentityFile : 指明对应用户的私钥文件地址(私钥的权限600)
#------------
# 配置完可以测试一下:
# @前面的协议一般都为git,后面的地址就是上面HostName
ssh -T git@gitlab.missfresh.net
# 若输出类似一下信息,则代表成功:
Hi xxx! You have successfully authenticated, but GitHub does not provide shell access.
# 可以打印详细信息,尤其连接有问题时
ssh -T -v git@gitlab.missfresh.net
使用密码登录,每次都需要输入密码,非常麻烦,好在ssh
提供公钥登录,可以省去输入密码的步骤。所谓公钥登录,原理就是用户将自己的公钥存储在远程主机上,登录时,远程主机会向用户发送一段随机字符串,用户用自己的私钥加密后再发给远程主机,远程主机用事先存储用户的公钥解密,如果成功,则客户的是可信的,直接允许登录shell
,不再要求密码。
git 查看终端帮助文档
# 比如查看git commit相关,可以如下
$ git help commit
.gitignore 规则不生效的解决办法
原因是.gitignore 只能忽略那些原来没有被 track 的文件,如果某些文件已经被纳入了版本管理中,则修改.gitignore 是无效的。那么解决方法就是先把本地缓存删除(改变成未 track 状态),然后再提交:
注意: git rm
是删除暂存区和分支上的文件,同时本地也不需要了,使用。而git rm --cached
只是删除暂存区和分支上的,本地还需要,只是不被版本控制了。其实若想用git
管理文件,则使用git rm
相关,若新建一个文件,并没有提交到暂存区,此时用git rm或git rm --cache
是找不到这个文件的,此时应该直接用rm
git rm -r --cached 文件名
git add .
git commit -m 'update .gitignore'
匹配规则:
- 所有空行或#开头的行都会被忽略;
- 文件或目录前加 / 表示仓库根目录的对应文件;
- 匹配模式最后跟反斜杠 / 说明要忽略的是目录;
- 要特殊不忽略某个文件或目录,可以在模式前加上取反 ! 。
# 忽略目录 fd1 下的全部内容,不管是根目录的还是子目录的,但不屏蔽fd1目录本身
fd1/*
# 屏蔽fd1目录
fd1/
# 只忽略根目录fd1下的所有
/fd1/*
# 所有以 '.a' 为后缀的文件都屏蔽掉
*.a
# 仓库中所有名为 tags 的文件都屏蔽
tags
# 仓库中所有以 'core.' 开头的文件都屏蔽
core.*
# mac系统创造的隐藏文件
.DS_Store
# idea编辑器用来存放配置信息的文件
.idea
# 忽略根目录,子目录中所有node_modules及子其目录
node_modules
# 忽略根目录,子目录中所有dist及子其目录
dist
# 忽略根目录public及其子目录
/public
git 常用操作
# 丢弃暂存区修改,注意这里是已经被跟踪的文件
$ git checkout -- .
# 丢弃暂存某个文件修改
$ git checkout -- xxx
# 丢弃未追踪(untracked)的文件(也就是工作区),后可跟具体文件,不跟则全部删除
$ git clean -f
# 连untracked的目录(工作区)也一块删掉
$ git clean -fd
# 若untracked的目录有子目录,可以如下全部删除
$ git clean -fd -f
# 删除某个分支(强制删除:-D)
$ git branch -d xxx
# 删除远程分支
$ git push origin -delete xxx
# 修改分支名(未推到远程)
$ git branch -m oldName newName
# 修改分支名(推到远程)
$ git branch -m oldName newName # 1. 修改本地
$ git push origin --delete oldName # 2. 删除远程
$ git push origin newName # 3. 推到远程
$ git branch --set-upstream-to=origin/newName # 4. 本地与远程相关联
# 保存当前修改,再拉取远程更新或切换到远程
$ git stash
# 想再恢复之前的保存,用如下命令
$ git stash pop
# 重命名本地分支名
$ git branch -m old-name new-name
# 查看带详细分支图的提交日志
$ git log --graph
# 修改已经提交的commit,会让你修改上次的提交内容
git commit --amend
禁用 package-lock.json
# 当前项目里禁用
echo 'package-lock=false' >> .npmrc
echo 'package-lock.json' >> .gitignore
# 当前机器当前用户,所有项目禁用
npm config set package-lock false
命令行初始化一个仓库
echo "# test" >> README.md
git init
git add README.md
git commit -m "first commit"
git remote add origin git@xxx/xxx.git
git push -u origin master
添加一个已有的仓库
# 只是初始化一个仓库的后两个步骤
git remote add origin git@xxx/xxx.git
git push -u origin master
git 远程主机常用操作
# 查看远程主机名(-v 查看远程主机的详细地址)
$ git remote
// origin
# 查看远程主机详细信息
$ git remote show <主机名>
# 添加远程主机
$ git remote add <主机名> <仓库地址>
# 删除远程主机
$ git remote rm <主机名>
# 重命名远程主机名
$ git remote rename <原主机名> <新主机名>
# 修改远程仓库地址,url地址有https与ssh两种
$ git remote set-url origin [url]
# 远程分支已删除,本地还没删除,可以通过以下命令同步一下
$ git remote prune origin
git fetch
# 获取指定远程主机上所有分支的更新
$ git fetch <远程主机名>
# 获取指定远程主机,指定分支上的更新
$ git fetch <远程主机名> <分支名>
# 获取的远程更新,需用 远程主机名/分支名 读取,切换到获取的更新master分支
$ git checkout origin/master
# 在获取的远程更新分支基础上新建分支
$ git checkout -b newBranch origin/master
# 将获取的远程master更新分支合并到当前分支
$ git merge origin/master
或者
$ git rebase origin/master
git pull
# 获取远程next分支的更新,然后合并到本地master分支
# 若合并到本地当前分支,则省略冒号后面的部分
$ git pull origin next:master
# 上面操作等同于下面操作
$ git fetch origin
$ git merge origin/next
# 在clone仓库时,git会自动在本地与远程同名分支之间,建立一种追踪关系(tracking)
# 当然也可以手动建立追踪关系,如下本地master与远程next分支
# $ git branch --set-upstream master origin/next // 这个命令废弃了
git branch --set-upstream-to=origin/myBranch myBranch
# 如果当前分支与 远程追踪分支 存在追踪关系,可以省略远程追踪分支名
# 当前分支还可以同时追踪多个远程分支??
$ git pull origin
# 如果当前分支只有一个追踪分支,主机名都可以省略
$ git pull
# 远程删除了某些分支,如果本地也想删除这些分支,可以如下:
$ git pull -p
git push
# 将本地master分支的更新推送到远程主机next分支上
$ git push origin master:next
# 省略远程分支名,则表示将本地分支推送到与之存在追踪关系的远程分支。推送本地分支到远程分支
# 如果远程分支不存在,则会新建
$ git push origin master
# 如果省略本地分支,则表示删除指定的远程分支
# 因为这等同于推送一个空的本地分支到远程
$ git push origin :master
# 等同于
$ git push origin --delete master
# 如果当前分支与 远程追踪分支 存在追踪关系,则可以省略本地及远程分支
$ git push origin
# 如果当前分支只有一个追踪分支,主机名都可以省略
$ git push
# 如果当前分支与多个主机存在追踪关系,则可以使用-u指定一个默认主机
# 如下将本地master分支推送到origin主机,同时指定origin为默认主机
$ git push -u origin master
# 如果远程主机版本比本地版本新,推送时会报错,应该先pull再push
# 如果强推则会覆盖远程,如下
$ git push --force origin
git rebase
参考:failed to push some refs to
# 多人开发一个分支时,远程更新后,本地commit后直接push后会出错,此时若先pull后push,则提交记录会分叉
# 为了让提交记录在一条直线上同时解决问题,可以如下,然后push即可
$ git pull --rebase origin master
代码回滚
# 代码已经提送至远程,可以用 git revert,
# 注意另外一个好处就是:不是重写之前的提交记录,而是增加记录,而且是撤销指定的提交。
# 表示回滚到上一次提交(其实就是撤销最近一次的提交)
git revert HEAD
# 指定回滚到哪一次,如果想撤销不连续的提交,可以空格分开
git revert HEAD~3
# 若是想直接回滚到某个点,可以直接
# 之前的提交记录会被移除,慎用
git reset --hard 提交鸡柳
bash 常用操作
# 查看gcam中每个参数的意义
$ git help commit
// -a, --all
// Tell the command to automatically stage files that have been modified and deleted, but new files you have not told Git about are not affected.
# 用于查找并显示给定命令的绝对路径(),但mac下如下显示
$ which gcam
// gcam: aliased to git commit -a -m
# 对比一下alias
$ alias gcam
// gcam='git commit -a -m'
oh my zsh 常用操作
参考:oh-my-zsh
# 查看所有别名,当然除了oh-my-zsh的命令别名,还有系统级别的,比如ls
$ alias
# 管道符查看含gcam的别名
$ alias | grep gcam
// gcam='git commit -a -m'
# 自定义别名命令,只是自定义,与命令是否真实存在无关
# 比如查看alias ls => ls='ls -G',所以自定义别名方式如下:
$ alias 别名=命令
# 取消别名
$ unalias 别名
问题总结
** git push 时提示 Username for ‘https://github.com’:**
本地已经配了 ssh 登录,但推代码时提示这个,表示现在是 https 的方式,两种方式修改:
# 命令行修改
git remote set-url origin git@github.com:yuccie/jsArt.git
# 直接修改 .git/config文件
url = git@github.com:yuccie/jsArt.git