1.什么是Git?
简单的来说,Git就是一个帮我们管理文件版本的程序。专业名称:分布式版本控制系统
而这又会引入一个新的概念———
什么是“分布式”,什么是“版本控制”
1.1 什么是分布式
先举一个生活中的例子:
小饭店原来只有一个厨师,切菜洗菜备料炒菜全干。后来客人多了,厨房一个厨师忙不过来,又请了个厨师,两个厨师都能炒一样的菜,两个厨师的关系是集群。为了让厨师专心炒菜,把菜做到极致,再请了个配菜师负责切菜,备菜,备料 ... 厨师和配菜师的关系是分布式。一个配菜师也忙不过来了,又请了个配菜师,两个配菜师关系是集群。一个配菜师因故请假了,但是其余的配菜师还是该啥就干啥,只是没请假的配菜师任务均匀的加量了,但他们的任务和职责是不变的,这是集群。
—— 集群:多个人在一起作同样的事
—— 分布式 :多个人在一起作不同的事
说系统一些——
分布式是解决中心化管理的问题把一个大的问题拆分为多个小的问题,并分别解决,最终协同合作。分布式的主要工作是分解任务,将职能拆解。
说专业一些——
分布式是将一套系统拆分成不同子系统部署在不同服务器上 。
1.2 什么是版本控制
再举一个生活中的例子:
我们在写论文的时候,写完了提交给指导老师去审核,老师说你写的不好要改改,于是乎,你就去改论文。一般的做法是:不直接在原论文上修改,而是复制一份,在新复制的那一份上做改动。因为如果改了论文,被老师评价说还不如上一次,让你重改,你还可以找到未修改过的论文。
在上面的场景中,原论文是一个版本,新复制的论文又是一个新的版本。
简单点说,我们复制原论文,产生新论文的这个过程就加版本控制。
只不过这个版本控制是我们手动完成的。
1.3 什么是版本控制系统
版本控制系统就是自动的帮我们完成上述操作的系统或者说就是一个应用程序(这里的系统不是指操作系统,而是一个应用系统)。
1.4 版本控制系统如何控制版本
我们需要进行版本控制的文件都要提交到一个仓库(其实就是一个隐藏文件夹)里面,我们对文件做出的修改都会被这个版本控制系统侦测到,如果我们要保留这个版本的文件,就要通过版本控制系统提供的命令把文件提交到仓库里面,然后版本控制系统就会自动为我们提交的文件打上版本号。
什么是仓库?
本地仓库:建立在本地的文件夹。
远程仓库:建立在互联网服务器内的文件夹。
1.5 说到底,Git有什么用
对文件进行版本管理,方便在不同版本进行切换修改,类似文件分不同时间备份让后需要时找回其中一份代替,不过更方便使用。
1.6 Git的特点
- 云的概念。代码可以存在云端中,类似于网盘文件一样,我们可以在各个设备访问自己的代码。
- 社交属性。由于代码是开源的,用户可以查看其他用户的项目并且可以评论,也可以关注用户。
- 团队合作。GitHub允许多人协同完成工作,并且可以标示别人的修改和备注,最后还可以合并
1.7 Git与GitHub的联系与区别
Github相当于一个网盘(远程仓库),用户可以利用Git将文件(代码、图片等)提交到Github里进行保存,并且可以与其它用户共享代码(开源)。
2. 安装Git
-
进入Git官网,选择相应操作系统版本下载
-
根据指示安装Git.
完成安装之后,就可以使用命令行的 Git 工具(已经自带了 ssh 客户端)了,另外还有一个图形界面(GUI)的 Git 项目管理工具。
3.初次运行 Git 前的配置
一般在新的系统上,我们都需要先配置下自己的 Git 工作环境。配置工作只需一次,以后升级时还会沿用现在的配置。当然,如果需要,你随时可以用相同的命令修改已有的配置。
Git 提供了一个叫做 git config 的工具(实际是 git-config 命令,只不过可以通过 git 加一个名字来呼叫此命令。),专门用来配置或读取相应的工作环境变量。而正是由这些环境变量,决定了 Git 在各个环节的具体工作方式和行为。
3.1 用户信息
在桌面按右键出现第一个要配置的是你个人的用户名称和电子邮件地址。这两条配置很重要,每次 Git 提交时都会引用这两条信息,说明是谁提交了更新,所以会随更新内容一起被永久纳入历史记录:
并单击进入,在命令行中输入下列代码
git config --global user.name "username"
git config --global user.email "user-email"
如果用了 –global 选项,那么更改的配置文件就是位于你用户主目录下的那个,以后你所有的项目都会默认使用这里配置的用户信息。如果要在某个特定的项目中使用其他名字或者电邮,只要去掉 –global 选项重新配置即可,新的设定保存在当前项目的 .git/config 文件里。
3.2 查看配置信息
要检查已有的配置信息,可以使用 git config –list 命令
git config --list
4. 如何使用Git
4.1 创建版本库
版本库又名仓库(repository),你可以简单理解成一个目录,这个目录里面的所有文件都可以被Git管理起来,每个文件的修改、删除,Git都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”。
4.1.1 首先,选择一个合适的地方,创建一个空目录
分别输入以下代码:
mkdir [filename]
cd [filename]
pwd
4.1.2 通过 git init 命令把这个目录变成Git可以管理的仓库:
git init
此时仓库就建好了,而且告诉你这是一个空的仓库(empty Git repository)。
当前目录下新增了一个.git的目录,这个目录是Git来跟踪管理版本库的,没事千万不要手动修改这个目录里面的文件,不然改乱了,就把Git仓库给破坏了。
如果你没有看到.git目录,那是因为这个目录默认是隐藏的,用 ls -ah 命令就可以看见。
4.1.3 将文件添加到版本库中
所有的版本控制系统,其实只能跟踪文本文件的改动,图片、视频、Word这些二进制文件无法有效控制,因此建议以纯文本的形式编写。(注:因为文本是有编码的,比如中文有常用的GBK编码,日文有Shift_JIS编码,如果没有历史遗留问题,强烈建议使用标准的UTF-8编码,所有语言使用同一种编码,既没有冲突,又被所有平台所支持。)
(1)新建一个 readme.txt 文件
一定要放到learngit目录下(子目录也行),因为这是一个Git仓库,放到其他地方Git找不到这个文件。
(2)使用命令 git add 将 readme.txt 添加到仓库:
git add readme.txt
(3)使用命令 git commit 将 readme.txt 提交到仓库
git commit -m "[content]"
-m 后面输入的是本次提交的说明,可以输入任意内容,当然最好是有意义的,这样你就能从历史记录里方便地找到改动记录。
注:git add 命令和 git commit 命令都支持一次性添加或提交多个文件
4.2 修改文件(以 readme.txt 为例)
4.2.1 在新建的readme.txt文件中增加内容,并修改其内容
4.2.2 利用 git status 命令查看当前仓库的修改状态
git status
由上图可以看出,readme.txt 文件被修改过(modified: readme.txt),但没有准备提交(commit)的修改
4.2.3 利用 git diff 命令查看具体修改的是什么内容
git diff [filename]
由于提交的时候提交的是空白文档,故显示为增加(+)了“Time is a poison. you are the cure."(注:“-”代表被修改前的,“+”代表被修改后的)
4.2.4 利用 git log 命令查看历史修改记录
git log
其中,上面第3行的commit c24a792...中的c24a792...表示的这次提交的commit id,HEAD -> master表示test3这次提交的是当前的版本,上次的版本就是HEAD^,上上次就是HEAD^^,如果版本太久远,就会用类似HEAD~100这种形式来表示。
4.2.5 知道了修改内容,认为没有问题就可以将它提交到仓库里面了,也是同样的步骤git add, git commit命令。
一般情况下修改一个文档并提交到Github上需在命令行中分别输入四行命令:
- git status
- git add [filename]
- git commit -m "[content]"
- git push
4.3 版本回退
4.3.1 利用 git reset 命令切换版本
git reset --hard HEAD^ //回退到上个版本
回退到之前的版本后,之前的版本则不会在 git log 中显示,不过不用担心回不去。
git reset --hard [commit id] //切换到指定版本,commit id只需输入该id前几位即可
参数 | 作用 |
---|---|
--mixed | 重置HEAD指针和暂存区,工作区保持不变。 |
--soft | 后面只能接指针,仅仅重置版本(比如将当前版本HEAD改为HEAD^,但是暂存区和工作区的内容还是HEAD的)。 |
--hard | 后面只能接指针,重置版本、暂存区和工作区内容(比如将当前版本HEAD改为HEAD^,暂存区和工作区的内容都变成HEAD^的)。 |
4.3.2 利用 git reflog 命令查看历史命令
忘记commit id也无妨,可利用此命令查看每个版本的commit id
git reflog
其中,从 b7244e9 HEAD@{3}: commit: test2 这一句中,我们可以看出来,test2的版本的commit id是b7244e9。找到了commit id,再次使用 git reset 命令,就能回退到指定的版本了
4.4 工作区与暂存区
4.4.1 什么是工作区
就是在电脑里能看到的目录,例如learngit文件夹就是一个工作区
4.4.2 什么是版本库
工作区有一个隐藏目录 .git,这个不算工作区,而是Git的版本库。
Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD。
我们在工作区修改的内容,通过 git add 命令,会将修改的内容存储到stage区域,也就是暂存区,然后再经过 git commit 命令,才会将我们的修改内容合入到master分支上
可以简单理解为,需要提交的文件修改通通放到暂存区,然后,一次性提交暂存区的所有修改。
4.5 管理文件
4.5.1 管理修改
当我们修改了一次文件后,输入 git add 命令将文件添加进暂存区后,再一次修改该文件,输入 git commit 命令将该文件提交到版本库中。
而在版本库中储存的文件是第一次修改过后的文件,而第二次修改的文件因未添加进暂存区中,而没有被提交到版本库中。
所以 git commit 命令只是将暂存区的文件提交到版本库中。
4.5.2 撤销修改
- 当我们修改了一次文件之后,发现需要撤销刚才所写的内容。(尚未添加至暂存区)
在命令行中输入
git checkout -- [filename]
可将未添加至暂存区内的内容撤销掉
命令 git checkout -- readme.txt 意思就是,把readme.txt文件在工作区的修改全部撤销,这里有两种情况:
一种是readme.txt自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;
一种是readme.txt已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。
总之,就是让这个文件回到最近一次 git commit 或 git add 时的状态。
- 当我们修改了一次文件之后,发现需要撤销刚才所写的内容。(已添加至暂存区)
可以在命令行中输入
git reset HEAD [filename]
将暂存区的内容撤销到工作区(也就是将本次 git add 的内容撤销到工作区)
然后,我们再使用 git checkout 命令,将本次修改移除掉
4.5.3 删除文件
我们先在learngit目录下新建一个test.txt文本文件,并提交到本地版本库中。
当我们在本地将此文件删除后
- 如果是确实要删除,则使用命令删除此文件
git rm [filename]
然后在删除后进行 git commit 操作更新本地仓库就行。
git rm 用于删除一个文件。如果一个文件已经被提交到版本库,那么你永远不用担心误删,但是要小心,你只能恢复文件到最新版本,你会丢失最近一次提交后你修改的内容。
- 如果是误删,那么也没关系,我们的本地仓库中还有这个文件,我们只需要从仓库中取出就行了
git checkout -- [filename]
此时,原先被删除的文件又回来了
git checkout 其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”。
4.5.4 版本回退和撤销修改场景总结
假如readme.txt原内容为A,修改后为A+B:
- 没有执行 git add 操作,工作区想要恢复为A,则执行:
git checkout -- readme.txt
执行前,工作区内容为A+B,暂存区内容为A,版本库内容为A。
执行后,工作区内容变为A,暂存区内容为A,版本库内容为A。
- 执行了 git add 操作,想要撤回本次 git add 操作(工作区恢复为A+B,暂存区恢复为A)则执行:
git reset readme.txt
此命令等同于命令:
git reset --mixed readme.txt
--mixed表示重置HEAD指针和暂存区,但是工作区内容保持不变。
执行前,工作区内容为A+B,暂存区内容为A+B,版本库内容为A。
执行后,工作区内容为A+B,暂存区内容为A,版本库内容为A。
- 执行了 git add 操作,想要撤回本次 git add 操作(工作区恢复为A,暂存区恢复为A),则执行:
git reset readme.txt
git checkout -- readme.txt
或者执行如下命令:
$ git reset --hard head
执行前,工作区内容为A+B,暂存区内容为A+B,版本库内容为A。
执行后,工作区内容为A,暂存区内容为A,版本库内容为A。
- 执行了 git add 操作和 git commit 操作,想要撤回本次操作(工作区恢复为A+B,暂存区恢复为A+B,版本库恢复为A),则执行:
$ git reset --soft HEAD^
--soft表示仅仅重置HEAD指针,不重置工作区和暂存区的内容。
执行前,工作区内容为A+B,暂存区内容为A+B,版本库内容为A+B。
执行后,工作区内容为A+B,暂存区内容为A+B,版本库内容为A。
- 执行了 git add 操作和 git commit 操作,想要撤回本次操作(工作区恢复为A,暂存区恢复为A,版本库恢复为A),则执行:
git reset --hard HEAD^
--hard表示重置HEAD指针、暂存区、工作区内容。
执行前,工作区内容为A+B,暂存区内容为A+B,版本库内容为A+B。
执行后,工作区内容为A,暂存区内容为A,版本库内容为A。