【Git】从零开始的 Git 基本操作

文章目录

  • 1. 创建 Git 本地仓库
  • 2. 配置 Git
  • 3. 认识工作区、暂存区、版本库
    • 3.1 添加文件 | 场景一
    • 3.2 查看 .git 文件
    • 3.3 添加文件 | 场景二
  • 4. 修改文件
  • 5. 版本回退
  • 6. 撤销修改
    • 6.1 情况一:对于工作区的代码,还没有 add
    • 6.2 情况二:已经 add,但没有 commit
    • 6.3 情况三:已经 add 了,并且也 commit 了
  • 7. 删除文件
  • 8. 本文命令总结

在这里插入图片描述

1. 创建 Git 本地仓库

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

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

ubuntu@VM-20-5-ubuntu:~/gitcode$ pwd
/home/ubuntu/gitcode
ubuntu@VM-20-5-ubuntu:~/gitcode$ git init
Initialized empty Git repository in /home/ubuntu/gitcode/.git/
ubuntu@VM-20-5-ubuntu:~/gitcode$ ll -a
total 12
drwxrwxr-x  3 ubuntu ubuntu 4096 Apr 16 19:26 ./
drwxr-xr-x 10 ubuntu ubuntu 4096 Apr 16 19:26 ../
drwxrwxr-x  7 ubuntu ubuntu 4096 Apr 16 19:31 .git/

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

其中包含 Git 仓库的诸多细节,使用 tree .git/ 命令看看:

ubuntu@VM-20-5-ubuntu:~/gitcode$ tree .git/
.git/
├── branches
├── config
├── description
├── HEAD
├── hooks
│   ├── applypatch-msg.sample
│   ├── commit-msg.sample
│   ├── fsmonitor-watchman.sample
│   ├── post-update.sample
│   ├── pre-applypatch.sample
│   ├── pre-commit.sample
│   ├── pre-merge-commit.sample
│   ├── prepare-commit-msg.sample
│   ├── pre-push.sample
│   ├── pre-rebase.sample
│   ├── pre-receive.sample
│   └── update.sample
├── info
│   └── exclude
├── objects
│   ├── info
│   └── pack
└── refs├── heads└── tags9 directories, 16 files

2. 配置 Git

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

git config [--global] user.name "your name"
git config [--global] user.email "email@example.com"# 把 your name 改为你的昵称
# 把 email@example.com 改为你的邮箱
# [--global] 代表 --global 是一个可选项,输入命令的时候不要加方框!!!

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

查看配置的命令为:

git config -l
# 实机演示
ubuntu@VM-20-5-ubuntu:~/gitcode$ git config user.name "tjq"
ubuntu@VM-20-5-ubuntu:~/gitcode$ git config user.email "1234567890@qq.com"
ubuntu@VM-20-5-ubuntu:~/gitcode$ git config -l
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
user.name=tjq					# 新增
user.email=1234567890@qq.com	# 新增

删除对应配置的命令为:

git config [--global] --unset user.name "your name"
git config [--global] --unset user.email "email@example.com"# 如果配置的时候加了 --global 选项,那么删除的时候也要加

删除配置后,可以使用查看配置的命令(git config -l)查看是否真的已经删除。

# 实机演示
ubuntu@VM-20-5-ubuntu:~/gitcode$ git config --unset user.name "tjq"
ubuntu@VM-20-5-ubuntu:~/gitcode$ git config --unset user.email "1234567890@qq.com"
ubuntu@VM-20-5-ubuntu:~/gitcode$ git config -l
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true

3. 认识工作区、暂存区、版本库

  • 工作区:是在电脑上你要写代码或文件的目录。
  • 暂存区:英文叫 stage 或 index。一般存放在 .git 目录下的 index 文件(.git/index)中,我们有时把暂存区也叫做索引(index)。
  • 版本库:又名仓库,英文名 repository 。工作区有一个隐藏目录 .git ,它不算工作区,而是 Git 的版本库。这个版本库里面的所有文件都可以被 Git 管理起来,每个文件的修改、删除,Git 都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”。

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

在这里插入图片描述

  • 图中左侧为工作区,右侧为版本库。Git 的版本库里存了很多东西,其中最重要的就是暂存区。
  • 在创建 Git 版本库时,Git 会为我们自动创建一个唯一的 master 分支,以及指向 master 的一个指针 HEAD。
  • 当对工作区修改(或新增)的文件执行 git add 命令时,暂存区目录树的文件索引会被更新。
  • 当执行提交操作 git commit 时,master 分支会做相应的更新,可以简单理解为暂存区的目录树才会被真正写到版本库中。

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

3.1 添加文件 | 场景一

在包含 .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 后面的 -m 选项,要跟上描述本次提交的 message,由用户自己完成,这部分内容绝对不能省略,并要好好描述,是用来记录你的提交细节,是给我们人看的。

# 实机演示
ubuntu@VM-20-5-ubuntu:~/gitcode$ touch ReadMe
ubuntu@VM-20-5-ubuntu:~/gitcode$ la
.git  ReadMe
ubuntu@VM-20-5-ubuntu:~/gitcode$ vim ReadMe
ubuntu@VM-20-5-ubuntu:~/gitcode$ cat ReadMe 
hello git
ubuntu@VM-20-5-ubuntu:~/gitcode$ git add ReadMe 
ubuntu@VM-20-5-ubuntu:~/gitcode$ git commit -m "add first file"
[master (root-commit) daca7d4] add first file1 file changed, 1 insertion(+)create mode 100644 ReadMe

git commit 命令执行成功后会告诉我们,1 个文件被改动(就是我们新添加的 ReadMe 文件),插入了一行内容。

我们还可以多次 add 不同的文件,而只 commit 一次便可以提交所有文件,是因为需要提交的文件是通通被 add 到暂存区中,然后一次性 commit 暂存区的所有修改。

# 实机演示
ubuntu@VM-20-5-ubuntu:~/gitcode$ touch file1 file2 file3
ubuntu@VM-20-5-ubuntu:~/gitcode$ la
file1  file2  file3  .git  ReadMe
ubuntu@VM-20-5-ubuntu:~/gitcode$ git add file1 file2 file3
ubuntu@VM-20-5-ubuntu:~/gitcode$ git commit -m "add 3 files"
[master 63ffac4] add 3 files3 files changed, 0 insertions(+), 0 deletions(-)create mode 100644 file1create mode 100644 file2create mode 100644 file3

截至目前为止,我们已经能够将代码直接提交至本地仓库了。那么可以查看我们的历史提交记录吗?如何查看?

# 查看历史提交记录
git log# 查看美观且简略的历史提交记录
git log --pretty=oneline

该命令显示从最近到最远的提交日志,并且可以看到我们 commit 时的日志消息。

如果嫌输出信息太多,看得眼花缭乱的,可以试试加上 --pretty=oneline 参数。

# 实机演示
ubuntu@VM-20-5-ubuntu:~/gitcode$ git log
commit 63ffac4330249843d4b68f6a5f59384ba09a0358 (HEAD -> master)
Author: tjq <1234567890@qq.com>
Date:   Thu Apr 18 10:46:40 2024 +0800add 3 filescommit daca7d41906c112f4b11c148a43cd2a0c23a4871
Author: tjq <1234567890@qq.com>
Date:   Thu Apr 18 10:20:39 2024 +0800add first file
# 上面信息太多?试试加上 --pretty=oneline
ubuntu@VM-20-5-ubuntu:~/gitcode$ git log --pretty=oneline 
63ffac4330249843d4b68f6a5f59384ba09a0358 (HEAD -> master) add 3 files
daca7d41906c112f4b11c148a43cd2a0c23a4871 add first file

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

3.2 查看 .git 文件

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

ubuntu@VM-20-5-ubuntu:~/gitcode$ tree .git/
.git/
├── branches
├── COMMIT_EDITMSG
├── config
├── description
├── HEAD
├── hooks
│   ├── applypatch-msg.sample
│   ├── commit-msg.sample
│   ├── fsmonitor-watchman.sample
│   ├── post-update.sample
│   ├── pre-applypatch.sample
│   ├── pre-commit.sample
│   ├── pre-merge-commit.sample
│   ├── prepare-commit-msg.sample
│   ├── pre-push.sample
│   ├── pre-rebase.sample
│   ├── pre-receive.sample
│   └── update.sample
├── index
├── info
│   └── exclude
├── logs
│   ├── HEAD
│   └── refs
│       └── heads
│           └── master
├── objects
│   ├── 0e
│   │   └── 6b1780b73cd9220ec5073dc64b42f7ad4bd945
│   ├── 15
│   │   └── a37e9ef171cca4a5d985fccd1fcf9414b2c7cf
│   ├── 63
│   │   └── ffac4330249843d4b68f6a5f59384ba09a0358
│   ├── 8d
│   │   └── 0e41234f24b6da002d962a26c2495ea16a425f
│   ├── da
│   │   └── ca7d41906c112f4b11c148a43cd2a0c23a4871
│   ├── e6
│   │   └── 9de29bb2d1d6434b8b29ae775ad8c2e48c5391
│   ├── info
│   └── pack
└── refs├── heads│   └── master└── tags18 directories, 27 files
  1. index 就是我们的暂存区,add 后的内容都是添加到这里的。

  2. HEAD 就是我们默认指向 master 分支的指针;

    ubuntu@VM-20-5-ubuntu:~/gitcode$ cat .git/HEAD 
    ref: refs/heads/master
    

    而默认的 master 分支又是什么呢?

    ubuntu@VM-20-5-ubuntu:~/gitcode$ cat .git/refs/heads/master 
    63ffac4330249843d4b68f6a5f59384ba09a0358
    

    打印的 63ffac4330249843d4b68f6a5f59384ba09a0358 是什么东西呢?是不是看起来有点眼熟,其实保存的就是当前最新的 commit id

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

    ubuntu@VM-20-5-ubuntu:~/gitcode$ ls .git/objects/
    0e  15  63  8d  da  e6  info  pack
    

    查找 objects 时要将 commit id 分成 2 部分,其中前 2 位是文件夹名称,后 38 位是文件名称。

    找到这个文件之后,一般不能直接看到里面是什么,该类文件是经过 sha(安全哈希算法)加密过的文件,但是我们可以使用 git cat-file 命令来查看版本库对象的内容:

    git cat-file [选项] [要查看的内容]
    
    # 实机演示
    ubuntu@VM-20-5-ubuntu:~/gitcode$ git cat-file -p 63ffac4330249843d4b68f6a5f59384ba09a0358
    tree 15a37e9ef171cca4a5d985fccd1fcf9414b2c7cf
    parent daca7d41906c112f4b11c148a43cd2a0c23a4871
    author tjq <2780888910@qq.com> 1713408400 +0800
    committer tjq <2780888910@qq.com> 1713408400 +0800add 3 files
    # 这是我们最近一次的提交
    

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

    ubuntu@VM-20-5-ubuntu:~/gitcode$ git cat-file -p 15a37e9ef171cca4a5d985fccd1fcf9414b2c7cf
    100644 blob 8d0e41234f24b6da002d962a26c2495ea16a425f	ReadMe
    100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391	file1
    100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391	file2
    100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391	file3
    

    再看 ReadMe 对应的 8d0e41234f24b6da002d962a26c2495ea16a425f

    ubuntu@VM-20-5-ubuntu:~/gitcode$ git cat-file -p 8d0e41234f24b6da002d962a26c2495ea16a425f
    hello git
    # 这是我们对 ReadMe 做的修改,被 git 记录了下来!
    

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

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

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

3.3 添加文件 | 场景二

学习到这里,我们已经清楚了如何向仓库中添加文件,并且对于工作区、暂存区、版本库也有了一定的认识。那么我们再展示一种添加文件的场景,能加深对工作区、暂存区、版本库的理解,示例如下:

ubuntu@VM-20-5-ubuntu:~/gitcode$ touch file4				# 1. 新增 file4 文件
ubuntu@VM-20-5-ubuntu:~/gitcode$ git add file4				# 2. 将 file4 添加到暂存区
ubuntu@VM-20-5-ubuntu:~/gitcode$ touch file5				# 3. 新增 file5 文件
ubuntu@VM-20-5-ubuntu:~/gitcode$ git commit -m "add file"	# 4. 提交修改
[master 6856fbd] add file1 file changed, 0 insertions(+), 0 deletions(-)create mode 100644 file4

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

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

4. 修改文件

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

什么是修改?比如你新增了一行,这就是一个修改;更改了某些字符,是一个修改;创建一个新文件,也是一个修改。

下面我们对 ReadMe 文件进行一次修改:

# 实机演示
ubuntu@VM-20-5-ubuntu:~/gitcode$ la
file1  file2  file3  file4  file5  .git  ReadMe
ubuntu@VM-20-5-ubuntu:~/gitcode$ cat ReadMe 
hello git
ubuntu@VM-20-5-ubuntu:~/gitcode$ vim ReadMe 
ubuntu@VM-20-5-ubuntu:~/gitcode$ cat ReadMe 
hello git
hello world

此时,仓库中的 ReadMe 和我们工作区的 ReadMe 是不同的,如何查看当前仓库状态呢?

# 查看仓库状态
git status
# 可以用这个命令查看在上次提交之后,是否对代码进行了再次修改
# 实机演示
ubuntu@VM-20-5-ubuntu:~/gitcode$ git status
On branch master
Changes not staged for commit:(use "git add <file>..." to update what will be committed)(use "git restore <file>..." to discard changes in working directory)modified:   ReadMeno changes added to commit (use "git add" and/or "git commit -a")

上面的结果告诉我们,ReadMe 被修改过了,但还没有完成添加与提交。

目前,我们只知道文件被修改了,如果能知道具体哪些地方被修改了,就更好了,这样代码多了以后也可以很方便的进行对比管理。怎么做呢?

# 查看暂存区和工作区文件的差异
git diff [file]# 查看版本库和工作区文件的差异
git diff HEAD -- [file]
# git diff [file] 实机演示
ubuntu@VM-20-5-ubuntu:~/gitcode$ git diff ReadMe
diff --git a/ReadMe b/ReadMe
index 8d0e412..05fe86c 100644
--- a/ReadMe
+++ b/ReadMe
@@ -1 +1,2 @@hello git
+hello world# git diff HEAD -- [file] 实机演示
ubuntu@VM-20-5-ubuntu:~/gitcode$ git diff HEAD -- ReadMe
diff --git a/ReadMe b/ReadMe
index 8d0e412..05fe86c 100644
--- a/ReadMe
+++ b/ReadMe
@@ -1 +1,2 @@hello git
+hello world

git diff [file] 命令用来显示暂存区和工作区文件的差异,显示的格式正是 Unix 通用的 diff 格式。也可以使用 git diff HEAD -- [file] 命令来查看版本库和工作区文件的区别。

知道了对 ReadMe 做了什么修改后,再把它提交到本地仓库就放心多了。

# git add 后再次查看仓库状态
ubuntu@VM-20-5-ubuntu:~/gitcode$ git add ReadMe 
ubuntu@VM-20-5-ubuntu:~/gitcode$ git status 
On branch master
Changes to be committed:(use "git restore --staged <file>..." to unstage)modified:   ReadMe

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

# git commit 后再次查看仓库状态
ubuntu@VM-20-5-ubuntu:~/gitcode$ git commit -m "modify ReadMe file"
[master 1c25401] modify ReadMe file1 file changed, 1 insertion(+)
ubuntu@VM-20-5-ubuntu:~/gitcode$ git status 
On branch master
nothing to commit, working tree clean	# 仓库状态恢复正常

5. 版本回退

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

# 版本回退
git reset [--soft | --mixed | --hard] [HEAD]

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

选项工作区暂存区版本库
–soft不回退不回退回退
–mixed(默认)不回退回退回退
–hard(慎用)回退回退回退
  • --soft 参数对于工作区和暂存区的内容都不变,只是将版本库回退到某个指定版本。
  • --mixed 为默认选项,使用时可以不用带该参数。该参数将暂存区的内容退回为指定提交版本内容,工作区文件保持不变。
  • --hard 参数将暂存区与工作区都退回到指定版本。切记工作区有未提交的代码时不要用这个命令,因为工作区会回滚,你没有提交的代码就再也找不回了,所以使用该参数一定要慎重
  • HEAD 说明:
    • 可直接写成 commit id,表示指定退回的版本
    • 可以使用 ^ 表示:
      • HEAD 表示当前版本
      • HEAD^ 表示上一个版本
      • HEAD^^ 表示上上个版本
    • 也可以使用 ~数字 表示:
      • HEAD~0 表示当前版本
      • HEAD~1 表示上一个版本
      • HEAD~2 表示上上个版本

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

# 第一次修改提交
ubuntu@VM-20-5-ubuntu:~/gitcode$ cat ReadMe 
hello git
hello world
hello version1		# 第1次新增
ubuntu@VM-20-5-ubuntu:~/gitcode$ git add ReadMe 
ubuntu@VM-20-5-ubuntu:~/gitcode$ git commit -m "add version1"
[master 1fbbbb8] add version11 file changed, 1 insertion(+)# 第二次修改提交
ubuntu@VM-20-5-ubuntu:~/gitcode$ cat ReadMe 
hello git
hello world
hello version1		# 第1次新增
hello version2		# 第2次新增
ubuntu@VM-20-5-ubuntu:~/gitcode$ git add ReadMe 
ubuntu@VM-20-5-ubuntu:~/gitcode$ git commit -m "add version2"
[master 792517a] add version21 file changed, 1 insertion(+)# 第三次修改提交
ubuntu@VM-20-5-ubuntu:~/gitcode$ cat ReadMe 
hello git
hello world
hello version1		# 第1次新增
hello version2		# 第2次新增
hello version3		# 第3次新增
ubuntu@VM-20-5-ubuntu:~/gitcode$ git add ReadMe 
ubuntu@VM-20-5-ubuntu:~/gitcode$ git commit -m "add version3"
[master ca0330f] add version31 file changed, 1 insertion(+)# 查看历史提交记录
ubuntu@VM-20-5-ubuntu:~/gitcode$ git log --pretty=oneline 
ca0330f09ba66638fc757525042034d82bb7ee90 (HEAD -> master) add version3
792517a8bc024eab200301baf8691de821548cbe add version2
1fbbbb826ccc07c0037f7208faeefeb577195f8c add version1
...

现在,如果我们在提交完 version 3 后,发现 version 3 编写错误,想回退到 version 2,重新基于 version 2 开始编写。

由于我们在这里希望的是将工作区的内容也回退到 version 2 版本,所以需要用到 --hard 参数,示例如下:

# 查看历史提交记录
ubuntu@VM-20-5-ubuntu:~/gitcode$ git log --pretty=oneline 
ca0330f09ba66638fc757525042034d82bb7ee90 (HEAD -> master) add version3
792517a8bc024eab200301baf8691de821548cbe add version2
1fbbbb826ccc07c0037f7208faeefeb577195f8c add version1
...
# 输入 commit id 指定回退到 version2
ubuntu@VM-20-5-ubuntu:~/gitcode$ git reset --hard 792517a8bc024eab200301baf8691de821548cbe
HEAD is now at 792517a add version2
ubuntu@VM-20-5-ubuntu:~/gitcode$ cat ReadMe 
hello git
hello world
hello version1
hello version2

