Git详解一

来源:互联网 发布:中国网络自由 编辑:程序博客网 时间:2024/05/29 04:23

前言:模仿也是一种学习,经验是需要一点一点积累的,我相信就算是模仿,只要跟随自己的内心,不放弃,总有一天你也会成为那个人,加油!!!


本文摘自廖雪峰git教程,连接地址:http://www.liaoxuefeng.com/


一、Git的基本工作流程:

第一步:修改文件到指定目录(临时区域)

第二步:将文件添加到暂存区

第三步:执行commit操作,将文件通过推送从暂存区域永久性的保存到Git仓库



二、安装Git

因个人原因,一直以来都是Windows 所以这里只介绍Windows版的Git,下载地址http://msysgit.github.io/,选择默认安装即可

安装完成后,在安装的目录下找到git-bash.exe,点击会蹦出一个类似命令行窗口的东东,就表示git安装成功了!!

安装成功后,还需要进行一些配置,具体配置如下:

<span style="font-size:14px;"><span style="font-size:12px;">$ git config --global user.name "Your name"$ git config --global user.email "Your email"</span></span>

需要注意的是:用了 git config 命令的--global参数就表示这台电脑上的所有仓库都是使用这个配置,不过不用怕,git是支持对不同的仓库设置不同的用户名和email的

三、创建版本库:

首先我们要知道什么是版本库,版本库又名仓库,即Repository,我们可以将它看做是一个目录,只不过这个目录是由git进行管理的,而这个目录下的所有文件的修改,删除,git都能够追踪到,以便于我们在操作失误的情况下进行“还原”
创建版本库的操作,请看下面:
$ cd d:$ mkdir github$ cd github/$ mkdir workspaces$ cd workspaces
这里为了方便我把仓库建在了D:github/workspace目录下,cd d: 其实就是在指定要操作的路径,而mkdir "Your FileName"其实就是在指定的目录下创建一个文件夹
创建完目录后通过cd "dirName" 跳到指定目录下,通过执行:
$ pwd
该命令可以用来显示我们当前的目录:显示效果如下:
/d/github/workspaces
走到这一步其实我们就已经离成功不远了,只需要在调用一个命令就可以完成版本库的创建了,看代码:
$ git initInitialized empty Git repository in D:/github/workspaces/.git/
出现这行代码就表示我们的版本库创建成功了  :
Initialized empty Git repository in D:/github/workspaces/.git/
这时,如果你足够信息,你就会发现在你的磁盘的d:\github\workspaces\ 目录下多了一个 .git  文件夹,这个目录就是用来跟踪管理版本库的,所以这个目录下的文件没事千万不要去修改,一旦改坏,那么不好意思你的git仓库就被破坏了
如果你没有看到 .git 目录,你可以试试使用 ls -ah 命令,之所以没有显示有可能是你的,git 目录默认是隐藏的 而是用 ls -ah 命令可以查看隐藏的目录
#:其实创建目录时,也没必要一定要在空目录中创建,在有其他文件的目录中也是可以创建的,不过不是太建议这样做

四、把文件添加进仓库

首先在添加文件之前我们需要了解知道 所有的版本控制系统,其实是只能跟踪文本文件的改变的,比如TXT、HTML、所用程序的代码等,git也不例外,版本控制系统可以告诉你你每次操作的改动,以及改动的位置,但是这是基于文本的,比如:你在一个文件中的 第 5 行添加了 Hello,又或者在 第 8 行删除了 word,这些操作git都可以追踪到,但是如果你操作的是一些视频,音乐类型的二进制文件,虽然版本控制系统也能管理,但是就有点力不从心了,它能追踪的仅仅是文件的大小,比如文件从8kb变成了10kb,但到底改了哪里,版本控制系统是追踪不到的,还有就是文本是有编码的,比如中文常用的有,GBK等,不过在这里强烈建议使用UTF-8,因为这种编码是所有语言统一的编码

使用Windows的童鞋要特别注意:

千万不要使用Windows自带的记事本编辑任何文本文件。原因是Microsoft开发记事本的团队使用了一个非常弱智的行为来保存UTF-8编码的文件,他们自作聪明地在每个文件开头添加了0xefbbbf(十六进制)的字符,你会遇到很多不可思议的问题,比如,网页第一行可能会显示一个“?”,明明正确的程序一编译就报语法错误,等等,都是由记事本的弱智行为带来的。建议你下载Notepad++代替记事本,不但功能强大,而且免费!记得把Notepad++的默认编码设置为UTF-8 without BOM即可:

言归正传,现在我们开始编写一个 demo.txt 文件, 文件内容如下:

这是一个测试demo
注意:我们创建的这个文件一定要放到 我们创建的目录下,也就是 workspaces 目录下(i子目录也行),因为这是一个git仓库,只有和 .git 文件放到一起,git才能管理我们的文件

将文件放到指定位置后,还没完,就好比 大象放进冰箱,需要3步一样(打开冰箱,把大象放入冰箱,关闭冰箱),而我们仅仅完成了第一步,把文件放入到仓库,却还没有告诉 git 而下面我们要做的操作就是告诉git我们要它替我们管理的文件,看代码:

$ git add demo.txt
执行上面的代码 ,发现没有出现任何提示,那就对了,就表示我们已经操作成功

接下来就是告诉git 将我们的文件提交到仓库,前面做的所有操作都是为了这一步,只有走到这一步,那么才算是真真正正的将我们的文件放入到了git仓库中 命令:git commit -m

$ git commit -m "测试demo提交"[master (root-commit) 26a8ae4] 测试demo提交 1 file changed, 1 insertion(+) create mode 100644 demo.txt

这里要简单说一下 git commit 命令了,从字面上我们大概已经猜到这个命令是用来干嘛的了,对,他是用来提交用的,而后面跟的参数 “-m” 才是我们想要知道的, -m 后面跟的是我们要对本次提交做的说明,这个说明没有任何限制,但是最好是有意义的才行,这样当出现错误 想要回滚(还原)的时候我们找起来也方便不是么?

时间长了,可能大家会觉得先git add 在 git commit -m "" 比较麻烦 有没有简单一点的方法呢,这个当然是有的 不过不建议这样使用,先看命令:git commit -am "" 至于为什么不建议,主要是因为commit是一个 add 的集合,所以commit一次可以提交多个文件,而add可以用来添加多个文件

五、状态查询

经过上面的几步,我们已经成功的添加并提交了一个 demo.txt文件,如果这个时候我们又对demo.txt 这个文件进行了修改,修改内容如下:
这是一个测试demo在原有的基础上增加内容
这个时候如果我们想看下当前的状态,可以使用git status 命令,查看当前状态:
$ git statusOn branch masterChanges 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:   demo.txtno changes added to commit (use "git add" and/or "git commit -a")
通过打印的状态信息我们得知,demo.txt 被修改了,有一个还没有提交的修改,这时如果我们想要查看我们修改的内容怎么办?这时候我们就要使用 git diff demo.txt 来查看我们修改的内容:
$ git diff demo.txtdiff --git a/demo.txt b/demo.txtindex 6e8f9a2..9de03ca 100644--- a/demo.txt+++ b/demo.txt@@ -1 +1,2 @@-这是一个测试demo\ No newline at end of file+这是一个测试demo+在原有的基础上增加内容\ No newline at end of file
从这里我们我们可以看到我们修改的内容
知道了我们 demo.text 做了什么修改后,在把它提交到仓库就放心多了,要想提交还是需要两部,git add  和 git commit 至于是为什么 上面已经讲过,我们需要先告诉git管理系统我们修改的内容,然后在托管我们要被管理的文件
$ git add demo.txt
然后我们在调用 git  status  查看一下当前状态:
$ git statusOn branch masterChanges to be committed:  (use "git reset HEAD <file>..." to unstage)        modified:   demo.txt

这种状态就表示当前状态已进入暂存状态,这时候我们就可以放心的提交了  使用 git commit 命令交给git管理即可
$ git commit -m "▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒"[master bd78225] 在原有基础上增加内容 1 file changed, 2 insertions(+), 1 deletion(-)
提交后,我们可以在调用git status 再来查看一个当前的状态
<pre name="code" class="objc">$ git statusOn branch masternothing to commit, working directory clean


这时候会提示工作目录是干净的,提交成功!!

六、版本回退

上面我们已经熟悉了git的提交操作,像这样,你不断对文件进行修改,然后不断提交修改到版本库里,就好比玩RPG游戏时,每通过一关就会自动把游戏状态存盘,如果某一关没过去,你还可以选择读取前一关的状态。有些时候,在打Boss之前,你会手动存盘,以便万一打Boss失败了,可以从最近的地方重新开始。Git也是一样,每当你觉得文件修改到一定程度的时候,就可以“保存一个快照”,这个快照在Git中被称为commit。一旦你把文件改乱了,或者误删了文件,还可以从最近的一个commit恢复,然后继续工作,而不是把几个月的工作成果全部丢失。
在学习版本回退之前,我们先来看一个相关的命令,我们要进行版本回退,肯定要知道我们要回退的位置,但是如果我们提交了很多个命令,我们总不能凭借我们的记忆去进行回退吧,所以git中肯定提供了用于查看 我们存储我们提交操作 的命令,那就是 git log : 我们先来看一下:
$ git logcommit bd78225d2baf892319021e167ae258a3a0e77049Author: mk <mahuikaimail@163.com>Date:   Fri Nov 27 21:43:16 2015 +0800    在原有基础上增加内容commit 26a8ae4fed9e24330d82d02137f90b5d156459e6Author: mk <mahuikaimail@163.com>Date:   Fri Nov 27 11:26:08 2015 +0800    测试demo提交
使用这个命令我们就可以查看我们提交的所有操作,当然 git log 还有很多参数可以使用,我们可以通过使用 git log -h 来查看可以跟的参数
需要友情提示的是,你看到的一大串类似3628164...882e1e0的是commit id(版本号),和SVN不一样,Git的commit id不是1,2,3……递增的数字,而是一个SHA1计算出来的一个非常大的数字,用十六进制表示,而且你看到的commit id和我的肯定不一样,以你自己的为准。为什么commit id需要用这么一大串数字表示呢?因为Git是分布式的版本控制系统,后面我们还要研究多人在同一个版本库里工作,如果大家都用1,2,3……作为版本号,那肯定就冲突了。

下面我们就通过一个命令 将我们当前的操作回退到上一个版本 即 git reset -hard HEAD,首先我们想要实现版本回退 ,肯定要知道我们要回退的版本号,而 HEAD 表示的就是当前版本,而我们要回退到上一个版本,那么就要使用 git reset --hard HEAD^,上上一个版本就是HEAD^^,当然往上100个版本写100个^比较容易数不过来,所以写成HEAD~100
$ git logcommit 26a8ae4fed9e24330d82d02137f90b5d156459e6Author: mk <mahuikaimail@163.com>Date:   Fri Nov 27 11:26:08 2015 +0800    测试demo提交
这时候如果你足够细心,调用一下 git log 你就会有所发现:
$ git logcommit 26a8ae4fed9e24330d82d02137f90b5d156459e6Author: mk <mahuikaimail@163.com>Date:   Fri Nov 27 11:26:08 2015 +0800    测试demo提交
我们上次的提交的版本居然没了

--hard参数有啥意义?这个后面再讲,现在你先放心使用。

完成了版本回退后,我们停一停,去打开我们的 demo.txt 文件,你就会发现我们上一次添加的内容居然也没了...

那么,如果我们这时候不想回退版本了,想回到我们回退版本之前的那本版本,我们能回去么? 这个是必须可以的啊 不然也不会说git 强大么,那么我们应该使用那个命令呢?

我们可以使用 先使用 git reflog 这个命令,该命令记录了我们保留了我们的所有的操作命令,我们可以通过该命令来查看我们最近做的所有操作
$ git reflog26a8ae4 HEAD@{0}: reset: moving to HEAD^bd78225 HEAD@{1}: commit: 在原有基础上增加内容26a8ae4 HEAD@{2}: commit (initial): 测试demo提交
这时候我们就可以通过 我们操作的ID 也就是前面的那个 十六进制数字 然后可以通过这个 十六进制数字就可以回退到我们想要回退的任何一个版本
$ git reset --hard bd78225HEAD is now at bd78225 在原有基础上增加内容
通过 git log 查看
$ git logcommit bd78225d2baf892319021e167ae258a3a0e77049Author: mk <mahuikaimail@163.com>Date:   Fri Nov 27 21:43:16 2015 +0800    在原有基础上增加内容commit 26a8ae4fed9e24330d82d02137f90b5d156459e6Author: mk <mahuikaimail@163.com>Date:   Fri Nov 27 11:26:08 2015 +0800    测试demo提交
哈哈 我们又回来了

七、工作区和暂存区

工作区:所谓的工作区其实就是我们电脑上的目录。比如我们前面创建的 workspaces就是一个工作区

版本库:工作区中有一个 .git 目录,这个 .git 目录就是版本库

暂存区:暂存区是版本库中最重要的部分,我们在创建版本库的时候,git会默认给我们创建一个分支,以及一个指针,这个分支就是master,指针就是HEAD



关于分支和HEAD 我们后面会讲到

前面我们讲到我们要提交一个操作,需要两步操作:
第一步:使用 git add 命令,将文件添加进版本库,这一步其实就是将文件存入暂存区
第二步:使用git commit 命令提交更改,其实就是将当前暂存区中的所有内容提交到当前的 master 分支上
所以你可以简单的理解为需要提交的文件修改通通放入到暂存区,然后一次性提交到暂存区中的所有修改

文件的几种状态:未追踪,已更改未提交,已暂存状态
下面我们来分别来演示这几种状态:
首先要向呈现 未追踪 这种状态 我们需要在我们的工作空间下去新建一个文件: demo2.txt 然后调用 git status
$ git statusOn branch masterUntracked files:  (use "git add <file>..." to include in what will be committed)        demo2.txtnothing added to commit but untracked files present (use "git add" to track)
UNtracked files 翻译为 未跟踪的文件,表示这个文件还没有被 add 进git仓库

已更改,未提交状态:其实这个状态在前面我们已经出现很多次了,我们只需要对add进git仓库或已提交的文件进行更改就会进入到这种状态 例如:现在对demo.txt 进行操作
$ git statusOn branch masterChanges 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:   demo.txtUntracked files:  (use "git add <file>..." to include in what will be committed)        demo2.txtno changes added to commit (use "git add" and/or "git commit -a")

changes not staged for commit:就代表的就是这个状态

已进入暂存区:这个状态也很容易实现,我们只需要将 demo2.txt 添加到 git 仓库 ,当前状态就是 已进入暂存区状态
$ git statusOn branch masterChanges to be committed:  (use "git reset HEAD <file>..." to unstage)        new file:   demo2.txtChanges not staged for commit:  (use "git add <file>..." to update what will be committed)  (use "git checkout -- <file>..." to discard changes in working directory)
changes to be committed:这个状态就表示已进入暂存状态

下面我们将工作空间中的所有文件都重新add 一次,然后提交
$ git add .
git add , 添加当前工作空间下的所有目录到git 仓库 然后 commit

八、管理修改

所谓的修改其实就是对我们管理库中的文件进行增删改,而这里之所以提到管理修改是要展示一个小现象,至于是什么效果,来 看代码:
前面我们已经向版本库中添加了demo.txt 和 demo2.txt 两个文件,现在我们分别对demo.txt 和 demo2.txt 进行操作
首先向 demo.txt 文件中添加 “测试 管理修改“
这是一个测试demo在原有的基础上增加内容这是为了测试 以改变 未提交 状态测试 管理修改
然后 add 并使用git status 查看当前状态
$ git add demo.txt
$ git statusOn branch masterChanges 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:   demo.txtno changes added to commit (use "git add" and/or "git commit -a")
然后在修改 demo.txt 并添加 内容
这是一个测试demo在原有的基础上增加内容这是为了测试 以改变 未提交 状态测试 管理修改测试 管理修改  再次添加
最后,提交到仓库,大家可以想一想我们做了这个操作后,下面会出现什么效果呢?会不会是你心中想的那个效果呢?
来,让我们在查看一下状态
$ git statusOn branch masterChanges 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:   demo.txtno changes added to commit (use "git add" and/or "git commit -a")
咦,怎么还有一个已修改的状态???
来 让我们回想一下我们前面所做的操作, 第一次修改--》git add --》第二次修改 ---》git commit 有没有发现少了什么? 我们第二次的修改没有 add ,而commit 所做的操作是什么呢?commit所做的操作是提交 暂存区 中的所有修改,而我们的 第二次 修改并没有放入到暂存区,所以就没有提交

九、撤销修改

所谓撤销修改,顾名思义就是返回到上一个操作,这里的撤销和版本回退可不是一个概念,版本回退是回退到以前或最近的版本,是可以包含多个 add 操作的,而撤销仅仅是回退到上一个操作,注意是上一个操作,仅仅是一个操作。
那下面就到了我们练手的时候了 GO!!

举个例子:比如说你现在 向 demo.txt 这个文件中已经添加了一些内容,准备 add 进暂存区时,猛然发现要添加的文件中的内容写错了,这个时候怎么办?你可能会说这个还不简单 在 demo.txt 这个文件中使用 ctrl + z 不就完事了,恩 是滴 这样是可以解决的,但是在这里我们要讲的是另外一种方法,使用命令来完成我们的撤销操作:
$ git checkout -- demo.txt
撤销后,查看状态:
$ git statusOn branch masternothing to commit, working directory clean

这个问题是解决了,但是又有一个新的问题来了,大家有没有想过如果这时候我们修改的文件已经被添加进 暂存区 这种情况呢? 来 看代码:
我已经向 demo.txt 文件中添加了内容,让大家看一下当前的状态:
$ git statusOn branch masterChanges 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:   demo.txtno changes added to commit (use "git add" and/or "git commit -a")
这时候我们在 add:
$ git add demo.txt
那么此时的状态就变成了 已暂存 
$ git statusOn branch masterChanges to be committed:  (use "git reset HEAD <file>..." to unstage)        modified:   demo.txt
如果这时候我们想回去怎么办? 你觉得如果这时候我们还在 demo.txt 文件中使用 Ctrl + z 还好使么? 我们可以试一下看一下效果:
$ git statusOn branch masterChanges to be committed:  (use "git reset HEAD <file>..." to unstage)        modified:   demo.txtChanges 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:   demo.txt
恩?这是什么东东?其实想想也很好理解,我们都已经将文件 demo.txt 添加进 暂存区了,这时候我们在对 demo.txt 进行操作,所以,你懂得!就出现了这种情况

在这里我们还是先回到我们刚add完之后的状态,然后来看看在add 后怎么撤销:
$ git reset HEAD demo.txtUnstaged changes after reset:M       demo.txt

然后我们查看下状态:

$ git statusOn branch masterChanges 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:   demo.txtno changes added to commit (use "git add" and/or "git commit -a")
现在,假设你不但改错了东西,还从暂存区提交到了版本库,怎么办呢?还记得版本回退一节吗?可以回退到上一个版本。不过,这是有条件的,就是你还没有把自己的本地版本库推送到远程。还记得Git是分布式版本控制系统吗?我们后面会讲到远程版本库,一旦你把“stupid boss”提交推送到远程版本库,你就真的惨了……

回顾:

场景1:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令git checkout -- file

场景2:当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,第一步用命令git reset HEAD file,就回到了场景1,第二步按场景1操作。

场景3:已经提交了不合适的修改到版本库时,想要撤销本次提交,参考 版本回退 一节,不过前提是没有推送到远程库。

十、删除操作

删除操作主要包含两个:
一:误删操作:
二:删除操作:

如果是误删操作,我们要怎么回到没有删除之前的版本呢?
比如说现在我把 demo2.txt 这个文件给删除了(关于demo2.txt 这个文件大家有什么疑问可以去前面找找,我们是在将 工作区和暂存区时 创建的这个文件,文件现在还是空的呢,这里就用它来演示一下当前我们要做的操作),那么我们向回到demo2.txt 被删除之前的状态,那我们应该怎么回去呢?其实很简单,直接使用
git checkout 就可以实现这个操作,因为checkout 就是用来做在git 中 进行撤销操作的,具体的演示这里就不写了,命令给上:git checkout -- file

但如果是正常的删除情况呢? 如果是直接在工作空间中删除 demo2.txt 文件,会发生什么情况 大家应该都知道,这里也就不演示了,我们这里直接使用命令来进行删除 直接使用 git rm file 就行
$ git rm demo2.txtrm 'demo2.txt'
当前状态:
$ git statusOn branch masterChanges to be committed:  (use "git reset HEAD <file>..." to unstage)        deleted:    demo2.txt

好了,今天我们的内容暂时就先讲到这里,下一篇文章中我们会继续深入git的远程仓库以及分支等


相关文章:
1、《Gie基础教程1》
2、《Gie基础教程2》

0 0
原创粉丝点击