1. 创建版本库
版本库又名仓库,英文名repository
,可以简单理解成一个目录,这个目录里面的所有文件都可以被Git管理起来,每个文件的修改、删除,Git
都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”。
$ mkdir git_study
$ cd git_study
$ pwd
/d/Work/Git/git_study
注意:为了避免遇到各种莫名其妙的问题,请确保目录名(包括父目录)不包含中文。
$ git init
Initialized empty Git repository in D:/Work/study_git/.git/
此步骤为初始化仓库,同时生成一个.git
的隐藏目录。这个目录是Git来跟踪管理版本库的,不要乱改动。
2. 文件管理
1. 提交文件
创建一个.txt
的文件,内容可随意写。
$ git add file1.txt
$ git commit -m "write a file"
[master (root-commit) e6fddb0] write a file
1 file changed, 2 insertions(+)
create mode 100644 file01.txt
git add
是告诉git
有一个文件添加到了仓库。
git commit
是告诉git
这个文件正式提交了。-m
后面输入的是本次提交的说明,可以输入任意内容,当然最好是有意义的。
说明:
使用命令git add <file>
,可反复多次使用,添加多个文件;最后可使用命令git commit -m <message>
一次性提交。
通过以上命令,即可创建一个仓库并提交文件。
2. 查看状态
$ git status
可以看到哪些文件修改了,或者新增了等等,就是告诉你当前哪些文件处于什么状态。
3. 查看提交日志
将file01.txt重新修改多次,然后提交仓库。
我这里修改了两次。
git log
通过命令即可看到每次提交的信息。重点关注commit -m
时填写的说明,方便查看每次主要修改了那些内容。
$ git log --pretty=oneline
此命令可以简化日志的输出。从下往上看,依次显示每次的提交内容,最上面为当前的最新版本。
4. 版本回退
通过日志,可以看出每次提交都会形成一个commit_id
.
使用以下命令可以回退到之前的版本。
git reset --hard commit_id
版本回退成功。
$ git reflog
如果你又不想回退了,想恢复到回退以前,可以使用git reflog
查看之前的commit_id
是什么,继续使用版本回退的命令返回过去。
注意:
commit_id
没有必要写全,一般写前五六位即可,git
会自行判断。
3. 原理解析
1. Git区的划分
workspace:工作区
Index:暂存区
Repository:本地仓库
Remote:远程仓库
可以在工作区中,添加、删除、修改文件等等操作。add
实际是将文件保存在暂存区,commit
是将文件一次性提交给本地库。所以暂存区和本地仓库(初始化时默认会创建一个master
分支)实际都在.git
隐藏目录中。
说明:Git跟踪并管理的是修改,而非文件。如果一个文件的修改要想被提交到Repository,必须经过
add
->commit
的顺序。因为工作区的修改不会被提交,只有暂存区的修改才能被提交。
比如我们将file01.txt修改了,然后直接commit
。
# 修改完之后查看工作区和版本库里面最新版本的区别
$ git diff HEAD -- file01.txt
2. 撤销修改
分为多种情况:
场景1:如果只是工作区写坏了,想丢弃修改,可以使用以下命令.
$ git checkout -- file01.txt
注意:
git checkout -- file
命令中的--
很重要,没有--
,就变成了“切换到另一个分支”的命令。
场景2:如果工作区文件写坏了,并且add
到了暂存区,想丢弃修改,可以使用以下命令、
$ git reset HEAD file01.txt
$ git checkout -- file01.txt
用命令
git reset HEAD <file>
,就回到了场景1,然后按场景1操作。
场景3:已经提交了不合适的修改到版本库时,想要撤销本次提交,可以进行版本回退的方法操作,不过前提是没有推送到远程库。
3. 删除文件
场景1:如果你要删除的文件之前已经提交过版本库了,那么可以很轻松得找回来。
$ git checkout -- <file>
说明:不管是误删,还是修改错了,都可以使用这个命令将文件复原回来。
注意:从来没有被添加到版本库就被删除的文件,是无法恢复的!
场景2:如果你真要删除此文件,可以使用以下命令
# 告诉git要删除文件了
$ git rm test.txt
# 再次提交
$ git commit -m "remove test.txt"
现在,文件就从版本库中被删除了。
4. 分支管理
1. 基本原理
一个仓库本身只有一条分支线。一开始只有一条分支,你的所有提交都会提交到master
上,这条线会随着提交的次数增多而越来越长。
如果创建了新的分支,那么会在master的位置新创建一条分支,比如dev
,但是分支线还是只有一条。
那么你新的提交就是针对新的分支了,随着提交的增多这条线会越来越长。而master
还在原来的位置没有动。
当你将dev
和master
合并,实际上是将master指针指向当前dev的位置。
2. 创建分支
$ git checkout -b dev
# `git checkout`命令加上`-b`参数表示创建并切换,相当于以下两条命令
$ git branch dev # 创建分支
$ git checkout dev # 切换分支
对于创建分支,还有如下命令可以使用
$ git switch -c dev
# `git switch`命令加上`-c`参数表示创建并切换,相当于以下两条命令
$ git branch dev # 创建分支
$ git switch dev # 切换分支
注意:使用
git checkout
时区分前面说过的撤销修改git checkout -- <file>
.
查看当前分支
$ git branch
git branch
命令会列出所有分支,当前分支前面会标一个*
号。
现在我们就可以在dev
分支上提交了,而且不会影响到master
分支。
比如我们修改了README.md的文件。
切换到master
分支发现文件并没有被修改。
3. 合并分支
现在处在master
分支,现在我们将dev
分支合并上来。再次查看README.md文件,发现是被修改过的。
$ git merge dev
4. 删除分支
现在master
分支和dev
分支内容一致了,那么dev
分支的使命也就完成了,可以将其删除,当然你也可以继续在上面工作。
$ git branch -d dev
说明:在实际的工作中,通常会创建多条分支,防止master
被频繁修改导致出错的现象,确保过程更安全。
5. 解决冲突
冲突发生在合并分支的时候。
我们新建一个分支feature1
,修改README.md的内容并提交。
切换到master分支同样修改README.md文件内容。并提交。
最后合并feature1分支。
显示合并失败,并指出了是哪个文件。
这时需要手动修改冲突文件的内容。
<<<<<<< HEAD
表示当前所处分支的内容。=======
为分割线。>>>>>>> feature1
表示冲突分支的内容,需要将他们修改为最终需要的内容。最后重新提交。
用git log --graph
命令可以看到分支合并图。
$ git log --graph --pretty=oneline --abbrev-commit
这个时候你可以删除feature1
分支,或者继续使用。
6. 分支管理策略
git分支合并时,默认采用Fast forward
模式,这种模式下,删除分支后,会丢掉分支信息。
如果要强制禁用Fast forward
模式,git会在merge时生成一个新的commit,这样,从分支历史就能看出分支信息。
$ git merge --no-ff -m "merge with no-ff" dev
合并dev分支,使用--no-ff
,表示禁用Fast forward
模式。
因为本次合并是新的commit
,所以需要加上-m
,并把提交的说明填写上去。