我们发现:此时 ReadMe 文件的内容,已经回退到 version 2 了!当前我们再次用 git log 查看一下提交日志,发现 HEAD 指向了 version2,如下所示:

ubuntu@VM-20-5-ubuntu:~/gitcode$ git log --pretty=oneline 
792517a8bc024eab200301baf8691de821548cbe (HEAD -> master) add version2
1fbbbb826ccc07c0037f7208faeefeb577195f8c add version1
...

到这里一般的回退功能就演示完了,但是现在我后悔了,想再回到 version 3 怎么办?我们可以继续使用 git reset 命令,回退到 version 3 版本,但我们必须要拿到 version 3commit id 才能指定回退的版本。

但我们看到了 git log 并不能打印出 version 3commit id ,我们该如何找回呢?

# 显示本地每次提交的信息
git reflog
# 实机演示
ubuntu@VM-20-5-ubuntu:~/gitcode$ git reflog 
792517a (HEAD -> master) HEAD@{0}: reset: moving to 792517a8bc024eab200301baf8691de821548cbe
ca0330f HEAD@{1}: commit: add version3		# version 3 的记录
792517a (HEAD -> master) HEAD@{2}: commit: add version2
1fbbbb8 HEAD@{3}: commit: add version1
1c25401 HEAD@{4}: commit: modify ReadMe file
e094860 HEAD@{5}: commit: add file5
6856fbd HEAD@{6}: commit: add file
63ffac4 HEAD@{7}: commit: add 3 files
daca7d4 HEAD@{8}: commit (initial): add first file

这样,你就可以很方便的找到你的所有操作记录了,但 ca0330f 这个是啥东西?其实这就是 version 3commit id 的一部分。

没错,Git 版本回退的时候,也可以使用部分 commit id 来代表目标版本。示例如下:

# 回退到 version 3
ubuntu@VM-20-5-ubuntu:~/gitcode$ git reset --hard ca0330f
HEAD is now at ca0330f add version3# 查看工作区
ubuntu@VM-20-5-ubuntu:~/gitcode$ cat ReadMe 
hello git
hello world
hello version1
hello version2
hello version3# 查看 log
ubuntu@VM-20-5-ubuntu:~/gitcode$ git log --pretty=oneline 
ca0330f09ba66638fc757525042034d82bb7ee90 (HEAD -> master) add version3
792517a8bc024eab200301baf8691de821548cbe add version2
1fbbbb826ccc07c0037f7208faeefeb577195f8c add version1
1c25401534e7b402fc77529a1014647d2268447e modify ReadMe file
e094860cb7f95c34041e3520d17ee393965740c1 add file5
6856fbd20a828ed8c32b4f03982c8b1947c8b465 add file
63ffac4330249843d4b68f6a5f59384ba09a0358 add 3 files
daca7d41906c112f4b11c148a43cd2a0c23a4871 add first file

在长时间开发中,提交次数过多 / 本地信息丢失,可能使用 git reflog 也无法找到想要的 commit id 了,所以我们在版本回退时一定要慎重,后悔药也不是万能的!

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

在这里插入图片描述

6. 撤销修改

如果我们在工作区写了很长时间代码,越写越难受,感觉自己写的代码太垃圾了,想恢复到上一个版本,如何操作?

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

你当然可以直接手动删除代码,这个谁都会,但是在代码量很多的情况下,这种方法还适用吗?

Git 其实为我们提供了更好的方式:

# 对工作区代码撤销
git checkout -- [file]

我们可以使用这个命令让工作区的文件回到最近一次 addcommit 时的状态。要注意 git checkout -- [file] 命令中的 -- 很重要,切记不要省略,一旦省略,该命令就变为其他意思了

# 实机演示# 向 ReadMe 中新增一行代码
ubuntu@VM-20-5-ubuntu:~/gitcode$ vim ReadMe 
ubuntu@VM-20-5-ubuntu:~/gitcode$ cat ReadMe 
hello git
hello world
hello version1
hello version2
hello version3
This piece of code is like shit		# 新增# 恢复到上一次 add 或 commit
ubuntu@VM-20-5-ubuntu:~/gitcode$ git checkout -- ReadMe
ubuntu@VM-20-5-ubuntu:~/gitcode$ cat ReadMe 
hello git
hello world
hello version1
hello version2
hello version3

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

add 后,代码保存到了暂存区,如何撤销?

# 向 ReadMe 中新增一行代码
ubuntu@VM-20-5-ubuntu:~/gitcode$ vim ReadMe 
ubuntu@VM-20-5-ubuntu:~/gitcode$ cat ReadMe 
hello git
hello world
hello version1
hello version2
hello version3
This piece of code is like shit		# 新增# add 存入暂存区
ubuntu@VM-20-5-ubuntu:~/gitcode$ git add ReadMe 
ubuntu@VM-20-5-ubuntu:~/gitcode$ git status 
On branch master
Changes to be committed:(use "git restore --staged <file>..." to unstage)modified:   ReadMe

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

# --mixed 是默认参数,使用时可以省略
ubuntu@VM-20-5-ubuntu:~/gitcode$ git reset HEAD ReadMe
Unstaged changes after reset:
M	ReadMe# 使用 git status 查看状态,发现暂存区是干净的,工作区有修改
ubuntu@VM-20-5-ubuntu:~/gitcode$ git status 
On branch master
Changes not staged for commit:(use "git add <file>..." to update what will be committed)(use "git restore <file>..." to discard changes in working directory)modified:   ReadMeno changes added to commit (use "git add" and/or "git commit -a")

现在可以使用刚才 情况一 中的 git checkout -- [file] 撤销命令,把工作区的内容撤销:

ubuntu@VM-20-5-ubuntu:~/gitcode$ git checkout -- ReadMe
ubuntu@VM-20-5-ubuntu:~/gitcode$ git status 
On branch master
nothing to commit, working tree clean	# 工作区是干净的
ubuntu@VM-20-5-ubuntu:~/gitcode$ cat ReadMe 
hello git
hello world
hello version1
hello version2
hello version3	# 新增的代码没有了

6.3 情况三:已经 add 了,并且也 commit 了

不要担心,我们可以使用 git reset --hard HEAD^ 命令回退到上一个版本!

不过,这是有条件的,即:我们还没有把本地仓库的代码推送到远程仓库(gitee / github),因为撤销功能本质就是为了防止不好的代码被推送到远端。

# 实机演示# 向 ReadMe 中新增一行代码
ubuntu@VM-20-5-ubuntu:~/gitcode$ vim ReadMe 
ubuntu@VM-20-5-ubuntu:~/gitcode$ cat ReadMe 
hello git
hello world
hello version1
hello version2
hello version3
This piece of code is like shit		# 新增# 提交
ubuntu@VM-20-5-ubuntu:~/gitcode$ git add ReadMe 
ubuntu@VM-20-5-ubuntu:~/gitcode$ git commit -m "test quash"
[master 15e3520] test quash1 file changed, 1 insertion(+)# 回退
ubuntu@VM-20-5-ubuntu:~/gitcode$ git reset --hard HEAD^
HEAD is now at ca0330f add version3
ubuntu@VM-20-5-ubuntu:~/gitcode$ cat ReadMe 
hello git
hello world
hello version1
hello version2
hello version3

总结:

工作区暂存区版本库解决方法
最新版本上一版本 | 其他版本git check -- [file] 撤销工作区到上一版本
最新版本最新版本上一版本 | 其他版本git reset [--mixed | --hard] [HEAD] 回退暂存区和工作区
最新版本最新版本最新版本 | 上一版本 | 其他版本git reset [--hard] [HEAD] 回退版本库、暂存区和工作区

7. 删除文件

在 Git 中,删除一个文件不仅仅是把工作区的文件删除,还要把版本库中对应的文件也删除,否则会造成工作区与版本库不匹配的问题!

我们删除之前提交的 file5 试试:

# 实机演示# rm 删除工作区的 file5
ubuntu@VM-20-5-ubuntu:~/gitcode$ ls
file1  file2  file3  file4  file5  ReadMe
ubuntu@VM-20-5-ubuntu:~/gitcode$ rm file5# 查看状态
ubuntu@VM-20-5-ubuntu:~/gitcode$ git status 
On branch master
Changes not staged for commit:(use "git add/rm <file>..." to update what will be committed)(use "git restore <file>..." to discard changes in working directory)deleted:    file5no changes added to commit (use "git add" and/or "git commit -a")
# git status 提示我们工作区被修改了(删除也算修改)
# 我们需要把本次修改提交到版本库# 提交
ubuntu@VM-20-5-ubuntu:~/gitcode$ git add file5
ubuntu@VM-20-5-ubuntu:~/gitcode$ git commit -m "delete file5"
[master 6fdee7a] delete file51 file changed, 0 insertions(+), 0 deletions(-)delete mode 100644 file5# 再次查看
ubuntu@VM-20-5-ubuntu:~/gitcode$ git status
On branch master
nothing to commit, working tree clean
ubuntu@VM-20-5-ubuntu:~/gitcode$ ls
file1  file2  file3  file4  ReadMe
# 到这里才算是删干净了

除了上面的基本方法以外,Git 还提供了一个专用的删除命令:

# 删除文件
git rm [file]

使用此命令可以让我们少 add 一次,相当于直接把工作区的删除操作同步到了暂存区,我们删除 file4 试试:

