在上一篇中,我们学习了如何安装 Git 并创建了第一个本地堆栈。现在,我们要深入了解 Git 工作中几个非常重要的概念,并学习如何将文件真正地纳入 Git 的管理之下。
认识 Git 的三大区域:工作区、暂存区、版本库
要明白 Git 的工作流程,必须先搞清晰它在哪几个地方“存放”和“处理处罚”你的文件。 Git 主要涉及以下三个区域:
- 工作区(Working Directory)
- 是什么? 就是你在电脑里,能直接看到、直接操作的谁人项目文件夹。比如你在里面新建文件、修改代码,这些操作都是在工作区进行的。简单来说,这就是你正在工作的地方,你的“办公桌”。
- 暂存区(Staging Area / Index)
- 是什么? 这是 Git 中一个非常核心且独特的概念。它不像工作区那样是一个看得见的文件夹,它更像一个目录清单大概一个中心“打包区”。当你以为工作区里的某个文件修改好了,大概某个新文件要纳入 Git 管理了,你就可以用一个命令把这些改动“放”到暂存区里,表明“我这些改动已经准备好了,待会儿要一起保存”。
- 在哪儿? 暂存区的信息通常存放在 Git 堆栈目录(谁人隐蔽的 .git 文件夹)下的 index 文件里(路径是 .git/index)。以是,有时候人们也把暂存区叫做“索引”(Index)。可以想象成你的“打包盒子”,你把准备好一起提交的文件放进去。
- 版本库(Repository)
- 是什么? 这就是 Git 用来永世存储你的项目历史版本的地方。它包含了所有提交过的版本数据,分支信息,以及 Git 管理项目所需的统统数据。
- 在哪儿? 就是你项目文件夹里谁人隐蔽的 .git 文件夹。留意,这个 .git 文件夹不属于工作区!它是独立于工作区的版本库本身。版本库就像你的“堆栈”或“档案室”,所有经过 commit 保存的版本都安全地存放在这里,随时可以追溯或规复。
工作区、暂存区、版本库的关系流程图解 (概念)
想象一下,它们之间的关系就像这样:
- +--------------+ +--------------+ +--------------+
- | 工作区 | ----> | 暂存区 | ----> | 版本库 |
- | (Working Dir)| | (Staging Area)| | (Repository) |
- +--------------+ +--------------+ +--------------+
- (你的办公桌) (准备提交的区域) (历史版本仓库)
- ^ ^ |
- | | |
- +---------------------+---------------------+
- (可以从版本库或暂存区恢复到工作区)
复制代码
- 你所有的文件修改都起首发生在工作区。
- 当你以为某一部分修改完成了,须要先 git add 把这些改动从工作区添加到暂存区。
- 当你以为暂存区里的内容(也就是你通过 git add 累积起来的所有改动)都准备好作为一个完整的历史版本保存时,须要 git commit 把暂存区的内容提交到版本库。
重点来了!
你仅仅在工作区新建了一个文件,大概修改了工作区里的文件,对于 Git 的版本库来说,它是不知道的!这些改动没有被 Git 跟踪起来。
通过新建或粘贴进⽬录的⽂件,并不能称之为向堆栈中新增⽂件,⽽只是在⼯作区新增了⽂件。必须要通过使⽤git add 和 git commit 命令才能将⽂件添加到堆栈中进⾏管理!!
要让 Git 开始管理这些文件和改动,你必须完成从工作区 -> 暂存区 -> 版本库 的这个流程,也就是依次利用 git add 命令和 git commit 命令!
将文件添加到堆栈进行管理:git add 和 git commit
明白了“三区”的概念,我们就知道 Git 跟踪和保存文件的基本步骤是:
- 在工作区对文件进行修改或新增。
- 利用 git add 命令将工作区的改动添加到暂存区。
- 利用 git commit 命令将暂存区的改动提交到版本库,形成一个新的历史版本。
下面我们通过现实操作来学习这两个命令。
场景一:第一次添加文件到堆栈
假设我们已经在 git init 过的项目文件夹里(也就是工作区),新建了一个 ReadMe 文件,并写了一些内容。
- # 确保你在 Git 仓库目录下
- zz@139-159-150-152:~/gitcode$ pwd
- /home/zz/gitcode
- # 使用 vim 或其他编辑器创建并编辑 ReadMe 文件
- # 比如输入两行内容:
- # hello bit
- # hello git
- zz@139-159-150-152:~/gitcode$ vim ReadMe
- # 查看 ReadMe 的内容(确认修改已完成)
- zz@139-159-150-152:~/gitcode$ cat ReadMe
- hello bit
- hello git
复制代码 现在,ReadMe 文件在我们的工作区里。要让 Git 跟踪它,我们须要先把它加到暂存区。
第一步:将文件添加到暂存区 (git add)
利用 git add 命令指定要添加的文件名:
- # 将 ReadMe 文件添加到暂存区
- zz@139-159-150-152:~/gitcode$ git add ReadMe
复制代码
- git add [文件名]:将指定文件的工作区改动添加到暂存区。
- git add [目录名]:将指定目录(包括子目录)下的所有改动都添加到暂存区。
- git add .:将当前目录下的所有改动(包括新增、修改、删除,但删除须要单独处理处罚或利用特定命令)都添加到暂存区。这是最常用的方式,表示“把我当前目录下所有 Git 知道有变革的文件的改动都放进暂存区”。
实行 git add ReadMe 后,ReadMe 文件的当前状态(包括内容和存在)就被放进了暂存区,它现在正安静地躺在你的“打包盒子”里,等待被提交。
第二步:将暂存区内容提交到版本库 (git commit)
现在暂存区里有了 ReadMe 文件。我们可以用 git commit 命令把暂存区里的所有内容作为一个新的版本提交到版本库。
- # 提交暂存区的所有内容到版本库
- # -m 后面跟着的是本次提交的“说明信息”
- zz@139-159-150-152:~/gitcode$ git commit -m "commit my first file"
复制代码
- git commit -m "你的提交信息":提交暂存区中的所有内容到版本库。-m 参数非常重要,背面跟着的是本次提交的日志
消息(message)。这个消息是给你本身和未来的协作者看的,要清晰地说明这次提交“做了什么”。这部分内容绝不能省略,也务必好好形貌!
- git commit [文件名1] [文件名2] ... -m "你的提交信息":提交暂存区中指定文件的内容到版本库(但通常我们是提交暂存区的全部内容,以是第一个命令更常用)。
实行 git commit -m "commit my first file" 后,Git 会把你暂存区里所有的改动(这里就是新增的 ReadMe 文件内容)打包,生成一个唯一的版本号(commit id),然后永世地存储到版本库里。
Git 会给出提交成功的反馈信息:
- [master (root-commit) c614289] commit my first file # [分支信息] commit id 的前几位] 提交信息
- 1 file changed, 2 insertions(+) # 本次提交涉及1个文件,新增了2行内容
- create mode 100644 ReadMe # ReadMe 文件被创建,权限模式是 100644
复制代码 这说明你的 ReadMe 文件已经成功地作为你的第一个版本,被 Git 永世保存起来了。
明白多次 add,一次 commit:
你可能会想,假如我改了好几个文件,是不是要 add 一次就 commit 一次?不是的!
你可以多次利用 git add 命令,将差别时间修改好的、准备一起提交的文件或改动,连续地添加到暂存区。当你以为所有这次要一起保存的改动都进了暂存区后,末了只需实行一次 git commit 命令,Git 就会把暂存区里的所有内容,作为一个完整的、单一的版本提交到版本库。
例如,我们再创建并添加三个空文件 file1, file2, file3:
- # 在工作区创建三个新文件
- zz@139-159-150-152:~/gitcode$ touch file1 file2 file3
- # 逐个或批量添加到暂存区
- zz@139-159-150-152:~/gitcode$ git add file1
- zz@139-159-150-152:~/gitcode$ git add file2
- zz@139-159-150-152:~/gitcode$ git add file3
- # 或者直接 git add . 把当前目录下的所有新增文件都加进去
- # 一次性提交暂存区里所有待提交的内容(file1, file2, file3)
- zz@139-159-150-152:~/gitcode$ git commit -m "add 3 files"
- [master 23807c5] add 3 files # Git 生成了新的 commit id
- 3 files changed, 0 insertions(+), 0 deletions(-) # 本次提交涉及 3 个文件,没有增删行(因为是空文件)
- create mode 100644 file1 # file1 被创建
- create mode 100644 file2 # file2 被创建
- create mode 100644 file3 # file3 被创建
复制代码 这次提交就包含了这三个文件。这再次印证了 commit 提交的是暂存区的内容。
查看提交历史:git log
每次 git commit 都会在版本库中留下一个永世的历史记录。我们可以利用 git log 命令来查看这些记录。
- zz@139-159-150-152:~/gitcode$ git log
- commit 23807c536969cd886c4fb624b997ca575756eed6 (HEAD -> master) # 最新提交的 commit id,以及 HEAD 和 master 分支的指向
- Author: zz91 <2689241679@qq.com> # 作者信息
- Date: Sat May 6 11:27:32 2023 +0800 # 提交日期和时间
- add 3 files # 提交时填写的消息(message)
- commit c61428926f3853d4ec6dde904415b0e6c1dabcc6 # 上一个提交的 commit id
- Author: zz91 <2689241679@qq.com>
- Date: Sat May 6 11:25:50 2023 +0800
- commit my first file
复制代码 git log 命令会按照提交时间的倒序(近来的提交在最上面)表现所有的提交记录。你可以看到每个提交的唯一 ID、作者、时间以及提交时填写的消息。
假如以为输出信息太多,可以加上 --pretty=oneline 参数,让信息更简洁:
- zz@139-159-150-152:~/gitcode$ git log --pretty=oneline
- 23807c536969cd886c4fb624b997ca575756eed6 (HEAD -> master) add 3 files # commit id 和提交信息
- c61428926f3853d4ec6dde904415b0e6c1dabcc6 commit my first file # 上一个 commit id 和提交信息
复制代码 明白 Commit ID:
git log 中看到的那一长串字母和数字组合(比如 23807c5... 和 c614289...),就是每次提交的 Commit ID(版本号)。
它不是简单的 1, 2, 3 递增序号,而是 Git 利用 SHA1 这种加密算法,根据本次提交的内容(包括文件的改动、提交者、时间、父提交等信息)计算出来的一个唯一的哈希值。即使你在差别的电脑上提交相同的内容,生成的 Commit ID 也会是一样的。它是 Git 用来引用某个特定版本的“身份证号”。通常我们只须要利用它的前几位(一般是 7-8 位)就可以唯一标识一个提交了。
(进阶明白)提交后的 .git 目录变革
为了帮助你更深刻地明白 Git 是如何工作的,我们可以再次 peek 一下 .git 目录里的变革。在我们实行了几次 add 和 commit 后,.git 目录会变得更“丰满”。
- zz@139-159-150-152:~/gitcode$ tree .git/
- .git/
- ├── branches
- ├── COMMIT_EDITMSG # 最近一次 commit 的消息
- ├── config # 仓库配置文件
- ├── description
- ├── HEAD # 指向当前分支(如 master/main)
- ├── hooks # 钩子脚本目录
- ├── index # **就是暂存区的文件!git add 会修改它!**
- ├── info
- │ └── exclude # Git 忽略文件配置
- ├── logs # 记录 HEAD 和分支的移动历史
- │ ├── HEAD
- │ └── refs
- │ └── heads
- │ └── master
- ├── objects # **Git 存放所有对象的地方(文件内容、目录树、提交等)!**
- │ ├── 23 # 根据对象 ID 前两位命名的文件夹
- │ │ └── 807c536969cd886c4fb624b997ca575756eed6 # 最新 commit 对象
- │ ├── 83
- │ │ └── 0a8c9feefbdc098bbae2cdc25e5034ce1920d7 # 一个 tree 对象 (目录树快照)
- │ ├── 8f
- │ │ └── add50161b6fafa53ce7e79d278dc490240c946 # 可能是一个 blob 或 tree 对象
- │ ├── 9c
- │ │ └── 9e1f0f6bff3015df71a0963004476f5e6cfd54 # ReadMe 文件的 blob 对象 (内容)
- │ ├── c6
- │ │ └── 1428926f3853d4ec6dde904415b0e6c1dabcc6 # 第一个 commit 对象
- │ ├── e6
- │ │ └── 9de29bb2d1d6434b8b29ae775ad8c2e48c5391 # file1/file2/file3 的 blob 对象 (内容)
- │ ├── info
- │ └── pack # 优化存储的对象打包文件
- └── refs # 存放指向 commit 的引用,如分支和标签
- ├── heads # 分支引用存放处
- │ └── master # master 分支引用,里面存着 master 分支最新提交的 commit id
- └── tags # 标签引用存放处
- # 注意:你的 objects 目录下的文件夹和文件可能不同,因为它们是根据你的具体提交内容生成的。
复制代码 这里面有几个关键文件/目录,和我们的操作密切相干:
- .git/index: 这就是暂存区!每次实行 git add 命令,Git 都会更新这个文件,记录下当前暂存区的文件状态和对应的对象信息。
- .git/HEAD: 这是一个指针,默认环境下,它指向你当前地点的分支(比如 master 或 main)。
- # 查看 HEAD 指向
- zz@139-159-150-152:~/gitcode$ cat .git/HEAD
- ref: refs/heads/master # 表示 HEAD 指向 refs/heads/master
复制代码
- .git/refs/heads/master: 这是一个文件,它里面保存着 master 分支最新一次提交的 commit id。
- # 查看 master 分支指向的 commit id
- zz@139-159-150-152:~/gitcode$ cat .git/refs/heads/master
- 23807c536969cd886c4fb624b997ca575756eed6 # 这就是我们上面 git log 看到的最新 commit id
复制代码
- .git/objects/: 这是 Git 的对象数据库,Git 存储所有版本数据的核心区域!每次 git add,Git 会把工作区的文件内容压缩并存入这里,生成一个 blob 对象;每次 git commit,Git 会根据暂存区的内容,生成一个 tree 对象(代表当时的目录结构)和一个 commit 对象(包含作者、时间、message,以及指向 tree 对象和父 commit 对象)。你看到的 objects 目录下以 commit id 前两位命名的文件夹里,就存放着这些对象。
以是上图现实上还有一个文件夹作为逻辑上的中心层:对象库
Git 利用 SHA1 哈希值作为对象的 ID。你可以利用 git cat-file -p [对象ID] 命令来查看 Git 对象库中某个对象的内容。
例如,查看最新的 commit 对象(利用上面 git log 或 .git/refs/heads/master 看到的 commit id):
- zz@139-159-150-152:~/gitcode$ git cat-file -p 23807c536969cd886c4fb624b997ca575756eed6
- tree 830a8c9feefbdc098bbae2cdc25e5034ce1920d7 # 这个 commit 对应的目录树对象 ID
- parent c61428926f3853d4ec6dde904415b0e6c1dabcc6 # 这个 commit 的父提交 ID(上一个版本)
- author zz91 <2689241679@qq.com> 1683343652 +0800 # 作者信息
- committer zz91 <2689241679@qq.com> 1683343652 +0800 # 提交者信息
- # 这是本次提交的消息
- add 3 files
复制代码 再查看上面 commit 对象里指向的 tree 对象(利用 tree 背面的 ID):
- zz@139-15 Confusion - git diff vs git diff --staged? (added, modified, deleted files) - Stack Overflow https://stackoverflow.com/questions/3878338/git-diff-vs-git-diff-staged-added-modified-deleted-files
- ```git diff` shows the difference between the *working directory* and the *staging area*.
- `git diff --staged` shows the differences between the *staging area* and the *last commit*.`
- The provided text *only* mentions `git diff [file]` (which compares working dir to staging) and `git diff HEAD -- [file]` (which compares working dir to last commit). It *doesn't* mention `git diff --staged`.
- To stick strictly to the text, I should *only* explain `git diff [file]` (WD vs Stage) and `git diff HEAD -- [file]` (WD vs HEAD/Repo). However, for beginner understanding, clearly explaining the three comparisons (`WD vs Stage`, `Stage vs Repo`, `WD vs Repo`) is very helpful.
- Let's clarify based on standard Git usage and the provided text:
- * `git diff` (without file): By default, compares Working Dir and Staging Area.
- * `git diff [file]`: Compares the *specific file* in the Working Dir and Staging Area. (This matches the text's example).
- * `git diff --staged` (or `--cached`): Compares Staging Area and the last commit. (Not in text, but a crucial comparison).
- * `git diff HEAD` (without file): Compares Working Dir and the last commit.
- * `git diff HEAD -- [file]`: Compares the *specific file* in the Working Dir and the last commit. (This matches the text).
- Okay, I will explain `git diff [file]` as comparing Working Dir and Staging Area (as the text implies by the context of needing `git add` afterwards). I will also explain `git diff HEAD -- [file]` as comparing Working Dir and the last commit (as the text states). I will *not* introduce `git diff --staged` as it's not in the provided content, even if it's conceptually useful. I need to explain what the diff output format means simply.
- Let's refine the "修改文件" section based on this.
- **Refined Drafting - Modifying Files:**
- * Start with modifying ReadMe.
- * Introduce `git status` - explain it shows the state relative to Staging and Repository. Show output "Changes not staged for commit". Explain this means "Working Dir has changes compared to Staging Area".
- * Introduce `git diff [file]` - explain it shows *what* those unstaged changes are. Show output. Explain the `+` (added lines) and `-` (removed lines). State it compares Working Dir and Staging Area.
- * Mention `git diff HEAD -- [file]` as another diff command, comparing Working Dir and the *last commit* in the Repository. Explain why you might use it (see differences since the *last saved version*).
- * Show `git add ReadMe` - explain it moves the *modified* `ReadMe` from Working Dir to Staging Area.
- * Show `git status` again - output should be "Changes to be committed". Explain this means "Staging Area has changes ready to be committed".
- * Show `git commit -m "..."` - explain it saves the Staging Area to the Repository.
- * Show final `git status` - output "nothing to commit, working tree clean". Explain this means Working Dir and Staging Area match the last commit.
- This flow directly uses the provided commands and explanations while clearly linking them back to the three areas and the state changes.
- Let's integrate this refined section into the overall structure.
- 59-150-152:~/gitcode$ git cat-file -p 830a8c9feefbdc098bbae2cdc25e5034ce1920d7
- 100644 blob 9c9e1f0f6bff3015df71a0963004476f5e6cfd54 ReadMe # ReadMe 文件,类型是 blob,这是它的对象 ID
- 100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 file1 # file1 文件,类型是 blob,这是它的对象 ID
- 100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 file2 # file2 文件
- 100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 file3 # file3 文件
复制代码 这个 tree 对象记录了在 23807c5... 谁人提交时,项目根目录下有哪些文件和文件夹,以及它们各自对应的对象 ID。这里可以看到 ReadMe, file1, file2, file3 都指向了各自的内容对象。
末了,我们查看 ReadMe 文件对应的 blob 对象(利用上面看到的 9c9e1f0f6bff3015df71a0963004476f5e6cfd54 ID):
- zz@139-159-150-152:~/gitcode$ git cat-file -p 9c9e1f0f6bff3015df71a0963004476f5e6cfd54
- hello bit
- hello git
- # 这就是 ReadMe 文件在那个提交时的实际内容!
复制代码 通过这个探索,我们可以看到 Git 如何在 objects 目录下存储文件的现实内容(blob 对象)、目录结构(tree 对象)以及提交信息(commit 对象),并且通过 Commit ID 将它们关联起来。每次 git add 和 git commit 都会在这个对象库中创建新的对象。这有助于我们明白 Git 是如何保存项目历史的。
总结 .git 内部的几个重要部分:
- index: 暂存区的现实文件,git add 的结果保存在这里。
- HEAD: 指向当前地点分支(默认是 master 或 main)的指针。
- refs/heads/master: 一个文件,里面存储着 master 分支最新提交的 commit id。
- objects: Git 的对象数据库,存放所有 Git 管理的对象(文件内容、目录树、提交等)。
在今后的学习中,试着将常用的 Git 命令和 .git 目录内部的变革接洽起来,每次操作后都进行追念“这时候目录内部的操作”,可以帮助你更深刻地明白 Git 的工作原理。
场景二:再次明白 add 和 commit 的配合
为了加深对工作区、暂存区、版本库以及 add 和 commit 命令关系的明白,我们再看一个例子:
- # 1. 在工作区新增 file4 文件
- zz@139-159-150-152:~/gitcode$ touch file4
- # 2. 将 file4 添加到暂存区(它现在进入了打包盒子)
- zz@139-159-150-152:~/gitcode$ git add file4
- # 3. 紧接着,在工作区又新增了 file5 文件(它还在办公桌上)
- zz@139-159-150-152:~/gitcode$ touch file5
- # 4. 提交修改(Git 会提交暂存区的内容)
- zz@139-159-150-152:~/gitcode$ git commit -m"add file"
- [master 3d406c0] add file
- 1 file changed, 0 insertions(+), 0 deletions(-)
- create mode 100644 file4
复制代码 看提交结果,Git 告诉我们只有 1 file changed (file4)!这是怎么回事?我们明明新增了两个文件 (file4 和 file5) 啊?
原因: 回忆一下我们前面说的,git commit 提交的是暂存区里的内容。在实行 git commit 命令时:
- file4 已经通过 git add file4 被添加到了暂存区。
- file5 固然在工作区被创建了,但我们没有对它实行 git add file5,以是它还在工作区,没有进入暂存区。
因此,git commit 时只看到了暂存区里的 file4,就把 file4 提交了,而完全忽略了还在工作区的 file5。
如何提交 file5 呢? 非常简单,按照流程来:先 git add file5 把 file5 加到暂存区,然后再 git commit 一次。
这个例子再次夸大用 commit 提交的是暂存区,而不是工作区!在你 commit 之前,肯定要确保所有想提交的改动都已经通过 git add 进入了暂存区。
修改文件并提交:git status 和 git diff
除了新增文件,修改已有文件是更常见的操作。Git 在这方面设计得非常高效,由于它跟踪并管理的是文件的修改,而不是整个文件。
“修改”可以有许多种:在你文件中新增一行、删除一行、更改几个字符、甚至改变文件名等等,Git 都能识别为“修改”。
让我们来修改一下之前创建的 ReadMe 文件:
- # 查看 ReadMe 的当前内容
- zz@139-159-150-152:~/gitcode$ cat ReadMe
- hello bit
- hello git
- # 修改 ReadMe 文件,比如增加一行
- # hello bit
- # hello git
- # hello world
- zz@139-159-150-152:~/gitcode$ vim ReadMe
- # 再次查看修改后的内容
- zz@139-159-150-152:~/gitcode$ cat ReadMe
- hello bit
- hello git
- hello world
复制代码 现在,工作区里的 ReadMe 文件内容和版本库中最新提交的 ReadMe 内容已经不一样了。Git 怎么知道哪些文件被修改了呢?
查看工作区状态:git status
git status 命令是利用 Git 过程中最最常用的命令之一!它用于查看你当前工作区和暂存区的状态,告诉你哪些文件有改动,这些改动处于哪个阶段(在工作区还是暂存区)。
- # 查看 Git 仓库状态
- zz@139-159-150-152:~/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: ReadMe
- no changes added to commit (use "git add" and/or "git commit -a")
复制代码 git status 的输出信息告诉我们:
- On branch master: 你当前在 master 分支上(分支概念背面会讲)。
- Changes not staged for commit:: 工作区有改动,但这些改动还没有添加到暂存区(还没有 add)。
- modified: ReadMe: ReadMe 文件被修改了。
- no changes added to commit: 暂存区是空的,没有任何准备要提交的内容。
这个状态说明:你修改了 ReadMe 文件,但 Git 只是知道它被改了,还没有把这个改动记录到暂存区,更没有提交到版本库。它还在你的“办公桌”上。
查看具体修改内容:git diff
git status 告诉我们文件被修改了,但具体改了哪些地方呢?这就须要用到 git diff 命令。
git diff 命令默认环境下,是用来查看工作区与暂存区之间文件差异的。
- # 查看 ReadMe 文件在工作区和暂存区之间的差异
- zz@139-159-150-152:~/gitcode$ git diff ReadMe
- diff --git a/ReadMe b/ReadMe
- index 9c9e1f0..4a97140 100644
- --- a/ReadMe # Diff 比较的“旧”文件(暂存区或最新提交的版本)
- +++ b/ReadMe # Diff 比较的“新”文件(工作区的文件)
- @@ -1,2 +1,3 @@ # 表示在原文件的第1行开始的2行,和新文件的第1行开始的3行之间有差异
- hello bit
- -hello git # 减号开头的行表示在旧版本有,在新版本被删除了
- +hello git # 加号开头的行表示在旧版本没有,在新版本被增加了
- +hello world # 加号开头的行表示在新版本被增加了
复制代码 git diff 的输出利用了尺度的 diff 格式:
- 以 --- a/ 开头表示比较的“旧”文件(通常是暂存区或上一个版本的)。
- 以 +++ b/ 开头表示比较的“新”文件(通常是工作区当前的)。
- @@ ... @@ 之间的信息表示差异发生的位置。
- 以 - 开头的行表示这行在旧版本有,但在新版本被删除了。
- 以 + 开头的行表示这行在旧版本没有,但在新版本被新增了。
通过 git diff ReadMe,我们清晰地看到在工作区,我们在 hello git 背面新增了一行 hello world,并且固然 hello git 本身内容没变,但由于上面的行删除了,这里表现似乎是删了又加了(Git 以为行号变了也算改动,大概这里的 diff 算法是按行匹配)。但重点是,你能清晰地看到 hello world 是新增的。
另一个常用的 diff 比较:工作区与版本库最新提交的差异
假如你想直接看工作区的文件和版本库里最新提交的版本有什么差别,可以利用 git diff HEAD -- [文件名] 命令:
- # 查看工作区 ReadMe 文件和版本库最新提交版本 ReadMe 文件的差异
- git diff HEAD -- ReadMe
复制代码 这个命令会比较你当前工作区的状态和 HEAD 指针指向的谁人提交(也就是当前分支的最新版本)的文件状态。了解这个有助于你区分工作区和暂存区在 diff 命令中的差别作用。
提交修改后的文件
现在我们知道了 ReadMe 被修改了,并且通过 git diff 确认了修改内容。接下来,按照流程,把这个修改也保存到版本库中。
第一步:将修改添加到暂存区 (git add)
固然文件是修改,不是新增,但流程一样,还是要先 add 到暂存区:
- zz@139-159-150-152:~/gitcode$ git add ReadMe
复制代码 实行 git add ReadMe 后,ReadMe 文件在工作区里的修改就被添加到了暂存区。暂存区里现在包含了 ReadMe 文件修改后的新内容。
再次查看状态 (git status):
现在 ReadMe 的修改已经在暂存区了,我们再看看状态:
- zz@139-159-150-152:~/gitcode$ git status
- On branch master
- Changes to be committed:
- (use "git restore --staged <file>..." to unstage)
- modified: ReadMe
复制代码 这次的输出变了!ReadMe 文件出现在了 Changes to be committed: 这个区域下,并且前面表现 modified: ReadMe。这表明 ReadMe 文件在暂存区里有改动,这些改动已经准备好被提交到版本库了。
第二步:将暂存区内容提交到版本库 (git commit)
暂存区里有内容了,我们就可以实行 commit 命令来保存这个修改版本了:
- # 提交暂存区的修改到版本库,并写上提交信息
- zz@139-159-150-152:~/gitcode$ git commit -m "add modify ReadMe file"
- [master 94da695] add modify ReadMe file
- 1 file changed, 2 insertions(+), 1 deletion(-) # 这次修改的结果:1 个文件改动,增加了 2 行,删除了 1 行
复制代码 提交成功!ReadMe 文件的这次修改已经被作为一个新的版本永世保存在版本库里了。
末了查看状态 (git status):
提交完成后,工作区和暂存区都应该是干净的(和版本库最新提交的状态一致)。
- zz@139-159-150-152:~/gitcode$ git status
- On branch master
- nothing to commit, working tree clean
复制代码 nothing to commit, working tree clean:这说明当前工作区和暂存区都没有任何须要提交的改动,它们的状态是干净的,和版本库里最新的版本是同步的。这是一个很好的状态!
总结一下 Git 的基本操作流程
通过上面的学习,我们现在对 Git 的基本操作流程有了清晰的认识:
- 在工作区里工作: 新建、编辑、删除文件。
- 查看状态: 经常利用 git status 查看工作区和暂存区的状态,了解哪些文件有改动,它们处于哪个阶段。
- 查看具体改动: 利用 git diff [文件名] 查看工作区里的文件相对于暂存区的具体修改内容。
- 将改动添加到暂存区: 利用 git add [文件名] 或 git add . 将工作区中准备提交的改动放入暂存区。
- 提交暂存区的改动: 利用 git commit -m "有意义的提交信息" 将暂存区的内容作为一个新版本提交到版本库。
- 查看历史: 利用 git log 查看已经提交的版本历史。
明白工作区 -> 暂存区 -> 版本库 这个流程,以及 git add 和 git commit 在其中扮演的角色,是把握 Git 的关键。每次改动都须要经过 add 和 commit 两步(或类似操作)才能真正被 Git 永世记录下来。
接下来,我们将继续学习 Git 的其他常用操作,比如如何回退版本,如何忽略文件等等。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |