Unsplash
Photo by Arnold Exconde on Unsplash

Contents
  1. 1. 前言
  2. 2. 工作区、暂存区(stage)和版本库(Repository)
    1. 2.1. 查看可以加入暂存区的文件
    2. 2.2. 将工作区文件加入暂存区
    3. 2.3. 将暂存区修改提交到分支
    4. 2.4. 查看暂存区文件
    5. 2.5. 修改暂存区文件(不影响工作区)
    6. 2.6. 修改暂存区文件(并重置工作区)
    7. 2.7. 验证
  3. 3. 关于gitignore
  4. 4. 总结
  5. 5. 下一步
  6. 6. Reference

前言

通过前几周对git的研究和探索,工作步入正轨。在实际使用过程中,发现对于工作区、暂存区和HEAD之间的关系有些迷茫。使用一些零散时间将Gooogle到的信息以及自己的测试结果整合一下。

工作区、暂存区(stage)和版本库(Repository)

  1. 工作区就是本地电脑中能看到的目录
  2. 版本库包含暂存区和分支,master也是一个分支,HEAD是指向master分支的游标

查看可以加入暂存区的文件

git status
-s 表示精简模式以前标M/D/A来区分修改/删除/新增的文件
-b 同时显示分区名称

将工作区文件加入暂存区

git add .将工作区所有修改添加到暂存区
git add FILE_NAME将工作区单个修改的文件添加到暂存区

将暂存区修改提交到分支

git commit -m "MSG"一次性把暂存区的所有修改提交到当前分支
假如提交成功,命令行应显示如下

1
2
3
$ git commit -m "SOME_MSG"
[BRANCH_NAME 53c0744]
3 files changed, 13 insertions(+), 4 deletions(-)

提交完成后,暂存区就干净了,可运行git status查看,在提交成功的状态下,status应显示如下

1
2
3
$ git status
On branch BRANCH_NAME
nothing to commit, working tree clean

查看暂存区文件

git diff --cached --name-only对比暂存区和HEAD(当前分支最新提交)之间的文件差异(git add添加的文件)
git diff HEAD对比工作区和HEAD(当前分支最新提交)之间的文件差异
git diff对比工作区与暂存区之间的文件差异
–name-only表示只显示文件名

修改暂存区文件(不影响工作区)

git reset HEAD清空暂存区目录树
git rm --cached FILE_NAME删除暂存区单个文件

修改暂存区文件(并重置工作区)

git reset --hard HEAD此操作在情况暂存区目录树的同时,会将工作区还原到HEAD状态

验证

  1. 先建一个分支test
  2. 修改分支内任意一个文件
    git status -s red M
  3. case1:记录未将工作区修改的文件添加至暂存区的状态
    3.1 使用git diff查看工作区与暂存区之间的文件差异

    3.2 使用git diff HEAD查看工作区与HEAD之间的文件差异

    3.3 使用git diff --cached查看暂存区与HEAD之间的文件差异
  4. 执行git add .后进行git status -s查看
    git status -s green M
  5. case2:记录将工作区修改的文件添加至暂存区后的状态
    5.1 使用git diff查看工作区与暂存区之间的文件差异

    5.2 使用git diff HEAD查看工作区与HEAD之间的文件差异

    5.3 使用git diff --cached查看暂存区与HEAD之间的文件差异
  6. 使用git reset HEAD来重置暂存区目录树

    6.1 接着运行status和三条命令,会发现和case1一样
  7. 执行add将工作区修改重新提交到暂存区后,使用git reset HEAD --hard来重置工作区修改和暂存区目录树

    7.1 再运行status和三条命令,会发现所有的命令运行结果都是空,因为--hard参数将HEAD覆盖到了工作区,所有的修改都没了,而且无法挽回,所以慎用

关于gitignore

gitignore不能忽略已经track的文件

NAME
gitignore - Specifies intentionally untracked files to ignore
DESCRIPTION
A gitignore file specifies intentionally untracked files that Git should ignore. Files already tracked by Git are not affected; see the NOTES below for details.

有时项目中会把node_modules或temp或runtime之类的目录加入版本管理,都是陈年历史,创项目时就加进去了,一般也不会专门提交个commit把他们去除。
此处有两种做法,经测(git2.12.1)有效:

  1. git ls-files -z UNTRACK_DIR | xargs -0 git update-index --assume-unchanged更新目录树,将文件夹内所有文件假设为未改变
    1.1 git update-index --assume-unchanged FILE_NAME更新目录树,将单个文件假设为未改变
  2. git rm --cached -r UNTRACK_DIR下定决心将文件夹移出目录树(需要提交)
    假如用了第一种做法,之后需要将文件或文件夹取消假设,只需:
    git update-index --no-assume-unchanged FILE_NAME移除假设标签

总结

利用碎片时间的研究,并花了一整天进行知识梳理和实际试验,对Git的工作区、暂存区之间的关系有了进一步的了解。

下一步

(预留)向Git前进 | rebase

Reference

Git学习笔记(三) Git暂存区 - agul
git如何ignore已经track的文件 - sabrinaluo
工作区和暂存区 - liaoxuefeng

Contents
  1. 1. 前言
  2. 2. 工作区、暂存区(stage)和版本库(Repository)
    1. 2.1. 查看可以加入暂存区的文件
    2. 2.2. 将工作区文件加入暂存区
    3. 2.3. 将暂存区修改提交到分支
    4. 2.4. 查看暂存区文件
    5. 2.5. 修改暂存区文件(不影响工作区)
    6. 2.6. 修改暂存区文件(并重置工作区)
    7. 2.7. 验证
  3. 3. 关于gitignore
  4. 4. 总结
  5. 5. 下一步
  6. 6. Reference