在这里插入图片描述

0,Git 是什么

Git 是一个VCSVersion Control System),即版本控制系统

版本控制系统从字面意思来看,它的用途就是管理/控制文件的版本。使用它,可以方便的知道一个文件什么时间修改了哪些内容。这样,如果文件被改动后出了什么问题,就可以快速的定位问题,从而解决问题。

版本控制系统中可以保存任何的文件,比如文档,代码等。

版本控制系统主要有如下优点:

  1. 方便多人协作
  2. 方便管理/控制/查看历史版本信息。

常见的版本控制系统有 Git,SVN等,Git 比 SVN 更强大,更流行。

Git 诞生于2005年,由Linux 开源社区(主要是Linus Torvalds)开发而成,他们对Git 的设计理念是:

  • 速度更快
  • 设计简单
  • 完全分布式
  • 非线性开发模式的强力支持,允许成千上万个并行开发的分支
  • 可以高效管理类似Linux 内核这样的超大项目

今天我们就来介绍Git。

1,Git 五种状态

Git 五种状态

如上图所示,Git 的工作状态可分为五种,清楚的了解了这五种状态,有助于我们对Git 的整体理解:

  • 状态 0【本地目录】:

    其实在这个状态时,还没有Git,这时只是本地系统的普通文件/目录

  • 状态 1【Git 工作区】:只有在工作区的内容,才属于Git 的控制范围,才会被Git 管理。

    通过git init 可以将本地系统中的普通目录纳入Git 工作区

    通过git checkout 可以将Git 本地仓库中的内容拉到Git 工作区

    通过git clone/fetch 可以将Git 远程仓库中的内容拷贝到Git 工作区

  • 状态 2【Git 暂存区】:暂存文件的改动情况。

    通过git add 可以将Git 工作区中的普通文件加入Git 暂存区

  • 状态 3【Git 本地仓库】:只供本地当前用户可访问,只有本地仓库中的内容,才可以提交到远程仓库。

    通过git commit 可以将Git 暂存区中的内容提交Git 本地仓库

  • 状态 4【Git 远程仓库】:可供多用户访问,方便协同合作。

    通过git push 可以将Git 本地仓库中的内容推送Git 远程仓库

2,Git 安装

你可以使用你系统(Windows/Mac/Linux) 中对应的包管理器来安装Git 工具。比如在Ubuntu 系统中可以使用如下命令来安装:

sudo apt install git-all

3,Git 帮助手册

Git 共支持100 多个命令,可用man git 查看其详细手册。

使用git help -a 命令可列出Git 支持的所有命令command,使用git help <command> 可查看每个命令的详细手册,例如git help init

使用git help -g 可列出其它手册:

>>> git help -g
________________________________________________________________
The common Git guides are:

   attributes   Defining attributes per path
   everyday     Everyday Git With 20 Commands Or So
   glossary     A Git glossary
   ignore       Specifies intentionally untracked files to ignore
   modules      Defining submodule properties
   revisions    Specifying revisions and ranges for Git
   tutorial     A tutorial introduction to Git (for version 1.5.1 or newer)
   workflows    An overview of recommended workflows with Git

使用git help 手册 可查看某个对应的手册,例如git help tutorial

4,Git 配置

可以使用Git 配置文件来定制自己的Git 环境。

4.1,Git 配置文件

Git 有三种级别的配置文件,你可以通过直接修改配置文件的方式来修改Git 配置,也可以使用git config 命令来修改Git 配置。

Git 的三个级别的配置文件如下:

  • /etc/gitconfig 文件:整个系统中的所有用户都适用。可使用git config --system 来修改该文件。
  • ~/.gitconfig~/.config/git/config文件:当前用户的配置文件,只适用于当前用户。可使用git config --global 来修改该文件。
  • .git/config:当前项目的配置文件,只适用于当前项目。可使用git config --local 来修改该文件。

这三个级别的大小关系为:当前项目级别>当前用户级别>系统配置级别。

可以用如下命令查看配置:

git config --list

可以用如下命令查看配置及其所在的配置文件:

git config --list --show-origin

4.2,配置用户名和邮件

一般在下载完Git 工具后,需要在当前用户级别设置Git 的账户信息:用户名邮件地址

设置方法如下:

git config --global user.name "example_name"
git config --global user.email "example@email.com"

下面配置可得到彩色的git 输出

git config --global color.ui true

下面介绍Git 的基本使用。

5,获取一个Git 仓库

使用Git 有两种方式,一种是使用GUI 模式,一种是使用命令行模式

一般推荐使用命令行模式,因为GUI 模式一般不会实现所有的Git 功能,而使用命令行,则可以使用所有的Git 功能。

有两种方式可以获取一个Git 仓库:

  • 第一种:初始化(init)一个未被版本控制的本地目录。
  • 第二种:从远程克隆(clone)一个现成的Git 仓库。

5.1,初始化本地目录

首先,进入到我们想要进行版本控制的目录,如下已处在项目目录:

>>> pwd
~/hello_git

使用git init 初始化当前目录:

>>> git init
Initialized empty Git repository in ~/hello_git/.git/

也可以直接使用git init <dir>,来初始化一个新的Git 项目(然后再进入该目录):

git init hello_git

可看到当前hello_git 目录多了一个.git 子目录:

>>> ls -a
.  ..  .git

这是Git 工具使用的一些必要文件,目前我们无需过多关注。

到目前为止hello_git 目录,已经算是一个Git 工作区

5.2,克隆远程仓库

可使用git clone <url> 命令从远程克隆一个现有的仓库,当然必须有这个项目的可读权限,才能克隆该项目。如下:

>>> git clone https://github.com/codeshellme/codeshellme.github.io.git

以上命令会在当前目录下创建一个codeshellme.github.io.git 子目录,该目录就是一个Git 工作区,该项目的所有内容在这个目录中。

我们也可以在克隆一个项目时,为这个子目录起一个新名字,如下:

>>> git clone <url> <new_dir_name>

6,查看当前状态

当得到一个Git 仓库后,我们可以使用git add 将一个本地文件纳入Git 控制。

在使用git add 之前,我们可以先使用git status 来查看当前目录的状态,比如我们已经在当前目录下创建了一个新的文件README

>>> ls
______
README

使用git status 可以看到README 文件处于未跟踪Untracked状态:

>>> git status
_____________________________________________
On branch master

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)

	README

nothing added to commit but untracked files present (use "git add" to track)

并且可以看到On branch master 这行信息,这说明我们当前的Git 分支master分支。

如果觉得git status 输出的内容较多,可以使用git status -s 命令来输出简短的状态sshort 的意思。

7,跟踪新文件

我们使用如下命令将这个文件纳入Git 控制:

>>> git add README

此时再使用git status,可以看到README 文件已经被纳入跟踪,处于可提交状态

>>> git status
______________________________________________
On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

	new file:   README

git add 支持通配符*,如下:

git add *      `将当前目录中的所有内容加入跟踪`
git add *.c    `将当前目录下的所有以".c" 为后缀的文件加入跟踪`
git add hello* `将当前目录下的所有以"hello" 为前缀的文件纳入跟踪`

另外git add .git add * ,都可将当前目录中的所有内容加入跟踪。

8,提交到本地仓库

提交到本地仓库使用git commit 命令:

>>> git commit README -m "add README file"
________________________________________________
[master (root-commit) 01c07e9] add README file
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 README

git commit 命令后边紧跟要提交的文件-m 参数后边可加一些本次提交的日志信息(比如本次对文件的改动情况),方便自己和他人查看。

也可以使用git commit .git commit * 来提交所有的文件。

9,查看文件的提交日志

使用git log 可查看文件的提交日志:

git log				`查看当前目录的所有提交情况`
git log <filename>  `只查看一个文件的提交情况`

10,修改文件

如果我们修改了某个文件,如下,向README 文件中加入新的内容:

echo "hello" > README

此时使用git status,可见README 文件处于已修改modified 状态:

>>> git status
_______________________________________
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   README

no changes added to commit (use "git add" and/or "git commit -a")

11,查看文件修改内容

此时可使用git diff 命令查看我们对文件进行了哪些修改:

git diff              `查看当前目录所有的改动情况`
git diff <filename>   `只查看一个文件的改动情况`

12,撤销修改

如果发现本次修改的问题较大,可以使用如下命令,来放弃本次修改的所有内容:

git checkout -- <file>

git checkout 后边是两个横杠--,再后边是文件名,执行该命令后,<file> 的内容将恢复到未修改之前(注意:已提交的内容,是无法使用该命令来撤销修改的)。

如果本次修改没有问题,可使用git commit 来提交本次的修改。

13,删除文件

使用git rm 可以将某个文件从Git 中删除,Git 将不再跟踪该文件,例如:

git rm README

执行该命令后,README 文件即会从Git 项目中删除,也会从本地磁盘删除。

如果你只想从Git 中将其删除,而不从磁盘删除,可使用--cached 参数:

git rm --cached README

如果在删除文件之前,你已经改动过这个文件,可以使用-f 强制删除:

git rm README -f

14,修改文件名

可以使用git mv 来修改Git 中的文件名,如下,我们将README 改为readme

git mv README readme

此时再使用git status,可见README 已被重命名为readme

>>> git status
_____________________________________________
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	renamed:    README -> readme

也可以使用git status -s输出简短内容:

>>> git status -s
___________________
R  README -> readme

15,关联到远程仓库

只有将本地仓库的内容推送到远端仓库,才有助于多人合作。

如果你的Git 工作区 是由git clone 克隆而来,则它会自动关联到远端。

如果你的Git 工作区 是由git init 初始化而来,则需要手动关联到远端。要想关联到远端仓库,则必须首先有一个远端仓库。

比如,我们已经在GitHub 上创建了一个远程仓库,地址为https://github.com/codeshellme/hello_git.git

~/hello_git 目录下,使用git remote add将本地仓库关联到远端,如下:

git remote add origin https://github.com/codeshellme/hello_git.git

其中,origin 相当于https://github.com/codeshellme/hello_git.git 的别名,origin 就代表了https://github.com/codeshellme/hello_git.git

使用git remote -v可查看关联信息:

>>> git remote -v
_________________________________________
origin	https://github.com/codeshellme/hello_git.git (fetch)
origin	https://github.com/codeshellme/hello_git.git (push)

15.1,移除远程仓库

可使用如下命令,移除本地与远程的关联:

git remote rm <remote>

例如:

git remote rm origin 

该命令将使得本地仓库远端仓库origin 断开关联关系。

16,推送到远端

如果一个本地仓库已经关联到了远端仓库,则可以使用git push,将本地仓库内容推送到远端,如下:

git push origin master

该命令的意思是将本地仓库推送到远端originmaster 分支

注意,要想将本地仓库推送到远端,必须对远端仓库有可写权限。

17,获取远端信息

可以使用git fetch <remote> 来获取远端的所有信息,如下:

git fetch origin

该命令的含义是将远端origin所有分支获取到本地仓库。

18,查看分支

当从远端获取所有分支后,我们可能需要查看分支信息。

使用如下命令可查看所有本地分支

git branch

使用如下命令可查看所有远程分支

git branch -r

使用如下命令可以查看所有本地分支远程分支

git branch -a

19,合并分支

git fetch 将远端内容获取到本地之后,并没有进行合并,此时我们需要使用git merge 来合并分支,如下:

git merge <branch_name>

该命令的含义是将branch_name 分支合并到当前分支

20,拉取且合并

git pull <remote> <branch> 命令可以简单的认为是git fetch <remote> + git merge <branch>。如下:

git pull origin master

该命令的含义是,拉取远端originmaster 分支,然后合并到当前分支

21,创建分支

分支版本控制系统中的重要概念,尤其是在大型项目中,会经常用到分支。

使用分支有助于我们在开发新功能的时候,避免对当前可用的版本造成不必要影响。当我们的项目有了一个可用的版本,这时我们要开发新的功能。这种情况下,一般会在这个可用的主分支上切出一个新的开发分支,专门用于开发新功能,当新功能开发完毕,则需要将这个开发分支再合并回原来的主分支。

就像下图所表达的意思一样:

在这里插入图片描述

使用git branch <branch_name>,可以创建新的分支。

使用git branch -b <branch_name>,创建分支,并切换到该分支。

22,切换分支

使用git checkout <branch_name>命令,可从当前分支切换到<branch_name> 分支。

使用git checkout - 可切换到上一个分支。

git branch -b 的作用相当于git branch + git checkout

23,命令别名

我们可以用git config给Git 常用命令指定其简写形式,以方便书写。常用别名如下:

git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.st status

执行以上配置后,git co 就相当于git checkout,其它类似。

24,文件忽略

我们可以配置Git,使其忽略掉一些我们不关心的文件,比如一些中间文件和日志文件。

我们可以在一个项目(比如hello_git)目录下创建.gitignore 文件,该文件中是一些规则,其告诉Git 应该忽略哪些文件。

下面是一个例子:

# 忽略所有的 .a 文件
*.a

# 但跟踪所有的 lib.a,即便你在前面忽略了 .a 文件
!lib.a

# 只忽略当前目录下的 TODO 文件,而不忽略 subdir/TODO
/TODO

# 忽略任何目录下名为 build 的文件夹
build/

# 忽略 doc/notes.txt,但不忽略 doc/server/arch.txt
doc/*.txt

# 忽略 doc/ 目录及其所有子目录下的 .pdf 文件
doc/**/*.pdf

这里https://github.com/github/gitignore 还有很多适用于各种语言的配置。

25,命令总结

下面总结一下我们介绍到的Git 命令。

帮助手册

命令 含义
man git 查看Git 详细手册
git help -a 查看Git 支持的所有命令
git help -g 查看Git 支持的其它手册
git help <命令/手册> 查看某个命令/手册的内容

配置文件

命令 含义
git config --system 修改Git 系统级配置
git config --global 修改Git 当前用户级配置
git config --local 修改Git 当前项目级配置
git config --list 查看Git 所有配置
git config --list --show-origin 查看Git 所有配置及其所在文件

基本操作

命令 含义
git init 初始化当前目录为Git 工作区
git init <dir> 新建dir目录,并将其初始化Git 工作区
git clone <url> 从远程克隆一个Git 项目
git clone <url> <dir> 从远程克隆一个Git 项目,并将内容放在dir 目录中
git status 查看变化状态
git status -s 查看简短变化状态
git add 添加跟踪文件
git commit 提交改动内容
git log 查看改动日志
git diff 查看改动内容
git checkout -- <file> 撤销改动
git rm <file> 将文件移除Git 跟踪,并删除本地文件
git rm --cached <file> 将文件移除Git 跟踪,不删除本地文件
git rm <file> -f 强制将文件移除Git 跟踪,并删除本地文件
git mv 重命名文件

远程仓库

命令 含义
git remote add 将本地仓库与远程仓库相关联
git remote -v 查看仓库关联信息
git remote rm <remote> 将本地仓库与远程仓库断开关联
git push <remote> <branch> 将本地仓库内容推送到远程
git pull <remote> <branch> 将远程仓库分支拉取到本地并合并分支
git fetch <remote> 将远程仓库内容全部拉取到本地,不进行合并

分支操作

命令 含义
git branch 查看所有本地分支
git branch -r 查看所有远程分支
git branch -a 查看所有本地分支远程分支
git branch <branch_name> 创建分支 <branch_name>
git branch -b <branch_name> 创建切换到分支 <branch_name>
git checkout <branch_name> 切换到<branch_name> 分支
git checkout - 切换到上一个分支
git merge <branch> <branch> 分支合并到当前分支

(完。)