最近发生了奇怪的事情,mysql总是会连不上,查了半天原因,最后发现进程文件没有生成。es报警“Too many open files”。搜索才发现是,打开文件太多了,超过了限制。解决方法是修改/etc/security/limits.conf
。另外还牵扯到了另一个配置file-max
。经过调试还是踩了不少坑的。坐下笔记,防止重复踩坑。
limits.conf配置说明
ssh提速
最近ssh链接超慢,但是ping发现网速还是很快的。记录一下解决方法
修改/etc/ssh/sshd_config
两个参数
1 | UseDNS no |
保存后重启ssh服务
1 | systemctl restart sshd |
9.上传到远程仓库
小白的故事
本故事纯属虚构,如有雷同,^0^那可太巧了
这几天以来,小白学会了很多git的使用技巧。让他在应对问题的时候可以比较从容。比如需求反复修改。处理一些临时功能,后期要删除等比较繁琐的事情。
今天是小白负责的第一个项目发布的日子。
BOSS让小白把代码提交到远程仓库,这样负责发布的小伙伴就可以将代码进行发布了。
小白询问了老鸟如何将代码上传到github。回来开始操作。
- 创建线上仓库
进入github.com登录自己的账号,点击右上角的加号,选择new repository
填写仓库名称然后点击绿色的cteate repository
按钮
创建成功会有如下提示
这时候说明已经创建成功了。这里会显示项目的远程地址,同时介绍了两种使用情况
- 没有项目时可以先创建一个目录,进行
git init
初始化,然后用git remote add
进行关联 - 如果已经有了本地项目直接使用
git remote add
进行关联
小白一看我属于第二种情况。果断进入项目目录执行
1 | $ git remote add origin https://github.com/shooke/learngit.git |
提示让Username for 'https://github.com':
让输入git账号,小白果断输入,然后回车
再次提示Password for 'https://xiaobai@163.com@github.com':
这里让输入密码
“奇怪怎么没有显示*
啊”小白疑惑,这时候正好老鸟走过来
“BOSS让你上传代码,搞定了吗”,老鸟说
“就差一步了,为啥没法输入密码啊”小白问
“傻子,git命令行工具跟windows的cmd不一样的,这里是不会有星号提示的,但其实你的密码已经输入了,不行你可以试试”老鸟回答
小白重新输入密码,回车。出现了以下提示
1 | Counting objects: 26, done. |
“出现[new branch] master -> master
是不是就表示上传成功了”小白问
“对啊,这个提示代表你本地的master分支,上传到了远程的master分支”老鸟回答
“啥事分支啊” 小白好奇的问
“分支啊,这可是好东西,多人协作全靠它了,我还有事明天给你讲” 老鸟回去忙自己的事了
小结
git remote add [shortname] [url]
可以让本地仓库和远程仓库建立联系。shortname
是仓库名称,方便执行命令时使用,一般情况下都用origin
;url
就是远程仓库的地址,比如上面例子中的https://github.com/shooke/learngit.git
git remote -v
显示所有远程仓库git remote show [remote]
显示某个远程仓库的信息
8.再遇工作区和版本库
小白的故事
本故事纯属虚构,如有雷同,^0^那可太巧了
”大神我看你用使用git reset
时使用了--hard
参数,是不是还有其他参数啊。“小白虚心问道
”小伙很细心啊,不错,还有其余的2个参数,我挨个给你讲吧。刚才用过–hard,咱们从他讲起。咱们先创建个文件,加两条commit,方便讲解“老鸟说到
1 | $ echo "1"> test.txt |
“咱们创建了2条commit记录了,第一条记录test.txt
里的内容是1
,第二条记录test.txt
里的内容是2
。先看一下记录” 老鸟说
1 | $ git log |
“接下来,咱们撤销一下看看效果”老鸟继续教导小白
1 | $ git reset --hard HEAD^ |
”现在历史被撤回了,咱们看git的状态“ 老鸟说
1 | $ git status |
”你看工作区和暂存区都是空的对吧“老鸟说
”恩恩,文件内容应该变成1了“小白说
1 | $ cat test.txt |
“回答正确,咱们先把历史还原,然后再来试试另一个参数”老鸟说。
1 | $ git reset --hard a609df431578e5061b5d0261bfa38cb0fa01efb1 |
“接下来试试--mixed
,看看会是什么效果”老鸟说
1 | $ git reset --mixed HEAD^ |
“历史回退了”小白说
“恩,咱们看看文件状态有什么变化”老鸟说
1 | $ git status |
“这是什么意思啊,这个提示不是文件发生修改的时候才有的吗”,小白疑惑
“看一下文件内容你就明白了”老鸟说到
1 | $ cat test.txt |
”知道什么愿意你了吗“老鸟说
”哦,我明白了,历史回退了,按说文件的内容应该是1,但是现在内容是2,所以git以为文件发生了修改“小白说道。
”恭喜你答对了,--mixed
参数会清空stage缓存区,但是不会直接修改文件的内容,如果需要将文件内容撤回,可以在执行git checkout <file>
“老鸟解释道
1 | $ git checkout test.txt |
”你看内容变了吧,接下来你猜一下--soft
参数会是什么效果“老鸟说
”既然--hard
文件工作区和缓存去都清空了,--mixed
把缓存区清空了,那--soft
是不是会保留缓存区啊“小白说道
”不错嘛,这都分析到了,没错,--soft
参数只是撤销了记录,缓存区和工作区都不做修改,咱们来看下效果“。老鸟说,”先恢复一下记录方便看效果“
1 | $ git reset --hard a609df431578e5061b5d0261bfa38cb0fa01efb1 |
”历史回来了,咱们开始看下--soft
的作用“老鸟敲下命令
1 | $ git reset --soft HEAD^ |
”你看,是不是和你想的一样啊,要想清理缓存区可以按提示执行git reset HEAD <file>
,剩下的就不用我说了吧“老鸟说道
”恩恩,明白,文件线下的内容应该还是2吧,我清理完缓存区,然后git checkout <file>
文件内容就会变回commit对应的内容,对吧“小白问道
”没错,那你知道为什么会有这三种不同的参数吗“老鸟问
”不明白,--hard
很方便啊,其他两种还要做其他操作才能回复文件内容,多麻烦。“小白回答
”你现在只是一个文件,如果你的一个历史记录有很多文件怎么办,如果你只需要撤回其中一个文件呢,用--hard
不是自杀吗。使用--mixed
或--soft
可以保证文件内容不撤销,这样你就可以用git checkout
针对你需要撤销的文件进行撤回。多方便 “老鸟说道
”哦,明白了,谢谢大神“小白激动的说
”走了,有问题随时问我“,老鸟再次潇洒离去,留下了激动的小白
小结
--hard
撤销commit记录,清空tage暂存区,清空工作区内容,文件内容彻底还原--mixed
撤销commit记录,清空tage暂存区,保留工作区内容,执行git checkout <file>
可撤销修改,让文件内容还原--soft
撤销commit记录,保留stage暂存区,保留工作区内容,如果要撤回需要先执行git reset HEAD <file>
撤销暂存区,然后执行git checkout <file>
撤销修改
7.时光倒流
小白的故事
本故事纯属虚构,如有雷同,^0^那可太巧了
小白正在开心的写代码,刚刚完成了产品小伙伴的一个需求。还是小有成就感的,正准备起来活动活动喝杯水。谁知产品小伙伴有风风火火的跑过来。
“小白,小白,客户还是感觉以前的交互方式用着顺手。让把功能改回去”。产品小伙伴喊道。
听到这个消息,小白满脸的黑线。废了半天劲做出来的功能再改回去。这太坑了吧。
但是没办法,谁叫客户就是上帝呢,改吧。
开始撤销,ctrl z
。。。
what,没法撤销了?编辑器撤销的步骤有限,这可如何是好啊,难道要手动改代码?这也太悲剧了吧。
“对了找大神问一下,看git有没有办法回退”小白灵光一闪想起来老鸟。
老鸟一听到小白喊他“大神”,瞬间心情舒畅跑过来知道小白。
“你是要回退以前的版本吗?”老鸟问道。
“恩恩”小白点头
“回退其实很简单,看我操作,要记住啊”说完,做到小白的坐位上开始了他的神操作。
“首先用git log
看一下你的提交记录”,老鸟说道
1 | $ git log |
“咦,你这里git log居然乱码啊”,老鸟说道
“这是咋回事啊”,小白疑惑
“好办,编码问题解决一下就可以了”。老鸟输入了如下三条命令
1 | git config --global i18n.commitencoding utf-8 |
再次执行git log
果然好了
1 | git log |
“log记录有时候很多,你可以不停的按j
和k
来实现向下或向上查看内容,不行看了,就输入:q
退出。就跟vim编辑器使用方式一样”老鸟说。
“想要退回到那里,用git reset
会退到对应的commit id就可以了。比如会退到审核状态修改
。老鸟边说变执行命令
1 | git reset --hard 3e14b6822063c |
打开编辑器,小白发现,代码真的回到以前了。
“大神,commit id怎么输入了一部分啊,不需要全部输入吗”,小白激动说道
“不需要,只要git能够确定唯一的commit就行了,一般也就输入前几位”,老鸟说。
“每次都要看commit id好麻烦啊,有没有简单的方法?”小白谦虚问道
“当然有啊,可以用HEAD加上^
或者~n
回退啊”。老鸟说
1 | git reset --hard HEAD^ |
“这样就会回退一条commit,如果退两条,就再加一个^,退几条就加几个^”老鸟说
”那退20条,岂不是20个^,多麻烦啊“,小白说
”孺子可教啊,这要用~n了,可以这样写“,老鸟说
1 | git reset --hard HEAD~20 |
“明白了,谢谢大神”小白说道。
”你刚才要回退到那条commit啊“老鸟问道
”啊,我只需要退一条就行了,咱们刚才退了这么多,怎么办啊“小白说
”这怕啥,你只要知道历史中的commit id,就不用担心,及时你回退了50条,要回到第二条也没问题“老鸟边说变敲下哦了命令
1 | git reset --hard 3e14b6822063c7add663cd79756e77818e821819 |
”你看这不是回到你第二条命令时的状态了吗,只要你记得回退前的commit id,随时可以穿梭到任何commit“老鸟说道。
小白豁然开朗,原来历史是可以任意切换的,并不是回退了就抹除了。
小结
- 解决乱码
git config --global i18n.commitencoding utf-8
该命令表示提交命令的时候使用utf-8编码集提交
git config --global i18n.logoutputencoding utf-8
该命令表示日志输出时使用utf-8编码集显示
export LESSCHARSET=utf-8
设置LESS字符集为utf-8,为了让配置一直有效,可以把这个设置添加到~/.bashrc
,然后执行source ~/.bashrc
查看历史
git log
可以查看历史。但是如果用git reset
回退了,是看不到被退回的历史的,如果要保证历史,可以使用git revert
,后面会讲这个命令git log --stat
显示commit历史,以及每次commit发生变更的文件git log -S [keyword]
搜索提交历史,根据关键词git log [tag] HEAD --pretty=format:%s
显示某个commit之后的所有变动,每个commit占据一行git log [tag] HEAD --grep feature
显示某个commit之后的所有变动,其”提交说明”必须符合搜索条件git log --follow [file]
或git whatchanged [file]
显示某个文件的版本历史,包括文件改名git log -p [file]
显示指定文件相关的每一次diffgit log -5 --pretty --oneline
显示过去5次提交历史切换
git reset HEAD^
可以向前撤销一次,多个^
可以撤销多条历史,或者使用git reset HEAD~5
这样可以一次撤销5条历史git reset
可以任意切换到某个历史,使用git reset --hard commitid
即可,commit id不一定要全的,可以只写前几位
6.撤销操作
小白的故事
本故事纯属虚构,如有雷同,^0^那可太巧了
”大神!你是再叫我吗“,老鸟回过头问小白。
“是啊大神,虽然git diff很牛,可以让我知道改过什么,但我一点点的改回去好麻烦啊,有没有别的办法?”
大神,老鸟暗喜。这个大神的称号还是很少用的。老鸟摆出一副高深莫测的表情。
“办法当然有,既然你问了,就告诉你吧”
老鸟回到小白的工位入座。拿过键盘,开始实战时光回退大法,输入 git checkout package.json
。施展至于本着经验精神不忘问一句,“你确定这些修改不要了?”
“恩恩,前面的思路有问题,我想到了一个更好的办法,所以还原吧。”小白虚心的说道。
只见老鸟手起指落,敲击在回车上。
再次查看文件,package.json文件真的恢复了。小白满眼崇拜的目光看向老鸟。
看到小白的表情,老鸟还是非常受用的。
“既然你这么好学,老夫就再教你一招,包你从此不会写错代码。”老鸟说道
“恩恩,大神请将”小白谦虚道。
“这个git呢要活学活用,你已经知道git分为工作区,暂存区和仓库了吧?”老鸟说道
“恩恩”小白道
“git diff的功能你也了解了吧”,老鸟继续说
“恩恩”小白点头道
“其实工作区,暂存区和仓库的概念是贯彻始终的,git checkout 也适用”,老鸟继续说
“大神的意思是说,如果我对package.json进行了 git add操作,checkout的时候就会回到add时候的代码,如果没有add过,就会回到上一次commit时候的代码?”。小白问道
“恩,不错悟性很好啊,记住一点,开发一个功能要常add,完成后在用commit收尾。这样在开发过程中出错,可以及时撤销,也可以减少不必要的commit历史”。老鸟提醒小白。
“恩恩,谢谢大神”,小白真诚的向老鸟道谢
一口一个大神,叫的老鸟飘飘然。老鸟也是非常的开心。临走不忘说一句“遇到问题尽管找我”
小结
git checkout --filename
可以撤销文件的变更。
- 如果文件
git add
过,会撤回到add时的代码,即暂存区代码。 - 如果没有
git add
过,会撤回到上次commit时的代码,也就是版本库中,最近的版本。
关于工作区和版本库的介绍,可以看上一篇《4.工作区和版本库》
如果一个功能比较复杂,可以完成一小部分执行一次add,或者是commit,这样在后续开发中发现改错了东西,可以及时撤回。
5.对比文件变化
小白的故事
本故事纯属虚构,如有雷同,^0^那可太巧了
了解了工作去和版本库的区别,小白开始自己开动脑筋举一反三。既然git status
可以查看哪些文件发生的变化。那能不能知道具体的变化是什么呢。
毕竟作为一个程序猿,临时被唐僧召唤的事情经常发生。小白正在思考着,产品经理就喊上了。有个新需求需要确认排期。小白只好怪怪的跑过去。
确认完排期,回到座位上,继续开发今天的功能。add
commit
已经熟练的飞起。貌似git也很简单嘛。
中午到了,开饭。吃过午饭回到坐位的小白发现电脑关机了。据说是某个不知名的家伙不小心提到了插座。
好吧,重新开机就好了,打开自己熟悉的ide,一切如常。上午的功能还没有commit,看下改过哪些文件吧。git status
发现改了十几个文件。
好多都已经记不清改的什么了,肿木办?先把自己记忆清除的几个add。然后commit。剩下几个实在想不起来改过什么了。ide也没法回退了,这该如何是好啊。
正在小白苦恼的时候,老鸟过来了。
看着发呆的小白,老鸟关系的问“小猴子,今天怎么发呆了?”。
小白如实回答“有几个文件忘记改过什么地方了,电脑关过机,ide也没法撤销操作了”。
老鸟熟练的敲下了git diff package.json
,这时候所有的改动一目了然的展现在了小白面前。
1 | $ git diff package.json |
还不待老鸟解释,小白已经明白减号-
代表的是自己删除的行+
是产生的新行。
这下好了,可以看出自己修改过的细节,就可以很清楚的解决问题了。
看着小白激动的目光,老鸟挥一挥衣袖,不带走一点代码。飘然而去。
望着老鸟离去的背影,小白激动的追上去,语出惊人“大神,留步!”
小结
git diff --filename
可以比较文件的变更情况。
- 如果文件
git add
过,会显示工作区和暂存区的差别。 - 如果没有
git add
过,会显示工作区和仓库历史版本的差异。
git diff --cached [file]
显示暂存区和上一个commit的差异
git diff HEAD
显示工作区与当前分支最新commit之间的差异
git diff --shortstat "@{0 day ago}"
显示今天你写了多少行代码
关于工作区和版本库的介绍,可以看上一篇《4.工作区和版本库》
4.啥事工作区、暂存区和版本库
小白的故事
本故事纯属虚构,如有雷同,^0^那可太巧了
回到家的小白,想着今天发生的事,为什么git status
出来的提示信息不一样?为什么git status
出来的提示信息不一样?为什么git status
出来的提示信息不一样?
想着想着他就睡着了,梦里他遇到了linus大神,linus带他来到了一个神秘的机构。在这个房间里有2个人,还有一个大大的大屏幕。
每次大屏幕上显示git add
,就会有一份文件到达一个人的手里,他会把信息进行整理。当大屏幕上显示git commit
。第一个人就会把整理的内容放到第二个人的桌子上,然后回来继续工作。
小白疑惑的看向linus大神,大神和蔼的告诉他“小白,你不是一直奇怪,为什么git status
出来的提示信息不一样?”,这就是你要的答案。
小白仔细打量着房间里的一切,第一个人的办公桌上有一个牌子,上面写着”stage”。
第二个人的办公桌上同样有一个牌子,上面写着”HEAD”。
小明若有所思,抬起头的时候,发现linus大神已经不见了。他冲出房门,发现街上根本没有大神的踪影,只有房子上高高挂起的牌匾写着”版本库”三个打字。
他大声的呼喊,这时耳边传来“叮铃铃叮铃铃”的响声。
小明从梦中醒来一看,哇,还有半小时就八点60了,飞快起身,背上背包冲向公司。
距离上班还有1秒钟的时候,小白打卡成功。
打开电脑,想起昨天遇到的情形,好像自己明白了什么,到网上一查,原来如此。
git是分为工作区和版本库的。代码发生更改后,执行
git add
代码会放到代码库的暂存区(stage),当执行git commit
时代码会形成版本记录(HEAD),并且删除暂存取的记录。
当我们执行git status
时,git会将工作区(当前的代码)与暂存区的记录进行比较,如果暂存区没有记录,则会跟做过记录的版本作比较。从而提示你哪个文件发生过修改。
明白了这些,小白开始反思昨天看到的提示。
1 | $ git status |
Untracked files
列出的是新建的文件,还没有被add和commit过,所以提示你(use "git add <file>..." to include in what will be committed)
,这表示需要进行git add
操作
1 | $ git status |
Changes not staged for commit
列出被修改的文件,这时候文件还没有被add和commit。这时就是比较工作区和HEAD得出的结果。modified: readme.md
意思是这个文件发生了更改。
了解了不同提示的原因,小白果断git add
git commit
开始开发新功能。
小结
git是分为工作区和版本库的。代码发生更改后,执行git add
代码会放到代码库的暂存区(stage),当执行git commit
时代码会形成版本记录(HEAD),并且删除暂存取的记录。工作区可以简单理解为项目目录,每次项目更改都会记录,这些变更记录就是版本库。
下面是各种状态
1 | git status |
3.查看文件状态
小白的故事
本故事纯属虚构,如有雷同,^0^那可太巧了
第二天上班,小白开开心心的打开电脑,准备爽一把。忽然想起来,昨天好像有一个功能还没有做完,临走的时候没有执行add
和commit
。
糟糕好像忘记修改过哪几个文件了。这可如何是好啊?
一盏灯泡从小白的脑袋里亮起,好像我开始使用git了,git应该知道我昨天哪些代码没有commit
吧。
小白打开百度,果然,git是可以查看文件状态的。
1 | $ git status |
modified: readme.md
,哦,原来是readme.md
文件昨天修改过。马上git add readme.md
git commit -m "readme"
添加到仓库。
ok,继续快乐的工作。
开始开发新功能,创建一个新文件
1 | touch 我最帅.txt |
不一会功能开发完成。脑袋好乱,刚才出去又忘记改了什么文件。还是用git status
吧。
1 | $ git status |
"\346\210\221\346\234\200\345\270\205.txt"
是什么鬼,我们打开万能的百度,是因为git对对0x80以上的字符进行quote,解决方法很简单
1 | git config --global core.quotepath false |
没有报错,应该没有问题吧,小白抱着试试看的态度敲下了git status
命令
1 | $ git status |
果然正常了。小白那个开心啊。内心YY道:“我就说吗git这么强大,怎么可能弱鸡到中文都不能正常显示,我果然是天才,一下就找到了原因”
马上开始保存到仓库,咦,不对,好像两次git status
出现的提示不一样,这是怎么回事啊。
时间在小白的思考中慢慢流失,抬头一看,哇,这不8点60了吗。赶紧回家…
小结
git status
可以查看项目的变更情况git config --global core.quotepath false
可以解决,git提示信息中文乱码问题
思考
为什么小白两次git status
出现的提示不一样呢?这就要从git的管理机制,工作区和代码库说起了
预知后事如何,且看下回分解。
2.把项目交给git
小白的故事
本故事纯属虚构,如有雷同,^0^那可太巧了
小白接到上级指示,所有的项目代码都要用版本管理工具进行管理。本着对项目负责的态度,小白开始在网上搜索版本管理软件。
考察了svn和git后,最后决定使用git进行项目管理。
对于刚刚不如程序猿行列的小白来说,git好神秘啊,linus大神好神秘啊。
沐浴更衣,斋戒数天。开始使用git。
使用git的第一步当然是安装了。
1 | $ sudo apt update |
ok,搞定,这样就安装完了。
打开项目目录,输入神圣的git初始化命令
1 | $ git init |
完成了?这么简单?没有报错?小白小激动了一下,git初始化就这么简单?检查一下便知道。查看了一下,项目下果然多了个.git
文件夹。
接下来我们把项目加入到git代码仓库
1 | git add . |
这样,文件就被git记录下来了。就是这么easy。
不一会小白写好了一个新功能,然后git add .
git commit -m "我有完成了一个牛X的功能"
记录下自己的工作。好开心,原来git这么简单,每次做完功能先 add
然后commit
就好了。
就这样小白开始了他的git之旅…
小结
git init
可以初始化项目git add .
可以将文件加入到暂存区,.
是当前目录的意思,可以将目录下所有文件进行暂存,如果要针对某个文件可以加上文件名如git add readme.md
git commit -m "init"
将文件加入到git代码仓库,并生成一条init
的log记录