0,Git 是什么
Git 是一个VCS
(Version Control System
),即版本控制系统
。
版本控制系统
从字面意思来看,它的用途就是管理/控制
文件的版本
。使用它,可以方便的知道一个文件
在什么时间
被谁
修改了哪些内容
。这样,如果文件被改动后出了什么问题,就可以快速的定位问题,从而解决问题。
版本控制系统
中可以保存任何的文件,比如文档,代码等。
版本控制系统
主要有如下优点:
- 方便
多人协作
。 - 方便
管理/控制/查看
历史版本信息。
常见的版本控制系统有 Git,SVN等,Git 比 SVN 更强大,更流行。
Git 诞生于2005年,由Linux 开源社区(主要是Linus Torvalds)开发而成,他们对Git 的设计理念是:
速度
更快设计简单
- 完全
分布式
- 对
非线性开发模式
的强力支持,允许成千上万个并行开发的分支
- 可以高效管理类似
Linux 内核
这样的超大项目
今天我们就来介绍Git。
1,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
命令来输出简短的状态
,s
是short
的意思。
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
该命令的意思是将本地仓库推送到远端origin
的master 分支
。
注意,要想将本地仓库推送到远端,必须对远端仓库有可写权限。
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
该命令的含义是,拉取远端origin
的master 分支
,然后合并到当前分支
。
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> 分支 合并到当前分支 |
(完。)