前言
之前总结过git的一些基本命令,后来使用了更多git,写博客用于记录。不断更新 ,在实践中总结git知识点。
回顾下之前的git基本操作
- 将现有的项目添加提交并上传到远程仓库
1 | git add . #添加当前文件夹下的所有文件 |
- clone代码
1 | git clone https://github.com/raymond-zhao/cat-mall.git ../Github/cat-mall |
git status 和 git diff
在对文件进行修改之后,可以用 git status 查看结果,可以让我们时刻掌握仓库当前的状态

可以看到在modified部分,可以看到有四个文件被修改了,但是还没有进行提交(commit)修改
而下半部分的untracked files表示的是之前从未提交到仓库分支的文件(一个markd文件,一个照片)
上述只是看到被修改的文件,但如果能看看具体修改了什么内容就好了,git diff 可以实现这个功能

可以看到修改的详细细节(红色为修改前的内容,绿色为修改后的内容)。向下箭头可以下拉文本,q退出查看 (quit)
这样就可以放心的添加(add)到仓库的暂存区,并提交(commit)到仓库分支
1 | git add . |
小结
- 要随时掌握工作区的状态,使用
git status命令。 - 如果
git status告诉你有文件被修改过,用git diff可以查看修改内容。
版本回退
每当文件修改到一定程度的时候,就可以“保存一个快照”,这个快照在Git中被称为commit。一旦你把文件改乱了,或者误删了文件,还可以从最近的一个commit恢复,然后继续工作,而不是把几个月的工作成果全部丢失。
在Git中,我们用git log命令查看:

git log命令显示从最近到最远的提交日志,每一次commit很详细
可以加上--pretty=oneline参数,来简化显示。推荐使用

其中前面编号类似012214236e...的是commit id(版本号),是一个SHA1计算出来的一个非常大的数字,用十六进制表示
每个人的编号不一样,因为Git是分布式的版本控制系统,多人在同一个版本库里工作,如果大家都用1,2,3……作为版本号,那肯定就冲突了。
回退到历史版本
这样我们就可以进行回退操作
首先,Git必须知道当前版本是哪个版本。
在Git中,用HEAD表示当前版本,也就是最新的提交012214236e...,上一个版本就是HEAD^,上上一个版本就是HEAD^^,当然往上100个版本写100个^比较容易数不过来,所以写成HEAD~100。
我们可以使用git reset命令:
1 | git reset --hard HEAD^ #回退到上一版本 |

结果显示出现在是ca41b0a,也就是上一次commit的版本。我们成功回退版本!
当我们再查看日志的时候,发现已经没有20/8/31/commit1版本了

还原到最新版本
如果想要再还原到20/8/31/commit1版本呢?
也是可以的,只要上面的命令行窗口还没有被关掉,就可以顺着往上找,找到那个20/8/31/commit1版本的commit id是012214236e...,于是就可以指定回到未来的某个版本:
1 | git reset --hard 0221423 |

版本号没必要写全,前几位就可以了,Git会自动去找。当然也不能只写前一两位,因为Git可能会找到多个版本号,就无法确定是哪一个了。
这样就实现了还原到最后commit版本
Git的版本回退速度非常快,因为Git在内部有个指向当前版本的HEAD指针,当你回退版本的时候,Git仅仅是把HEAD从指向历史版本,再将工作区的文件更新即可
如果回退到了某个版本,关掉了命令行窗口,后悔想恢复到新版本但是找不到新版本的commit id怎么办?
在Git中,总是有后悔药可以吃的。Git提供了一个命令git reflog用来记录你的每一次命令:

知道commit_id,还原版本就十分滴完美!
注!!!
如果从历史版本回到最后的版本,也只能还原到最后
commit后的版本。我才开始
commit了版本A,之后又写了一部分内容 B(未commit)。还原到了A-1版本,之后又想还原到A+B版本,操作完之后发现还原后的没有B部分,也就是我只能还原到A。原因就是我在最后一次
commit就是A,而写完B之后,没有commit,于是无法还原。 (多多commit,,还原需谨慎。我是真的折腾)😭
小结
HEAD指向的版本就是当前版本,因此,Git允许我们在版本的历史之间穿梭,使用命令git reset --hard commit_id。 (commit_id也写成HEAD^)- 穿梭前,用
git log可以查看提交历史,以便确定要回退到哪个版本。 - 要重返未来,用
git reflog查看命令历史,以便确定要回到未来的哪个版本。
参考
工作区和暂存区
工作区(Working Directory)
就是在电脑里能看到的目录,比如我的mynlog文件夹就是一个工作区:

版本库(Repository)
也就是本地仓库
工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。(选择隐藏文件可见就可以看到)
Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD。


前面讲了我们把文件往Git版本库里添加的时候,是分两步执行的:
第一步是用git add把文件添加进去,实际上就是把文件修改添加到暂存区(index);
第二步是用git commit提交更改,实际上就是把暂存区的所有内容提交到当前分支(master)。
因为我们创建Git版本库时,Git自动为我们创建了唯一一个master分支,所以,现在,git commit就是往master分支上提交更改。
你可以简单理解为,需要提交的文件修改通通放到暂存区,然后,一次性提交暂存区的所有修改。 也就是可以多次git add . ,之后再一次性git commit
我对文件进行修改之后,git status 显示如下:

这是对文件进行了修改,但是未添加(add)到暂存区和提交(commit)到仓库分支。 并且出现了之前从未提交的文件(四张png图片)
然后git add .,再查看目前的状态 git status

出现了绿色的new file字样和modified,代表已添加到缓存区。
现在,暂存区的状态就变成这样了(原文是添加的readme和LICENSE文件):

所以,git add命令实际上就是把要提交的所有修改放到暂存区(index),然后,执行git commit就可以一次性把暂存区的所有修改提交到分支。

这时候再 git status,则是干净的
现在版本库变成了这样,暂存区就没有任何内容了:

小结
了解工作区和暂存区的概念,并通过例子加强git status 、git add、git commit的理解
如果不用git add到暂存区,那就不会加入到commit中。也就是说commit只会提交暂存区里的内容
撤销修改
在工作区撤销修改
在工作区写的内容想要撤销,当然可以手动删除。同时还有另外的一种方法
git status 查看一下状态

根据git提示,可以知道如下信息:
changes not staged for commit:表示没有更改添加到暂存区,也就是对于当前的修改还没有进行add操作

可以看到修改的部分是
2020-08-31-git 进阶.md文件,不能显示中文,所以用编码表示同时
next文件也做了修改。这个每次都有提示,猜想应该是因为next是我clone下来的文件,所以存在.git文件,将.git文件删除就ok了提示显示,
git checkout -- file可以丢弃工作区(work directory)的修改
git checkout -- file
1 | git checkout -- source/_posts/2020-08-31-git进阶.md (注意--不要遗漏,同时后面有一个空格) |
命令git checkout -- filename意思就是,把filename文件在工作区的修改全部撤销,这里有两种情况:
- 一种是文件自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;
- 一种是文件已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。
总之,就是让这个文件回到最近一次git commit或git add时的状态。
git checkout其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”。
注
- 文件必须写当前git bash 下的完整路径,可以参考
git status下的modified部分路径名称,如上的source/_posts/ - 文件名必须写中文(就是正常的文件名),不能按照modified部分的编码后的名称

这是错误过程,可以看到最后一次没有提示,表示成功撤销修改
打开git进阶文件可以看到内容已经撤销
添加到暂存区后的撤销
如果在工作区已经修改,并且添加到暂存区了,在commit之前,发现了这个问题。用git status查看一下,修改只是添加到了暂存区,还没有提交:


- 在添加到暂存区后,可以看到在
changes to be committed部分,添加的部分已经变成绿色,等待被commit提交 - 根据git提示,用命令
git reset HEAD <file>可以把暂存区的修改撤销掉(unstage),重新放回工作区:
1 | git reset HEAD . |
git reset命令既可以回退版本,也可以把暂存区的修改回退到工作区。当我们用HEAD时,表示最新的版本。
撤销到工作区的内容可以根据上述内容撤销其修改
提交到版本库后的撤销
前提是还没有把自己的本地版本库推送到远程。
可以利用上述的版本回退功能
小结
- 场景1:当你改乱了
工作区某个文件的内容,想直接丢弃工作区的修改时,用命令git checkout -- file。 - 场景2:当你不但改乱了工作区某个文件的内容,还
添加到了暂存区时,想丢弃修改,分两步,第一步用命令git reset HEAD <file>,就回到了场景1,第二步按场景1操作,用命令git checkout -- file。 - 场景3:已经提交了不合适的修改到版本库时,想要撤销本次提交,参考
版本回退,不过前提是没有推送到远程库。
远程仓库
已经在本地创建了一个Git仓库后,又想在GitHub创建一个Git仓库,并且让这两个仓库进行远程同步,这样,GitHub上的仓库既可以作为备份,又可以让其他人通过该仓库来协作。
首先,登陆GitHub,然后,在右上角找到“Create a new repo”按钮,创建一个新的仓库
在Repository name填入shijian,其他保持默认设置,点击“Create repository”按钮,就成功地创建了一个新的Git仓库。出现以下界面:

复制仓库的SSH链接
根据提示,可以返回到需要上传的文件夹目录下,右键选择git bash
1 | git init #创建.git隐藏文件,用于本地仓库 |
添加后,远程库的名字就是origin,这是Git默认的叫法,也可以改成别的,但是origin这个名字一看就知道是远程库。
接下来就是git的基本三样操作,添加提交并推送
1 | git add . #添加当前文件夹下的所有文件 |
把本地库的内容推送到远程,用git push命令,实际上是把当前分支master推送到远程。这时候在github界面就可以看到推送的文件
第一次push的时候可以添加参数
-u,之后可以不添加由于远程库是空的,我们第一次推送
master分支时,加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令。
分支
分支暂时用不到,就没有学习