前言:最近又重温了下廖雪峰老师的Git教程,实在是通俗易懂、醍醐灌顶,想记录一下这个Git教程的关键点,便于以后查看。

Git的主要作用是版本管理和分支管理,对个人开发者来说,可能版本管理会比较重要,分支管理在协作开发中会比较有作用。

Git初始化

初始化一个Git仓库,首先得下载Git Git - Downloads
然后进入一个目录,最好是非英文
执行命令

1
git init

创建完仓库之后,会有隐藏的.git目录,这里面就存放git的版本信息等。

Git管理是文本文件,对于二进制文件,只能知道其创建还是删除了,对于修改的操作是不知道的,像图片、视频、docx文档等都是二进制文件。

Git的版本管理

先看Git版本库模型:

img.png
我们在Git管理的目录中对文件进行修改(增删改)之后,可以执行以下git命令
以readme.txt为例:

1
2
git add readme.txt
git commit -m "XXX"

add添加到暂存区,commit提交到本地仓库。

可以多次add,一次commit,这样暂存区中的所有修改都会提交到本地仓库中去。

Git的回退操作

可以分为两种:

版本回退

第一种是回退版本,即已经提交了之后想要回退到之前的提交状态或者叫之前的版本。这里需要知道一个概念,当前的版本一般用 HEAD 来表示,HEAD相当于一个指针,指向当前的提交状态。

我们可以先查看提交历史,然后使用 git reset 根据版本号回退到之前的版本;如果回退之后后悔了想要恢复到新版本,可以先 git reflog,然后再 git reset;

如下:

1
2
3
4
5
git log 查看提交历史
git reset --hard 1094a 根据提交ID回退 git reset --hard HEAD^ 这个表示上一个版本,上上个就是HEAD^^ 前一百个就是HEAD~100

git reflog 查看命令历史 会出现当前命令执行时的版本号(提交ID)
git reset --hard 1094a 根据提交ID回退
修改回退

Git管理的是修改而不是文件,所以如果你对一个文件改了又改回去,那么git status之后是没有变化的;

当然修改也可以回退,这里可以用 git checkout – file命令,其实也可以用 git restore命令,以后可以直接用 git status,然后看提示命令就行。

git checkout – file :

一种是 readme.txt 自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;

一种是 readme.txt 已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。

总之,就是让这个文件回到最近一次 git commit 或 git add 时的状态。

而 git reset 也可以将提交到暂存的修改撤销回工作区。

所以:

1
2
3
4
5
6
7
8
1.如果是工作区修改
git status
git checkout -- readme.txt 其实是用版本库中的文件替换工作区文件

2.如果是暂存区修改回退,然后再撤销修改
git status
git reset HEAD readme.txt
git checkout -- readme.txt

Git远程仓库

一般我们用Github、Gitee 或者自己的服务器做远程仓库,Git的理念是分布式协作,是没有远程仓库的,我们加上远程仓库的概念是为了让协作更方便。开发的时候仍然可以不需要像SVN一样必须联网才能写代码。

如果用Github的话需要先连接公钥私钥,这里只做Git命令的分享。

1.以Github为例,我们可以先在本地创建仓库,后在Github上创建仓库,然后将两者连接,再将本地的内容push到远程仓库去。

2.第二种是先创建Github仓库,然后clone到本地再进行代码开发;

第一种:

1
2
3
4
5
6
git remote add origin git@server-name:path/repo-name.git
git push -u origin master
由于远程库是空的,我们第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的
master分支关联起来,在以后的推送或者拉取时就可以简化命令。
git remote -v 查看远程库信息
git remote rm origin 删除远程库连接 origin只是个名字,可以在创建连接时自定义。

第二种:

1
git clone git@github.com:michaelliao/gitskills.git

分支管理

分支是比较重要的内容,这张图可以比较好的理解分支,HEAD是当前的分支,其实是指向当前分支的最新提交结点。
img_1.png

Git鼓励大量使用分支:

查看分支:git branch

创建分支:git branch

切换分支:git checkout 或者git switch

创建+切换分支:git checkout -b 或者git switch -c

合并某分支到当前分支:git merge

删除分支:git branch -d

我一般喜欢用git switch

解决冲突

对于相同文件的像同行,如果每个分支有不同的代码,会出现冲突,这个时候Git不能快速处理,需要手动解决冲突。

img_2.png

可以先用以下命令合并分支

1
git merge feature1

然后去vscode或其他编辑上解决冲突,可以全accept incoming ,也可以全部reject。

解决完冲突之后再次提交,就是下面这样的:

img3.png

可以用以下命令查看git提交图:

1
git log --graph --pretty=oneline --abbrev-commit

Fast Forward

在没有冲突时,Git会用FF的模式,这样子的提交记录就会很平滑,只有一条直线,看不出来这里是合并过的。所以我们可以用 –no-ff 禁止ff,如下:

1
git merge --no-ff -m "merge with no-ff" dev

那么,提交记录就会变成这样:

img4.png

在实际开发中,我们应该按照几个基本原则进行分支管理:

首先,master分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活;

那在哪干活呢?干活都在dev分支上,也就是说,dev分支是不稳定的,到某个时候,比如1.0版本发布时,再把dev分支合并到master上,在master分支发布1.0版本;

你和你的小伙伴们每个人都在dev分支上干活,每个人都有自己的分支,时不时地往dev分支上合并就可以了。

所以,团队合作的分支看起来就像这样:

img5.png

多人协作模式

一般会有master分支、dev分支、bug分支、feature分支等。

  1. 首先,可以尝试用git push origin 推送自己的修改;
  2. 如果推送失败,则因为远程分支比你的本地更新,需要先用git pull试图合并;
  3. 如果合并有冲突,则解决冲突,并在本地提交;
  4. 没有冲突或者解决掉冲突后,再用git push origin 推送就能成功!
    如果git pull提示no tracking information,则说明本地分支和远程分支的链接关系没有创建,用命令git branch –set-upstream-to origin/
    这就是多人协作的工作模式,一旦熟悉了,就非常简单。

git pull 是 git fetch + git merge:

img6.png

变基

  • rebase操作可以把本地未push的分叉提交历史整理成直线;

  • rebase的目的是使得我们在查看历史提交的变化时更容易,因为分叉的提交需要三方对比。

自建服务器

公司用的自己的服务器做远程仓库,可以使用以下命令创建裸仓库,裸仓库不会有工作目录,但是会有修改信息:

1
git init --bare sample.git

然后再将自己的电脑和这个远程仓库连接就行。