最近开始学习使用版本控制工具  git .学习方式主要通过阅读 git 网站上的 Pro git 和动手实践,使用的系统为 Ubuntu16.04LTS,以及 Windows 8.1. 本文主要关注 git 进行本地文件追踪的文件状态变化、如何进行文件的修改和提交等关于本地文件操作的部分,即使用 git 进行本地仓库管理和使用的操作和方法。

  注:本文主要记录作者阅读 Pro git 的前两节的笔记。部分内容为对应内容的直接翻译。

  内容目录

    1git 基本概念

    2.git 获取/删除仓库

    3.git 本地操作命令

      3.1 git status

      3.2 git add

      3.3 git commit

      3.4 git rm

      3.5 git log

      3.6 git diff

    4.git 设置

一. 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 目录(仓库)

  获取一个 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 环境中可以看到路径名后面不再显示分支名称了;

三. git 本地操作命令

  git status —— 查看文件状态

  通过 git status 查看当前目录下各个文件的状态。git status 还会给出各种状态下文件可以使用的操作指令。

      git status          //查看当前文件夹下各个文件的状态
  git status -s //查看各文件状态,使用字母简单表示文件状态

  一个 git 仓库下文件的状态主要有 (对应上文的介绍看):

  Untracked files : 对应并未被 git 追踪记录的文件,当通过 git init 初始化一个目录时,是初始化了一个空的 git 目录,所有该目录下的文件均处于未被 git 追踪记录的状态。新建文件的状态也属于此类;

  changes not staged for commit : 仅限于已经被 git 追踪记录( tracked )的文件。若这些文件发生了修改,但还没有被通过 git add 加入需要进行提交的状态( staged ),则处于此状态;

  changes to be committed : 仅限于已经被 git 追踪记录( tracked )的文件。当这些文件发生了修改,且已经通过 git add 加入需要进行提交的状态,则处于此状态。通过 git commit 提交的修改即为处于该状态的文件的修改;

  笔者进行实践时新建 test 目录,其中仅包含一个 hello.cpp 文件,在通过 git init 初始化后,即生成一个空的 git repository,git status 的结果如下图,可以看到此时的 hello.cpp 处于 Untracked 状态。

  

  git add —— 添加文件至待修改状态

  通过 git add 添加文件至待提交的状态( changes to be committed )。git add 主要有两个功能: a.将未被 git 追踪记录( untracked )的文件"加入" git 仓库的记录中; b.将处于 changes not staged for commit 状态下的文件的修改添加至需要进行提交的状态( staged )。这两个功能均会将文件变为 changes to be committed 状态。

      git add file-list        //将 file-list 指定的文件添加至 changes to be committed 状态
  git add . //将当前目录下所有的文件添加至 changes to be committed 状态

  用户可通过 git add 命令将当前目录下处于 untracked 状态下的文件"添加"至 git 仓库中。在笔者的实践中,即通过 git add hello.cpp 将 hello.cpp 加入 changes to be committed 状态,也可使用 git add . 命令将当前目录下所有文件变为 changes to be committed 状态。

  git commit —— 提交修改至仓库

  通过指令 git commit 提交所有处于 staged 状态的文件。注意使用上述命令只会提交使用 git add 命令标记为 staged 状态的文件

  通过指令 git commit 提交时 Git 会通过默认编辑器显示一个编辑界面,用户需编辑提交信息(commit message),用于标识该次提交。其中 # 开始的行表示注释,用户编辑结束退出后,Git会使用该提交信息创建新的提交(即生成新的快照)。默认的显示内容包括最近一次 git status 命令显示的结果(注释),使用提交时加入参数 -v 则会将 git diff 指令的结果也包含在显示内容中,用户可以通过取消注释或编辑新内容来修改提交信息( Ubuntu 系统下运行结果 )。

  用户也可以使用 git commit -m "commit message" 命令来直接指定提交信息,可用于提交流程更简洁的情况。

    git commit -m "test"        //使用提交信息 "test" 提交所有 staged 的修改
git commit --allow-empty //允许无内容的提交
git commit -am "test" //直接将所有被修改的文件提交,相当于先 git add 再 commit

  注意:git commit 保存的数据仅保存在本地仓库中,若需要同步至远端仓库,需要使用 git 支持的远程仓库操作。同时,第一次使用 git commit 进行提交时需要设置好用户的用户名和邮箱,可以查看后文的 git 设置部分。

  

  git rm —— 删除对文件的追踪

  在 git 中,删除一个文件包括取消文件的 tracked 状态,之后再进行提交,可通过命令 git rm 完成上述操作。更具体描述可以参考这里

  git rm a.c  会将文件a.c 删除,并将删除这个"修改"标记为 staged 状态。当使用 git commit 命令之后,a.c 文件就会从工作目录中消失,并不再为 tracked 状态。这样可以保证不会在之后的操作中将该文件视为 untracked 文件再次进行处理。

  注意:常规的删除操作如 rm,会使得删除的文件处于 Changes not staged for commit 状态,而 git rm 的删除操作使得被删除文件处于 Changed to be commited 状态。对于后者,用户提交之后,被删除的文件之后不再被 git 记录,而前者由于并不会被提交,会一直保持该状态。

  对于已经修改并被加入staged状态的文件来说,通过 git rm 删除该文件需要使用 -f 参数,以避免删除 git 尚未记录的文件和其他误操作。

  使用参数 git rm --cached xxx 可以使得文件不再被 git 记录,但继续存在于工作目录下,作用与 .gitignore 文件类似。

  

  git log —— 查看提交历史

  对于本地创建的或自其他仓库克隆的具有多次提交记录的项目,可以通过 git log 命令查看历史的提交记录。

  默认情况, git log 会根据提交顺序的逆序排列(即最近的提交最先显示), git log 会显示提交顺序及其对应的SHA-1哈希值,以及作者、邮箱、提交日期和提交信息等内容。

  

  git log 有一些常用的参数可以用于更精确的显示需要的内容。

      -p           //在 log 条目中加入每次提交的修改信息
  -n //仅显示最近的n个提交条目
  --stat //显示每次提交被修改的文件的信息
  --pretty=options //options可以为online、short等,也可以自行指定输出的格式信息,可以参考这里
  --graph //输出字符树的形式显示提交记录

  git diff —— 查看修改情况

  通过指令 git status 可以得知当前各个文件所处的状态(是否发生改变等),通过指令 git diff可以得知某一文件发生的怎样的改变。

  git diff                   //查看那些再次修改但尚未被staged的文件修改情况,如 git add a.c 命令之后,再次对 a.c 所做的(而又未被staged)的修改
  git diff --stage       //查看当前staged状态下的文件较之原始(未修改状态下,也就是上一次提交时)的文件的修改情况
  git diff commit1 commit2 //比较两次提交之间的差别

  git diff 会将当前工作目录下的文件与处于staged状态的文件进行比较,并将差异结果显示出来。可以视为显示自上一次 git add 后进行的修改情况。

  git diff --stage会将当前处于staged状态的文件与上一次提交的结果进行比较,并将结果显示出来。可以视为显示自上一次 git commit 后进行的修改情况。

  注意:指令 git diff 只会显示还未被staged的修改,即之前已经通过 git add 命令加入staged状态的修改是不被显示的。使用参数 --staged或--cached显示当前已经处于staged状态的修改,即与上一次提交进行比较的结果。

  撤销与修改操作

  (1)针对提交过程:若发现存在部分文件未正确提交(未加入 staged 状态)或提交信息有疏漏,可以先将需要补充提交的文件加入 staged 状态,再使用 git commit --amend 命令,则本次提交会取代上一次的提交,在此过程中,也可以修改提交信息;

  (2)针对 staged 状态的文件:使用命令 git reset HEAD filename 可以将 filename 文件从 staged 状态中恢复至一般修改状态;

  (3)针对已经修改的文件:若想要将已经修改的文件恢复至未修改的状态,可以使用 git checkout --filename,则会将对应文件从之前的提交记录中恢复,而简单的丢弃对其的修改;

  事实上,通过 git status 命令获得当前工作目录中文件的状态信息时,针对每种文件状态会有相应的 git 操作提示。用户可以直接使用 git status 命令查看特定的文件类型如何进行操作。

  其他

  (1)跳过 staged area 状态:在命令 git commit 中加入 -a 参数,git 会直接将所有 tracked 文件提交,而不再需要使用 git add 将其转换为 staged 状态。

  (2)可创建一个 .gitignore 文件,来设置不需要 Git 进行显示和提交的文件(处理时直接忽略),最简单的 .gitignore 文件的写入就是每个文件/文件夹占一行,所有被包含在其中的内容都被 git 所忽略。具体的写法可参考这里

四. git 设置

  git 通过其携带的工具 git config 来对修改配置变量从而对应用进行个性化设置,个性化设置的变量可能会被存储在三个不同的位置,各自有着不同的作用域( Ubuntu 环境下目录结构 )。

    (1) /etc/gitconfig,全局的 git 变量设置。其中的设置会应用到系统所有用户和 git 仓库。通过 git config 的 --system 参数进行设置。

    (2) ~/.gitconfig或~/.config/git/config,用户个人的 git 变量设置,该设置应用于该用户的所有操作。通过 --global 参数进行设置。

    (3) git目录中的 config 文件(下文的.config目录中),记录对该 git 目录的一些配置变量。

  每一层设置的配置变量的值会覆盖上一层的设置值,故而 git 目录中的 config 文件中特定设置的效果会掩盖 /etc/gitconfig 中的对应的设置效果。

  设置个人信息

  设置个人有关的信息,包括用户名和 email,在进行提交之前,必须进行用户名和邮箱名的设置。这是与单个用户相关的设置,故而使用参数 --global。 

    git config --global user.name "xxx"
    git config --global user.email email_address

  设置默认编辑器   

    git config --global core.editor vim        //在 Ubuntu 环境下设置编辑器为 vim

  查看设置

  可以通过以下命令对 git 的配置参数进行查看

    git config --list           //查看当前已经设置的所有变量值,会从以上三个文件中读取,故而特定变量可能出现多次,其最后出现的值为 git 实际使用的值
    git config key_name //查看Git当前使用的特定变量的值,如 git config user.name

  git 帮助

  用户可以通过命令行方式获得帮助,包括如下命令,可以通过帮助信息和网络资源理解 git 相关命令的功能。 

    git help <action>      //如通过 git help config 来过得对config操作的相关帮助
    man git-行为名 //如通过 man git-config 来获得帮助
    git command -h //获得简略的帮助提示,如 git config -h

参考和学习资源:

    Git Handbook

    github-git-cheat-sheet, Github

    Pro Git,2nd edition

    Pro Git,中文版第二版

git 学习记录—— git 中的仓库、文件状态、修改和提交操作等的更多相关文章

  1. Git学习记录--git仓库

    Git是一款强大的版本控制工具,与svn相比git的分布式提交,本地仓库等在使用时确实比较方便.当然两者之间各有优劣,我在这里不多做比较.由于之前少有接触git,只是零星大致地了解一点,所以找时间系统 ...

  2. git学习——记录每次更新到仓库

    记录每次更新到仓库 工作目录下面的所有文件都不外乎这两种状态:已跟踪或未跟踪.已跟踪的文件是指本来就被纳入版本控制管理的文件,在上次快照中有它们的记录,工作一段时间后,它们的状态可能是未更新,已修改或 ...

  3. git杂记-记录每次更新到仓库

    git status 和 git diff的运用 git status 记录的是关于仓库文件是否有变更,例如是否被修改,是否被添加到暂村区.至于文件更改了什么内容该命令并不关心: git status ...

  4. Git学习记录 力做全网最强入门教程

    目录 Git学习记录 力做全网最强入门教程 什么是GitHub? 什么是Git? Git的配置 Git的安装(只介绍windos操作系统下) Git的配置 至此我们的入门教程到此结束,更新中级教程要等 ...

  5. Git 学习(五)远程仓库

    Git 学习(五)远程仓库 之前的章节所说的是本地Git仓库的操作,版本管理的优越性显然不会仅仅在本地.远程仓库也就是服务器或是网络端的仓库操作也是必须的. 本文具体说明 Git 的远程仓库操作,示例 ...

  6. Git 学习(三)本地仓库操作——git add & commit

    Git 学习(三)本地仓库操作——git add & commit Git 和其他版本控制系统如SVN的一个不同之处就是有暂存区的概念.这在上文已有提及,本文具体说明什么是工作区及暂存区,以及 ...

  7. git 学习笔记 Git实践

    网上有很多教程,这里我自己做下整理,省得有时忘记,有道是好记性不如烂博客! 先大概描述下Git的各种命令: git init                     #初始化 git clone   ...

  8. git学习——<五>git分支

    git学习——<一>git安装 git学习——<二>git配置文件 git学习——<三>git操作 git学习——<四>git版本管理 一.提出问题 今 ...

  9. [git 学习篇] git remote add origin错误

    http://blog.csdn.net/dengjianqiang2011/article/details/9260435 如果输入$ Git remote add origin git@githu ...

随机推荐

  1. Sql Server 数据库出现“可疑”的解决办法

    问题:数据库名称出现“可疑”字样 解决: 方法一: 重新还原数据库 方法二: 贴上语句:(DB_CS:你的数据库名) 第一步: ALTER DATABASE DB_CS SET EMERGENCY 第 ...

  2. cad快捷图标中的启动参数

    !!!转载   http://blog.sina.com.cn//s/blog_6848608101017v4w.html 有时候需要判断一下是否是硬件加速.Ribbon等原因造成了软件的问题,需要在 ...

  3. 可靠性、幂等性和事务 Kafka

    Kafka笔记—可靠性.幂等性和事务   分类: 消息队列 标签: kafka 这几天很忙,但是我现在给我的要求是一周至少要出一篇文章,所以先拿这篇笔记来做开胃菜,源码分析估计明后两天应该能写一篇.给 ...

  4. IO流一些问题的总结

    字节流的继承体系 字符流的继承体系 字符编码是什么?常见的字符编码表有哪些? 字符编码(英语:Character encoding)也称字集码,是把字符集中的字符编码为指定集合中某一对象,以便文本在计 ...

  5. WeakhashMap源码1

    弱引用(WeakReference)的特性是:当gc线程发现某个对象只有弱引用指向它,那么就会将其销毁并回收内存.WeakReference也会被加入到引用队列queue中. 它的特殊之处在于 Wea ...

  6. [EXP]CVE-2019-0604 Microsoft SharePoint RCE Exploit

    研表究明,汉字的序顺并不定一能影阅响读,比如当你看完这句话后,才发这现里的字全是都乱的. 剑桥大学的研究结果,当单词的字母顺序颠倒时,你仍旧可以明白整个单词的意思.其中重要的是:只要单词的第一个字母和 ...

  7. 第三节:EF Core上下文DbContext相关配置和生命周期

    一. 配置相关 1. 数据库连接字符串的写法 (1).账号密码:Server=localhost;Database=EFDB01;User ID=sa;Password=123456; (2).win ...

  8. Springboot Actuator之十一:actuator transaction

    前言spring boot 的自动化配置其实就是在spring 的基础上做的封装,在我们之前对mvc,aop的自动化配置中可以发现–> 只是在spring 的基础上添加了一些特性,可以认为只是一 ...

  9. DELPHI网页开发神器UNIGUI的安装与演示

    UNIGUI安装和演示 uniGUI v1.0.0.1397(带注册机).rar在delphi10.2安装 提示:安装包可以自行在网上搜索下载,或者联系我获取都可以 这里讲下怎样安装的方法: 1)执行 ...

  10. json loggin 的使用,小案例

    import json import os Base_path = os.path.join(os.path.abspath(".."),"龙茂天日志.log" ...