一、定义
Git(读音为/gɪt/)是一个开源的分布式版本控制系统,可以有效、高速地处理从很小到非常大的。
二、Git与SVN的最主要的区别?
SVN是集中式版本控制系统,版本库是集中放在中央服务器的,而干活的时候,用的都是自己的电脑,所以首先要从中央服务器哪里得到最新的版本,然后干活,干完后,需要把自己做完的活推送到中央服务器。集中式版本控制系统是必须联网才能工作,如果在局域网还可以,带宽够大,速度够快,如果在互联网下,如果网速慢的话,速度也会非常慢。
Git是分布式版本控制系统,那么它就没有中央服务器的,每个人的电脑就是一个完整的版本库,这样,工作的时候就不需要联网了,因为版本都是在自己的电脑上。既然每个人的电脑都有一个完整的版本库,那多个人如何协作呢?比如说自己在电脑上改了文件A,其他人也在电脑上改了文件A,这时,你们两之间只需把各自的修改推送给对方,就可以互相看到对方的修改了。
三、Git的下载安装
Git官网的地址:https://git-scm.com/download/
按照自己的操作系统点击进去选择对应的版本下载,按照对应系统的教程安装即可。
四、工作区和暂存区、版本库
1,工作区
就是你在电脑里能看到的目录。
2,暂存区
英文叫 stage 或 index。一般存放在 .git 目录下的 index 文件(.git/index)中,所以我们把暂存区有时也叫作索引(index)。
3,版本库
工作区有一个隐藏目录 .git,这个不算工作区,而是 Git 的版本库。
4,工作区、版本库中的暂存区和版本库之间的关系
(1)图中左侧为工作区,右侧为版本库。在版本库中标记为 “index” 的区域是暂存区(stage/index),标记为 “master” 的是 master 分支所代表的目录树。
(2)图中我们可以看出此时 “HEAD” 实际是指向 master 分支的一个"游标"。所以图示的命令中出现 HEAD 的地方可以用 master 来替换。
(3)图中的 objects 标识的区域为 Git 的对象库,实际位于 “.git/objects” 目录下,里面包含了创建的各种对象及内容。
(4)当对工作区修改(或新增)的文件执行 git add 命令时,暂存区的目录树被更新,同时工作区修改(或新增)的文件内容被写入到对象库中的一个新的对象中,而该对象的ID被记录在暂存区的文件索引中。
(5)当执行提交操作(git commit)时,暂存区的目录树写到版本库(对象库)中,master 分支会做相应的更新。即 master 指向的目录树就是提交时暂存区的目录树。
(6)当执行 git reset HEAD 命令时,暂存区的目录树会被重写,被 master 分支指向的目录树所替换,但是工作区不受影响。
(7)当执行 git rm --cached 命令时,会直接从暂存区删除文件,工作区则不做出改变。
(8)当执行 git checkout . 或者 git checkout – 命令时,会用暂存区全部或指定的文件替换工作区的文件。这个操作很危险,会清除工作区中未添加到暂存区中的改动。
(9)当执行 git checkout HEAD . 或者 git checkout HEAD 命令时,会用 HEAD 指向的 master 分支中的全部或者部分文件替换暂存区和以及工作区中的文件。这个命令也是极具危险性的,因为不但会清除工作区中未提交的改动,也会清除暂存区中未提交的改动。
五、Git的使用
1,git init 已存在目录中初始化仓库
# 创建目录
$ mkdir git_test
$ cd git_test
$ pwd
/Users/miao/git_test
# 初始化仓库
$ git init
Initialized empty Git repository in /Users/miao/git_test/.git/
这样的操作 Git 就把仓库建好了,而且是一个空的仓库(empty Git repository),同时在当前目录下多了一个.git的目录,这个目录是 Git 来跟踪管理版本库的,如果你没有看到 .git 目录,那是因为这个目录默认是隐藏的,用ls -ah命令就可以看到了。
2,git clone 克隆现有的仓库
想获得一份已经存在了的 Git 仓库的拷贝,就需要用到 git clone 命令,Git 克隆的是该 Git 仓库服务器上的几乎所有数据,而不是仅仅复制完成你的工作所需要文件。
(1)默认使用克隆仓库名称到本地
$ git clone https://gitcode.net/codechina/help-docs
运行结束后会在当前目录下创建一个名为 help-docs 的目录,并在这个目录下初始化一个 .git 文件夹, 从远程仓库拉取下所有数据放入 .git 文件夹,然后从中读取最新版本的文件的拷贝。 如果你进入到这个新建的 help-docs 文件夹,你会发现所有的项目文件已经在里面了,准备就绪等待后续的开发和使用。
(2)克隆仓库自定义本地仓库名称
$ git clone https://gitcode.net/codechina/help-docs myclone_docs
这样的运行操作会目标目录名自定义为myclone_docs。
3,编辑并添加提交文件到Git
(1)编辑添加文件
git add filename.txt
filename.txt是需要添加的文件名称
(2)提交文件
git commit -m "wrote a new file"
-m 后面输入的是本次提交的备注说明
Git在进行文件的编辑添加提交的时候,commit可以一次提交很多文件,所以你可以多次add不同的文件。
4,查看Git当前状态
命令: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.txt
no changes added to commit (use "git add" and/or "git commit -a")
含义:readme.txt被修改过了,但还没有准备提交的修改。
5,查看Git的变化比较
命令:git diff
示例:
$ git diff filename.txt
diff --git a/filename.txt b/filename.txt
index 46d49bf..9247db6 100644
--- a/filename.txt
+++ b/filename.txt
@@ -1,2 +1,2 @@
-Git is a version control system.
+Git is a distributed version control system.
Git is free software.
(END)
含义:
git diff顾名思义就是查看 difference,显示的格式正是 Unix 通用的 diff 格式,可以从上面的输出看到,当前文件的具体修改内容。
6,Git 查看日志
git log 可以查看全部的commit记录
命令:git log
如果嫌输出信息太多,看得眼花缭乱的,可以试试加上--pretty=oneline参数
git log命令显示从最近到最远的提交日志,我们可以看到2次提交,最近的一次是add distributed,最早的一次是wrote a filenamefile。
7,Git 回退
Git 必须知道当前版本是哪个版本才可以进行回退;在 Git 中,用HEAD表示当前版本,也就是最新的提交e55063a,上一个版本就是HEAD^ , 上上一个版本就是HEAD^^ , 当然往上100个版本写100个^比较容易数不过来,所以写成HEAD~100。
命令:git reset
示例:
$ git reset --hard HEAD^
HEAD is now at 50ed06b wrote a readme file
8,Git重置
命令git reflog用来记录你的每一次命令,通过git reflog找到想要重置的版本号,然后通过git reset 回退。
命令:git reflog
示例:
git reflog
50ed06b (HEAD -> master) HEAD@{0}: reset: moving to HEAD~
e55063a HEAD@{1}: reset: moving to HEAD
e55063a HEAD@{2}: commit: add distributed
50ed06b (HEAD -> master) HEAD@{3}: commit (initial): wrote a filenamefile
ESC
git reset --hard e55063a
9,撤消修改
提交完发现漏掉了几个文件没有添加,或者提交信息写错了。 此时,可以运行带有 --amend 选项的提交命令来重新提交:
命令:git commit --amend
这个命令会将暂存区中的文件提交。 如果自上次提交以来未做任何修改, 那么快照会保持不变,而你所修改的只是提交信息。
10,取消暂存的文件
取消暂存的文件,需要先用git status 提示如何撤消操作,然后根据提示信息去进行对应的操作。
命令: git reset HEAD <file>...
示例:
$ git add *
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
renamed: LICENSE -> LICENSE.md
modified: filename.txt
$ git reset HEAD filename.txt
Unstaged changes after reset:
M filename.txt
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
renamed: LICENSE -> LICENSE.md
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: filename.txt
# filename.txt 文件已经是修改未暂存的状态了。
git reset 确实是个危险的命令,如果加上了 --hard 选项则更是如此,在使用的时候需要多加注意,避免误操作。
11,撤消对文件的修改
如果不想保留对 filename.txt 文件的修改,想要撤消修改——将它还原成上次提交时的样子(或者刚克隆完的样子,或者刚把它放入工作目录时的样子)
命令:git --checkout
示例:
$ git checkout -- filename.txt
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
renamed: LICENSE -> LICENSE.md
git checkout – 是一个危险的命令。 你对那个文件在本地的任何修改都会消失——Git 会用最近提交的版本覆盖掉它。 除非你确实清楚不想要对那个文件的本地修改了,否则请不要使用这个命令。
12,删除文件
想要删除文件,可以自己手动删除之后git commit;或者使用命令git rm删掉,并且git commit。
如果是文件误删,可以通过上面的命令git --checkout撤销操作。