最近开始学习使用版本控制工具 git .学习方式主要通过阅读 git 网站上的 Pro git 和动手实践,使用的系统为 Ubuntu16.04LTS,以及 Windows 8.1. 本文主要关注 git 进行本地文件追踪的文件状态变化、如何进行文件的修改和提交等关于本地文件操作的部分,即使用 git 进行本地仓库管理和使用的操作和方法。
注:这里对原来的一篇内容进行了拆分,主要是原始的博文内容过多且有点混杂.关于 git 中仓库/文件状态等基本概念的内容参见本文章,关于 git 的修改/提交等基本操作的记录见.
注:本文主要记录作者阅读 Pro git 的前两节的笔记。部分内容为对应内容的直接翻译。
内容目录
git 的三种工作域
git 目录:git directory,是 git 存放数据和信息的地方,亦即仓库( repository ),保存项目所有版本和相关信息的位置。用户在进行克隆( clone )操作是就是对 git 目录(仓库)的操作;
工作目录:working directory,是对应项目的某个版本的文件集合,对应从 git 目录中解压出来的供用户进行操作和修改的数据和信息;
暂存区域 :staging area,为记录下一次提交时需要保存的文件列表信息的文件;
git 管理的文件的三种状态
git 管理的文件存在以下三种文件状态:
committed:已提交状态,表示数据文件已经被保存至本地数据仓库中。
modified:修改状态,表示文件已被修改,但是尚未被提交(保存)。
staged:暂存状态,表示是被标记了的被修改文件,在下次提交时会将所有标记过的修改保存。
对应上述的三种文件状态可知,若文件已经存在于 git 目录(仓库)中,则文件为已提交状态。若文件已被修改并记录至暂存区域,则文件处于暂存状态,用户提交时会提交处于此状态的修改。若文件仅仅只是被修改但未被标记为 staged,则为修改状态,且在下次提交时并不会保存其相关信息( 必须先进入暂存状态提交时才会保存 )。
文件的状态变化
在工作目录( working directory )中,存在两种状态的文件,tracked 和 untracked。tracked 文件是那些存在于上一次提交中的文件,即已经在 git 存在过记录的文件,这些文件可能又被修改过,也可能和上次提交时状态一致;Untracked文件则是工作目录下其他所有的文件,如上次提交后在目录中新建的文件等 。当第一次将仓库克隆至目录时,该目录所有文件均为 tracked 且均为未被修改的文件。
当前工作目录中可能存在的文件的状态变化图( 来自 git pro ):
可以通过命令 git status 来获取当前目录下文件的状态,其显示的结果主要通过以下几种标志状态描述:
Untracked files: 标志处于 untracked 状态的文件,git 不会主动将 Untracked 状态的文件转换为 staged 状态,需要用户通过 git add 命令显示的转化,避免提交不希望上传的文件;
Changes to be committed : 标志处于 staged 状态的文件,当进行提交时,上述文件的提交会被记录;
Changes not staged for commit: 标志那些被修改但并不处于 staged 状态的 tracked 文件,需要使用 git add 命令将其转换为 staged 状态;
一般情况下,使用命令 git add filename 将 filename 指定的文件或目录加入staged状态(从被修改的 tracked 文件或从 Untracked 文件),使用命令 git reset HEAD filename 可以将 filename 文件从 staged 状态中恢复至一般修改状态,使用命令 git commit 进行提交操作。
注意:提交的文件是处于 Changes to be committed 状态的文件,提交的内容为使用 git add 命令加入 staged 状态时的文件修改内容。即在使用 git add 命令后对相同文件的二次修改不会被提交,除非再次使用 git add 将修改后的文件加入 staged 状态。体现在 git status 命令中,若使用命令 git add a.c 之后再次对 a.c 文件进行了修改,则上述文件会同时出现在 Changes to be committed 和 Changes not staged for commit 描述中( 即存在同名条目 ),但具体的文件内容是不同的,而提交时只会提交处于 Changes to be committed 状态的条目,即之后的修改不会被提交。用户可通过 git status -s/--short 得到各文件状态的简要描述,参见这里。
获取 git 目录(仓库)
获取一个 git 仓库的方式主要有两种:
(1)将一个新的本地目录转化为 git 仓库。进入该目录,输入命令 git init ,git 会在当前目录下建立一个.git 目录,其中包含了所有必须的仓库的信息。该命令只是完成初始化过程,并没有产生提交,故而该仓库可以视为空。
(2)从其他地方克隆(clone)一个 git 仓库。使用命令 git clone 会将目标仓库的所有服务器上存放的文件( 包括各个版本和修改历史 )克隆至本地,同样存放在 .git 目录中,这一点与其他版本控制软件的 checkout (只获取特定需要的版本的项目)命令不同。
git clone <url> //获取url指向的仓库的内容
当用户使用 git clone https://github.com/project_name/project_name 命令获取一个 git 仓库时,git 会执行以下过程
a.在本地建立一个project_name目录,并在其中初始化一个.git目录;
b.获取将该仓库的所有文件,并将最近版本的工作文件解压放置至创建的 project_name 文件夹中供用户操作。
用户可在该指令后面加上目的文件夹名作为参数,如git clone https://github.com/xxx/xxx dir_name,则 git 会将该仓库文件放置至 dir_name 目录下。除了上述的 https 协议外,git 还支持 git:// 和 ssh 协议,具体可以查看官方文档。
注意:无论是使用 Linux 环境下的命令行还是通过 Windows 环境下的 Git bash,git 命令一般需要在 git 仓库目录中发挥作用,否则会出现报错 "fatal: not a git repository( or any of the parent directories ): .git"。故而当本地不存在 git 仓库时,可以选择 git clone 远端仓库,或通过 git init 初始化一个本地目录对应的仓库,并进入此目录,进行后续的 git 命令操作。
删除 git 仓库
从上面获取仓库的原理可以看到, 对 git 仓库的管理主要通过 .git 目录实现,删除 git 仓库的操作可以通过删除 .git 目录操作完成。
(1) 在 Linux 命令行或者 Windows 的 Git bash 环境下,在 git 仓库目录中使用命令 ls -a 会显示当前目录下所有文件和目录,此时会显示存在 .git 目录;
(2) 通过命令 rm -rf .git/ 删除当前文件夹下的 .git 目录;
(3) 此时当前目录即从一个 git 仓库变为一个普通目录,在 Git bash 环境中可以看到路径名后面不再显示分支名称了;
参考和学习资源: