本章讲解知识点

    1. Git 开始入门
    1. Git 指令学习
    1. 节点合并的原理
    1. git 常用操作实例

  • 本专栏适合于软件开发刚入职的学生或人士,有一定的编程基础,帮助大家快速掌握工作中必会的工具和指令
  • 本专栏针对面试题答案进行了优化,尽量做到好记、言简意赅
  • 如专栏内容有错漏,欢迎在评论区指出或私聊我更改,一起学习,共同进步。
  • 相信大家都有着高尚的灵魂,请尊重我的知识产权,未经允许严禁各类机构和个人转载、传阅本专栏的内容。

1. Git 开始入门

终于要开始学习 Git 指令了,累死豆芽,其实 Git 指令相当简单,最好的方式就是边学习边实操。不过前面两节内容又不得不讲,这是为了构成知识的完整体系。

学习指令前,还要学点概念,嘿嘿。【不过可以先跳过,学会指令后再来看会理解更深刻。】

1.1. Git 状态区

我们先来理解下 Git 工作区暂存区版本库概念:

  • 工作区:就是你在电脑里能看到的目录。

  • 暂存区:英文叫 stage 或 index。一般存放在 .git 目录下的 index 文件 (.git/index)中,所以我们把暂存区有时也叫作索引(index)。

  • 版本库:工作区有一个隐藏目录 .git,这个不算工作区,而是 Git 的版本库。

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

img
  • 图中左侧为工作区,右侧为版本库。在版本库中标记为 "index" 的区域是暂存区(stage/index),标记为 "master" 的是 master 分支所代表的目录树。

  • 图中我们可以看出此时 "HEAD" 实际是指向 master 分支的一个"游标"。所以图示的命令中出现 HEAD 的地方可以用 master 来替换。

  • 图中的 objects 标识的区域为 Git 的对象库,实际位于 ".git/objects" 目录下,里面包含了创建的各种对象及内容。

  • 当对工作区修改(或新增)的文件执行 git add 命令时,暂存区的目录树被更新,同时工作区修改(或新增)的文件内容被写入到对象库中的一个新的对象中,而该对象的 ID 被记录在暂存区的文件索引中。

  • 当执行提交操作(git commit)时,暂存区的目录树写到版本库(对象库)中,master 分支会做相应的更新。即 master 指向的目录树就是提交时暂存区的目录树。

  • 当执行 git reset HEAD 命令时,暂存区的目录树会被重写,被 master 分支指向的目录树所替换,但是工作区不受影响。

  • 当执行 git rm --cached <file> 命令时,会直接从暂存区删除文件,工作区则不做出改变。

  • 当执行 git checkout . 或者 git checkout -- <file> 命令时,会用暂存区全部或指定的文件替换工作区的文件。这个操作很危险,会清除工作区中未添加到暂存区中的改动。

  • 当执行 git checkout HEAD . 或者 git checkout HEAD <file> 命令时,会用 HEAD 指向的 master 分支中的全部或者部分文件替换暂存区和以及工作区中的文件。这个命令也是极具危险性的,因为不但会清除工作区中未提交的改动,也会清除暂存区中未提交的改动。

1.2. Git 文件的三种状态

Git 版本控制下的文件状态有三种:

  1. 已提交(committed) 该文件已经被安全地保存在本地数据库中了。

  2. 已修改(modified) 修改了某个文件,但还没有提交保存

  3. 已暂存(staged) 把已修改的文件放在下次提交时要保存的清单中

以上概念我们会在讲指令是具体讲解。


2. Git 指令学习

img

2.1. git init

Git 使用 git init 命令来初始化一个 Git 仓库,Git 的很多命令都需要在 Git 的仓库中运行,所以 git init 是使用 Git 的第一个命令。

在执行完成 git init 命令后,Git 仓库会生成一个 .git 目录,该目录包含了资源的所有元数据,其他的项目目录保持不变。

使用方法

使用当前目录作为 Git 仓库,我们只需使它初始化。【打开终端(Linux)或 Git Bash(Windows)】

git init

该命令执行完后会在当前目录生成一个 .git 目录。

也可以使用我们指定目录作为 Git 仓库。

git init douya

初始化后,会在 douya 目录下会出现一个名为 .git 的目录,所有 Git 需要的数据和资源都存放在这个目录中。

我们来查看一下 .git 的目录。输入指令

ls

我们会发现没有输出什么信息,这是因为 .git 的目录针对用户隐藏的,目的为了防止误操作。

输入指令

ls -a

输出信息:

./  ../  .git/

这时我们就看到了隐藏目录,因为这个目录文件很重要,不建议初学者修改该目录或文件。

2.2. git clone

我们使用 git clone 从现有 Git 仓库中拷贝项目。之前我们通过 Github 创建了一个 repo,接下来我们将这个 repo 拷贝到我们的目录下。我们复制一下仓库的地址:

img

输入命令:按照自己的【仓库名】和【地址】进行修改

git clone **********:douya123456/git_practice.git

git clone 后面加上复制的仓库地址。

输出信息:

Cloning into 'git_practice'...
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (3/3), done.

可以看出来,已经拷贝成功,我们的目录下已经有了该仓库【工作目录

切换至工作目录:

cd git_practice/

配置用户名和邮箱:

git config --global user.name "douya123456"
git config --global user.email "**********"

换成自己的【用户名】和【邮箱】。

2.3. git add 和 git status

我们来创建一个新文件 douya.c

touch douya.c

然后写入一行信息:

echo "hello douya!" >> douya.c

查看内容:

$ cat douya.c
hello douya!

可以看到已成功写入信息了。

接着我们将此修改添加至【暂存区

git add douya.c

如果有多个地方修改,可以使用 git add .

然后我们使用 git status 命令查看暂存区状态

$ git status

On branch main
Your branch is up to date with 'origin/main'.

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        new file:   douya.c

可以看到这里 new file: douya.c ,说明这个新文件已经添加至【暂存区】,等待我们提交至【本地仓库】。

2.4. git commit 和 git log

git commit 指令用于提交【暂存区】的修改至【本地仓库】中。

git commit -m [message]

[message] 可以是一些备注信息。

接下来我们就把暂存区的修改,提交至【本地仓库】。

输入

git commit -m "the first commit"

我们使用 git status 命令查看暂存区状态

$ git status

On branch main
Your branch is ahead of 'origin/main' by 1 commit.
  (use "git push" to publish your local commits)

nothing to commit, working tree clean

可以看出来,我们已经成功将修改提交至【本地仓库】了。

【这里我们就要想想】:为什么区分【暂存区】和【本地仓库】?修改起来是不是更方便呢?答案是的。

接着我们通过 git log 命令查看我们的提交:

$ git log

commit 1ce338f343f906d6a60996ca89ff465e37ea5e4c (HEAD -> main)
Author: jiangwenbo <**********>
Date:   Sat Jul 24 15:31:09 2021 +0800

    the first commit

commit c714e05c5d8abe5b9e47978664ec187a5240510f (origin/main, origin/HEAD)
Author: douya123456 <52236573+douya123456@users.noreply.github.com>
Date:   Fri Jul 23 15:28:37 2021 +0800

    Initial commit

可以看到,连同我们的【提交备注】都一并可以在日志中查看到。

我们也可以只查看一个提交节点

$ git log -1

commit 1ce338f343f906d6a60996ca89ff465e37ea5e4c (HEAD -> main)
Author: jiangwenbo <**********>
Date:   Sat Jul 24 15:31:09 2021 +0800

    the first commit

git log -1 意思是只查看最新的一个提交内容。

2.5. git rm

现在我们再添加一行信息至 douya.c 中:

echo "hello again!" >> douya.c

再次添加修改:

$ git add .
$ git status

On branch main
Your branch is ahead of 'origin/main' by 1 commit.
  (use "git push" to publish your local commits)

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   douya.c

现在我想把 douya.c 的修改从【暂存区】移除,因为我不想将这个修改提交至【本地仓库

使用命令:

git rm --cached douya.c

当然我们也可以强行从暂存区和工作区中删除修改后的 douya.c 文件

git rm -f douya.c

使用这个 -f 命令后,工作区的 douya.c 文件也被删除了。

2.6. git mv

git mv 命令用于移动或重命名一个文件、目录或软连接。

git mv [file] [newfile]

如果新但文件名已经存在,但还是要重命名它,可以使用 -f 参数:

git mv -f [file] [newfile]

我们可以添加一个 README 文件(如果没有的话):

$ git add README 

然后对其重命名:

$ git mv README  README.md
$ ls
README.md

2.7. git push

git push 命用于从将本地的分支版本上传到远程并合并。

命令格式如下:

git push <远程主机名> <本地分支名>:<远程分支名>

如果本地分支名与远程分支名相同,则可以省略冒号:

git push <远程主机名> <本地分支名>

实例

以下命令将本地的 master 分支推送到 origin 主机的 master 分支。

$ git push origin master

相等于:

$ git push origin master:master

如果本地版本与远程版本有差异,但又要强制推送可以使用 --force 参数:

$ git push --force origin master

删除主机分支可以使用 --delete 参数,以下命令表示删除 origin 主机的 master 分支:

$ git push origin --delete master

所以我们将我们修改推送至【远端仓库

$ git push origin main

Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Writing objects: 100% (2/2), 194 bytes | 194.00 KiB/s, done.
Total