About git

参考:阮一峰-常用 git 命令操作

参考:阮一峰-远程操作详解

参考:阮一峰-工作流

SSH

为 Secure Shell 的缩写,是一种网络协议,用于计算机之间的加密登录,如果一个用户从本地计算机,使用ssh协议登录另一台远程计算机,我们可以认为这种登录是安全的,即使被中途截获,密码也不会泄露。ssh之所以安全,因为他采用公钥加密

过程:

  1. 远程主机收到用户的登录请求,把自己的公钥发给用户,
  2. 用户使用这个公钥,将登陆密码加密后,发送给远程主机,
  3. 远程主机用自己的私钥,解密登录密码,如果密码正确,就登录成功。

但也有安全隐患,如果有人截获了登录请求(第一步),然后冒充远程主机,将伪造的公钥发送给用户,那么用户就很难辨别真伪。因为不像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

参考:廖雪峰-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
最近的文章

事件循环eventLoop

文章中难免有相互矛盾的地方,会逐渐完善,下面是关于 js 事件循环的一些内容一、js 为何单线程浏览器进程里有多个线程,比如定时器,http 请求等,但页面的渲染过程是单线程的,也就是说 ui 渲染和 j 解析是同一个线程,也就是同一时间只能执行二者其中一个。。。js 用途是与用户互动以及操作 dom,为避免复杂性,从一诞生就是单线程,否则会带来很复杂的同步问题。比如,假定 JavaScript 同时有两个线程,一个线程在某个 DOM 节点上添加内容,另一个线程删除了这个节点,这时浏览...…

继续阅读
更早的文章

那些酷的代码

复制到粘贴板,去app打开参考:js实现复制到粘贴板主要两种方法: 第三方库:clipboard.js 原生方法:document.execCommand()原生版本1:<button id="btn"></button>const btn = document.querySelector("#btn")btn.addEventListener('click',function(){ // 原生方法只支持input,textarea const input ...…

继续阅读