ubuntu@VM-20-5-ubuntu:~/gitcode$ ls
file1  file2  file3  file4  ReadMe# 使用 git rm 命令删除 file4
ubuntu@VM-20-5-ubuntu:~/gitcode$ git rm file4
rm 'file4'
ubuntu@VM-20-5-ubuntu:~/gitcode$ git status 
On branch master
Changes to be committed:(use "git restore --staged <file>..." to unstage)deleted:    file4ubuntu@VM-20-5-ubuntu:~/gitcode$ git commit -m "delete file4"
[master 0c91580] delete file41 file changed, 0 insertions(+), 0 deletions(-)delete mode 100644 file4# 删除完成后查看
ubuntu@VM-20-5-ubuntu:~/gitcode$ git status 
On branch master
nothing to commit, working tree clean
ubuntu@VM-20-5-ubuntu:~/gitcode$ ls
file1  file2  file3  ReadMe

现在,我们就掌握了两种在 Git 中删除文件的方式。

8. 本文命令总结

为了方便查阅,我按照本文的先后顺序,在这里列出我们学习到的 Git 新命令:

1. 创建本地仓库
git init2. 配置 git
git config [--global] user.name "your name"
git config [--global] user.email "email@example.com"3. 查看配置
git config -l4. 删除配置
git config [--global] --unset user.name "your name"
git config [--global] --unset user.email "email@example.com"5. 添加文件
# 添加一个或多个文件到暂存区:
git add [file1] [file2] ...
# 添加指定目录到暂存区,包括子目录:
git add [dir]
# 添加当前目录下的所有文件改动到暂存区:
git add .6. 提交文件
# 提交暂存区全部内容到本地仓库中:
git commit -m "message"
# 提交暂存区的指定文件到仓库区:
git commit [file1] [file2] ... -m "message"7. 查看提交记录
# 查看历史提交记录
git log
# 查看美观且简略的历史提交记录
git log --pretty=oneline8. 查看版本库对象的内容
git cat-file [选项] [要查看的内容]9. 查看仓库状态
git status 10. 查看文件间差异
# 查看暂存区和工作区文件的差异
git diff [file]
# 查看版本库和工作区文件的差异
git diff HEAD -- [file]11. 版本回退
git reset [--soft | --mixed | --hard] [HEAD]12. 显示本地每次提交的信息
git reflog13. 撤销工作区操作回上个版本
git checkout -- [file]14. 删除文件
git rm [file]

END

上一篇: 【Git】安装 Git

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/964.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

实在IDP文档审阅产品导引

实在IDP文档审阅&#xff1a;智能文档处理的革新者 一、引言 在数字化转型的浪潮中&#xff0c;文档处理的智能化成为企业提效的关键。实在智能科技有限公司推出的实在IDP文档审阅&#xff0c;是一款利用AI技术快速理解、处理文档的智能平台&#xff0c;旨在为企业打造专属的…

Qt 6子窗口全屏显示

一、全屏显示效果 二、全屏相关函数 1,全屏显示函数 QWidget::showFullScreen(); // 此方法只对顶级窗口有效&#xff0c;对子窗口无效 2&#xff0c;恢复显示函数 QWidget::showNormal(); // 此方法也只对顶级窗口有效&#xff0c;对子窗口无效 3&#xff0c;最小化显示函…

go语言并发实战——日志收集系统(五) 基于go-ini包读取日志收集服务的配置文件

实现日志收集服务的客户端 前言 从这篇文章开始我们就正式进入了日志收集系统的编写&#xff0c;后面几篇文章我们将学习到如何编写日志收集服务的客户端,话不多说,让我们进入今天的内容吧&#xff01; 需要实现的功能 我们要收集指定目录下的日志文件&#xff0c;将它们发…

12. MyBatis(二)

源码位置&#xff1a;MyBatis_demo 上篇文章我们学习了MyBatis的定义以及增删查改操作&#xff0c;并且学习了如何在xml文件中编写SQL时使用#{}的方式将参数和对象的属性映射到SQL语句中&#xff0c;上篇的内容已经足以应对大部分场景&#xff0c;本篇文章我们就要学习一下MyBa…

基础算法---二分查找

文章目录 基本思想1.数的范围2.搜索旋转排序数组3.搜索插入位置4.x的平方根总结 基本思想 二分查找的必要条件并不是单调&#xff0c;而是当我给定一个边界条件&#xff0c;然后左边满足这个边界条件&#xff0c;右边不满足这个边界条件&#xff0c;然后可以查找这个临界点&am…

华火电燃灶:烹饪艺术与科技创新的完美融合

华火电燃灶&#xff0c;以纯净电力激发明火之美&#xff0c;无须燃气&#xff0c;尽释碳负。每一道佳肴背后&#xff0c;都是对安全与健康的无声誓言&#xff0c;为家庭温馨瞬间添上一抹灿烂。从宝贝初声啼哭到晚年宁静美好&#xff0c;华火见证家的每一次幸福团聚&#xff0c;…

DevOps流程的简单总结

DevOps流程图&#xff1a; DevOps流程包含&#xff1a;计划&#xff08;plan&#xff09;、编码(code)、编译(build)、测试(test)、发布(release)、部署(deploy)、运营(operate)、监控&#xff08;monitor&#xff09;&#xff0c;这是一个循环的过程。DevOps是依托容器、自动化…

流程控制:goto语句,模拟switch语句

示例&#xff1a; /*** brief how about goto-switch? show you here.* author wenxuanpei* email 15873152445163.com(query for any question here)*/ #define _CRT_SECURE_NO_WARNINGS//support c-library in Microsoft-Visual-Studio #include <stdio.h>static …

涉密人员离职,如何一键锁定他的电脑屏幕

在任何情况下&#xff0c;保护企业数据的安全性和机密性都是非常重要的。如果涉密人员离职&#xff0c;应该遵循相关的保密协议和规定&#xff0c;确保企业数据的完整性和安全性。同时&#xff0c;也应该对员工进行适当的培训和教育&#xff0c;提高他们的安全意识和技能水平。…

【c++】cpp数学库函数、随机数和时间库函数

&#xff08;1&#xff09;cpp数学库函数 #include <iostream>using namespace std;#include <cmath> //数学函数库的头文件#define pi 3.1415926 //定义一个常量π int main() {cout << "平方数:pow(3, 2) :" << pow(3, 2) << endl;…

selenium‘拟人包装‘设置

1、设置header,proxy 1.1关于user-agent 输入about:version 找到user-agent: import requests # 引用requests库 from selenium import webdriver#载入浏览器驱动#header&#xff0c;proxy设置 optionswebdriver.ChromeOptions()#实例化浏览器参数设置options.add_argument…

水电远程预付费系统:创新与便利的融合

1.系统概述 水电远程预付费系统是一种现代化的管理工具&#xff0c;它通过先进的信息技术实现了水电费用的预先支付和远程管理。这种系统不仅提高了服务效率&#xff0c;也为用户带来了极大的便利&#xff0c;减少了传统抄表和收费过程中的诸多不便。 2.功能特性 2.1实时计量…

pycharm创建的项目

pycharm生成django templates删出 settings.py

nvidia-smi CUDA Version:N/A

问题 nvidia-smi显示&#xff1a;CUDA Version:N/A nvidia-smi -a显示&#xff1a;CUDA Version: Not Found 解决方法 查看Nvidia驱动版本 nvidia-smi如下图&#xff0c;版本为530.41.03 搜索cuda库 apt search libcuda注&#xff1a;不同的源&#xff0c;同一个库的命…

【JavaSE】JDK17的一些特性

前言 从springboot3.0开始&#xff0c;已经不⽀持JDK8了 选⽤Java17&#xff0c;概括起来主要有下⾯⼏个主要原因 JDK17是LTS(⻓期⽀持版)&#xff0c;可以免费商⽤到2029年。⽽且将前⾯⼏个过渡版&#xff08;JDK9-JDK16&#xff09; 去其糟粕&#xff0c;取其精华的版本JDK17…

用友 NC showcontent SQL注入漏洞复现

0x01 产品简介 用友NC是由用友公司开发的一套面向大型企业和集团型企业的管理软件产品系列。这一系列产品基于全球最新的互联网技术、云计算技术和移动应用技术&#xff0c;旨在帮助企业创新管理模式、引领商业变革。 0x02 漏洞概述 用友NC /ebvp/infopub/showcontent 接口处…

AndroidStudio右下角显示内存使用情况

目录 一.具体效果 二.4.0以下版本 三.4.0以上版本 四.增加内存配置 一.具体效果 二.4.0以下版本 1.打开 Android Studio. 2.进入设置界面。点击 Android Studio 左上角的“File”&#xff0c;然后选择“Settings” 3.在设置界面中&#xff0c;选择“Appearance & Beha…

机器学习理论公式推导及原理—决策树

机器学习公式推导及原理—决策树 根据西瓜书中的公式与内容来进行推导和实现 算法原理 从逻辑角度&#xff0c;一堆if else语句的组合从几何角度&#xff0c;根据某种准则划分特征空间。最终目的&#xff1a;将样本越分越“纯。 信息熵的概念 自信息&#xff1a;是指随机变量…

【汇编语言】初识汇编

【汇编语言】初识汇编 文章目录 【汇编语言】初识汇编前言由机器语言到汇编语言机器语言与机器指令汇编语言与汇编指令汇编语言程序示例 计算机组成指令和数据的表示计算机的存储单元计算机的总线 内存读写与地址空间CPU对存储器的读写内存地址空间 总结 前言 为什么要学习汇编…

29. 【Android教程】折叠列表 ExpandableListView

本节学习一个可折叠的 ListView&#xff0c;可以用在一些需要分类的场景下。通过 ExpandableListView 我们可以首先在 ListView 上展示大的分类&#xff0c;当点击某个类别的时候再将 ListView 做一个展开&#xff0c;展示该类下的所有子类供用户选择。它与 ListView 的不同主要…