• 【Git】Git 的基本操作 -- 详解


    一、创建 Git 本地仓库

    要提前说的是,仓库是进行版本控制的一个文件目录。我们要想对文件进行版本控制,就必须先创建一个仓库出来。

    创建⼀个 Git 本地仓库对应的命令为 git init ,注意命令要在文件目录下执行,例如:

    我们发现,当前目录下多了一个 .git 的隐藏文件,.git 目录是 Git 来跟踪管理仓库的,不要手动修改这个目录里面的文件,不然改乱了,就把 Git 仓库给破坏了。

    其中包含 Git 仓库的诸多细节:


    二、配置 Git

    当安装 Git 后首先要做的事情是设置自己的用户名称e-mail 地址,这是非常重要的。配置命令为:

    1. git config [--global] user.name "Your Name"
    2. git config [--global] user.email "email@example.com"
    3. # 把 Your Name 改成你的昵称
    4. # 把 email@example.com 改成邮箱的格式,只要格式正确即可

    注意:其中 --global 是一个可选项。如果使用了该选项,表示这台机器上所有的 Git 仓库都会使用这个配置。如果希望在不同仓库中使用不同的 name e-mail,可以不要 --global 选项,但要注意的是,执行命令时必须要在仓库里。


    1、查看配置命令

    git config -l


    2、删除对应的配置命令

    git config [ --global ] --unset user.name
    git config [ --global ] --unset user.email

    三、认识工作区、暂存区、版本库

    1、工作区

    在电脑上你要写代码或文件的目录。


    2、暂存区(stage 或 index)

    ⼀般存放在 .git 目录下的 index 文件(.git/index)中,我们把暂存区有时也叫作索引(index)。


    3、版本库(Repository)

    又名仓库 。工作区有一个隐藏目录 .git ,它不算工作区,而是 Git 的版本库。这个版本库里面的所有文件都可以被 Git 管理起来,每个文件的修改、删除,Git 都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以 “还原”。


    下面这个图展示了工作区、暂存区和版本库之间的关系:

    • 图中左侧为工作区右侧为版本库。Git 的版本库里存了很多东西,其中最重要的就是暂存区

    • 在创建 Git 版本库时,Git 会为我们自动创建一个唯一的 master 分支,以及指向 master 的⼀个指针叫 HEAD

    • 当对工作区修改(或新增、删除)的文件执行 git add 命令时,暂存区目录树的文件索引会被更新。

    • 当执行提交操作 git commit 时,master 分支会做相应的更新,可以简单理解为暂存区的目录树才会被真正写到版本库中。

    由上述描述我们便能得知:通过新建或粘贴进目录的文件,并不能称之为向仓库中新增文件,而只是在工作区新增了文件。必须要通过使用 git add git commit 命令才能将文件添加到仓库中进行管理。


    四、添加文件(一)

    在包含 .git 的目录下新建一个 ReadMe ⽂件,但在目前情况下,Git 还不能管理我们的 ReadMe 文件。

    可以使用 git add 命令可以将文件添加到暂存区:

    • 添加一个或多个文件到暂存区: git add [file1] [file2] ...

    • 添加指定目录到暂存区,包括子目录: git add [dir]

    • 添加当前目录下的所有文件改动到暂存区: git add .

    • 再使用 git commit 命令将暂存区内容添加到本地仓库中:

    • 提交暂存区全部内容到本地仓库中: git commit -m "message"

    • 提交暂存区的指定文件到仓库区: git commit [file1] [file2] ... -m "message"

    git commit 命令执行成功后会告诉我们,1 个文件被改动(就是我们新添加的 ReadMe 文件),插入了一行内容(ReadMe 有一行内容)。 还可以多次 add 不同的文件,而只 commit 一次便可以提交所有文件,是因为需要提交的⽂件是通通被 add 到暂存区中,然后一次性 commit 暂存区的所有修改。如:

    注意git commit 后面-m 选项,要跟上描述本次提交的 message,由用户自己完成,这部分内容绝对不能省略,并要好好描述,是用来记录你的提交细节,是给我们自己看的。

    截至目前为止,我们已经更够将代码直接提交至本地仓库了。可以使用 git log 命令,来查看下历史提交记录:

    该命令显示从最近到最远的提交日志,并且可以看到我们 commit 时的日志消息。如果担心输出的信息太多,看得眼花缭乱,可以试试加上 --pretty=oneline 参数:

    需要说明的是,我们看到的一大串类似 c64e0871...9c6502 的是每次提交的 commit id(版本号),Git 的 commit id 不是 1,2,3…… 递增的数字,而是⼀个 SHA1 计算出来的一个非常大的数字,用十六进制表示。


    五、查看 .git 文件

    先来看看我们的 .git 的目录结构:

    • index 就是我们的暂存区,add 后的内容都是添加到这里的

    • HEAD 就是我们的默认指向 master 分支的指针

    上面就是我们默认的 master 分支。

    打印的 c64e0871d6aaf40315d85200eb32c558bd9c6502 是什么东西呢?

    保存的就是当前最新的 commit id

    • objects Git 的对象库,里面包含了创建的各种版本库对象及内容。当执行 git add 命令时,暂存区的目录树被更新,同时工作区修改(或新增)的文件内容被写入到对象库中的一个新的对象中,就位于 ".git/objects" 目录下,来看看这些对象有何用处:

    查找 object 时要将 commit id 分成 2 部分,其前 2 位是文件夹名称,后 38 位是文件名称。找到这个文件之后,一般不能直接看到里面是什么,该类文件是经过 sha (安全哈希算法)加密过的文件,好在我们可以使用 git cat-file 命令来查看版本库对象的内容:

    这就是我们最近⼀次的提交。

    其中,还有一行 tree 15a37e9ef171cca4a5d985fccd1fcf9414b2c7cf,我们使用同样的方法,看看结果:

    再看 ReadMe 对应的 8d0e41234f24b6da002d962a26c2495ea16a425f:

    这是我们对 ReadMe 做的修改,被 git 记录了下来。

    总结一下,在本地的 git 仓库中,有几个文件或者目录很特殊

    • index:暂存区,git add 后会更新该内容。
    • HEAD:默认指向 master 分支的一个指针。
    • refs/heads/master:文件里保存当前 master 分支的最新 commit id。
    • objects:包含了创建的各种版本库对象及内容,可以简单理解为放了 git 维护的所有修改。

    后面再在学习的过程中,最好能将常见的 git 操作与 .git 目录当中的结构内容变化对应起来,这样有利于理解 git 细节流程。


    六、添加文件(二)

    下面展示另一种添加文件的场景,能加深对工作区、暂存区、版本库的理解,示例如下:

    1. 新增 file4 文件
    2. 将 file4 添加到暂存区
    3. 新增 file5 文件
    4. 提交修改

    提交后发现打印了 1 file changed, 0 insertions(+), 0 deletions(-) ,意思是只有一个文件改变了,难顶不是新增了两个文件吗?

    git add 是将文件添加到暂存区,git commit 是将暂存区的内容添加到本地仓库中。由于我们并没有使用 git add file5 ,file5 就不在暂存区中维护,所以在 commit 的时候其实只是把已经在暂存区的 file4 提交了,而遗漏了工作区的 file5。

    如何提交 file5 呢?

    再次 add,commit 即可。


    七、修改文件

    Git 比其他版本控制系统设计得优秀,因为 Git 跟踪并管理的是修改,而非文件。


    1、什么是修改

    比如你新增了一行,这就是一个修改,删除了一行,也是⼀个修改,更改了某些字符,也是一个修改,删了一些又加了一些,也是一个修改,甚至创建一个新文件,也算一个修改。

    让我们将 ReadMe 文件进行一次修改:

    此时,仓库中的 ReadMe 和我们工作区的 ReadMe 是不同的。

    如何查看当前仓库的状态呢?

    用命令:git status 来查看在你上次提交之后是否有对文件进行再次修改。

    上面的结果告诉我们,ReadMe 被修改过了,但还没有完成添加与提交。目前,我们只知道文件被修改了,如果能知道具体哪些地方被修改了,就更好了。可是我们还会记得一周之前写了什么代码吗,或者没写。

    命令:git diff [file] 用来显示暂存区和工作区文件的差异,显示的格式正是 Unix 通用的 diff 格式。也可以使用 git diff HEAD -- [file] 命令来查看版本库和工作区文件的区别。知道了对 ReadMe 做了什么修改后,再把它提交到本地仓库就放心多了。

    git add 之后,就没有看到上面 no changes added to commit (use "git add" and/or "git commit -a") 的消息了,接下来继续 git commit 即可:


    八、版本回退

    前面也讲到过,Git 能够管理文件的历史版本,这也是版本控制器重要的能力。如果有一天发现之前的工作出现了很大的问题,需要在某个特定的历史版本重新开始,那么这个时候就需要用到版本回退的功能了。

    执行 git reset 命令用于回退版本,可以指定退回某⼀次提交的版本。要解释一下 “回退” 的本质是要将版本库中的内容进行回退,工作区或暂存区是否回退由命令参数决定:

    git reset 命令语法格式为: git reset [--soft | --mixed | --hard] [HEAD]

    • --mixed 为默认选项,使用时可以不用带该参数。该参数将暂存区的内容退回为指定提交版本内容,工作区文件保持不变。

    • --soft 参数对于工作区和暂存区的内容都不变,只是将版本库回退到某个指定版本。

    • --hard 参数将暂存区与工作区都退回到指定版本。切记工作区有未提交的代码时不要用这个命令,因为工作区会回滚,你没有提交的代码就再也找不回了,所以使用该参数前一定要慎重。

    • HEAD 说明:

    1. 可直接写成 commit id,表示指定退回的版本。

    2. HEAD 表示当前版本。

    3. HEAD^ 表示上一个版本。

    4. HEAD^^ 表示上上一个版本。

    5. 以此类推...

    • 可以使用 ~ 数字表示:

    1. HEAD~0 表示当前版本。

    2. HEAD~1 表示上一个版本。

    3. HEAD^2 表示上上一个版本。

    4. 以此类推...

    为了便于表述,方便测试回退功能,先做一些准备工作:更新 3 个版本的 ReadMe,并分别进行 3 次提交,如下所示:

    如果我后悔了上面的操作,想再回去怎么办?

    可以继续使用 git reset 命令,回退到原先的版本,但我们必须要拿到原先版本commit id 去指定回退的版本。

    但我们看到了 git log 并不能打印出之前版本commit id ,运气好的话我们可以从终端上去找找之前的历史记录,运气不好的话 commit id 已经被我们搞丢了。不过 Git 还提供了⼀个 git reflog 命令能够补救一下,这个命令用来记录本地的每一次命令。

    这样就可以很方便的找到我们的所有操作记录了,但这个 c752678 这个是什么?

    是原先最新的版本。Git 版本回退的时候,也可以使用部分 commit id 来代表目标版本

    可以发现,此时 ReadMe 文件的内容,已经回退到最开始提交的时候了。

    但在实际开发中,由于长时间的开发,导致 commit id 早就找不到了,可是突然又想回退到之前的版本,那该如何操作呢?

    貌似现在就不可能做到了,但值得说的是,Git 的版本回退速度非常快,因为 Git 在内部有个指向当前分支(此处是 master)的 HEAD 指针, refs/heads/master 文件里保存当前 master 分支的最新 commit id 。当我们在回退版本的时候,Git 仅仅是给 refs/heads/master 中存储⼀个特定的 version,可以简单理解成如下示意图:


    九、撤销修改

    如果我们在我们的工作区写了很长时间代码,越写越写不下去,想恢复到上⼀个版本。


    1、情况一:对于工作区的代码,还没有 add

    新增代码后:

    可以直接删掉目前在工作区新增的代码,但如果我们写了 3 天,⼀直都没有提交,该怎么删掉呢?自己忘了新增过哪些,可以 git diff xxx ⼀下,看看差别再删。

    那我们肯定又要花上 3 天时间来删代码了,并且很大的概率还会改出 bug。Git 其实还为我们提供了更好的方式,可以使用 git checkout -- [file] 命令让工作区的文件回到最近一次 add commit 时的状态

    注意 git checkout -- [file] 命令中的 -- 很重要,切记不要省略。⼀旦省略,该命令就变为其他意思了。


    2、情况二:已经 add,但没有 commit

    回忆⼀下上面讲的 git reset 回退命令,该命令如果使用 --mixed 参数,可以将暂存区的内容退回为指定的版本内容,但工作区文件保持不变,那我们就可以回退下暂存区的内容了。

    用 git status 查看⼀下,发现现在暂存区是干净的,工作区有修改。

    注意--mixed 是默认参数,使用时可以省略。

    如何丢弃工作区的修改呢?


    3、情况三:已经 add,并且也 commit

    可以 git reset --hard HEAD^ 回退到上⼀个版本。但是这么做有条件的,就是还没有把自己的本地版本库推送到远程。⼀旦推送到远程版本库,就撤回不了了。



    十、删除文件

    在 Git 中,删除也是⼀个修改操作

    如果要删除 file5 文件,要怎么操作呢?如果是按照下面这种做法:

    这样直接删除是没有用的,反而徒增烦恼, git status 命令会立刻告诉我们哪些文件被删除了:

    此时,工作区和版本库就不⼀致了,要删文件,目前除了要删工作区的文件,还要清除版本库的文件。

    ⼀般走到这里,有两种可能

    • 确实要从版本库中删除该文件。
    • 不小心删错了。

    对第二种情况,很明显误删,需要使用 git 来进行恢复,很简单,我们刚学过(删除也是修改):

    对于第一种情况,很明显是没有删完,我们只删除了工作区的文件。这时就需要使用 git rm 将文件从暂存区和工作区中删除,并且 commit

    现在,文件就从版本库中被删除了。

  • 相关阅读:
    将用友U8的数据可视化需要哪些工具?
    菱形(曼哈顿距离) C++实现
    mysql数据库
    CentOS:root密码修改
    【leetcode】三维形体投影面积 c++
    【如何看待Unity收费】对标中小公司的待就业者的该如何做
    分布式任务调度Schedulerx2.0 Map模型作业执行流程
    CHATGPT----自然辩证法分析
    redis基本工具类编写
    CSS笔记(黑马程序员pink老师前端)CSS初始化
  • 原文地址:https://blog.csdn.net/weixin_74531333/article/details/139383585