初学Git

251 阅读11分钟

版本控制

定义

版本控制是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统。版本控制系统经历了从本地版本控制系统到集中化的版本控制系统再到分布式版本控制系统三个阶段。

版本控制系统VCS

  1. 有了它你就可以将某个文件回溯到之前的状态,甚至将整个项目都回退到过去某个时间点的状态
  2. 你可以比较文件的变化细节,查出最后是谁修改了哪个地方,从而找出导致怪异问题出现的原因,又是谁在何时报告了某个功能缺陷等等。
  3. 使用版本控制系统通常还意味着,就算你乱来一气把整个项目中的文件改的改删的删,你也照样可以轻松恢复到原先的样子。 但额外增加的工作量却微乎其微。

本地版本控制系统

* 大多都是采用某种简单的数据库来记录文件的历次更新差异。

* 其中最流行的一种叫做 RCS,现今许多计算机系统上都还看得到它的踪影。 甚至在流行的 Mac OS X 系统上安装了开发者工具包之后,也可以使用 rcs 命令。 它的工作原理是在硬盘上保存补丁集(补丁是指文件修订前后的变化);通过应用所有的补丁,可以重新计算出各个版本的文件内容。

集中化的版本控制系统

集中化的版本控制系统(Centralized Version Control Systems,简称 CVCS),诸如 CVS、Subversion 以及 Perforce 等,都有一个单一的集中管理的服务器,保存所有文件的修订版本,而协同工作的人们都通过客户端连到这台服务器,取出最新的文件或者提交更新。 多年以来,这已成为版本控制系统的标准做法。

这种做法带来了许多好处,特别是相较于老式的本地 VCS 来说。 现在,每个人都可以在一定程度上看到项目中的其他人正在做些什么。 而管理员也可以轻松掌控每个开发者的权限,并且管理一个 CVCS 要远比在各个客户端上维护本地数据库来得轻松容易。

事分两面,有好有坏。 这么做最显而易见的缺点是中央服务器的单点故障。 如果宕机一小时,那么在这一小时内,谁都无法提交更新,也就无法协同工作。 如果中心数据库所在的磁盘发生损坏,又没有做恰当备份,毫无疑问你将丢失所有数据——包括项目的整个变更历史,只剩下人们在各自机器上保留的单独快照。 本地版本控制系统也存在类似问题,只要整个项目的历史记录被保存在单一位置,就有丢失所有历史更新记录的风险。

分布式版本控制系统

分布式版本控制系统(Distributed Version Control System,简称 DVCS),像 Git、Mercurial、Bazaar 以及 Darcs 等,客户端并不只提取最新版本的文件快照,而是把代码仓库完整地镜像下来。 这么一来,任何一处协同工作用的服务器发生故障,事后都可以用任何一个镜像出来的本地仓库恢复。 因为每一次的克隆操作,实际上都是一次对代码仓库的完整备份。

更进一步,许多这类系统都可以指定和若干不同的远端代码仓库进行交互。籍此,你就可以在同一个项目中,分别和不同工作小组的人相互协作。 你可以根据需要设定不同的协作流程,比如层次模型式的工作流,而这在以前的集中式系统中是无法实现的。

认识.git目录

.git目录中包含了一个Git仓库所有必需的文件,这些文件是Git仓库的骨干。.git目录就是存了版本信息的地方,有了它才能使一个普通文件夹变成Git仓库从而进行版本管理。

认识配置文件

什么是配置文件

  1. 在使用Git之前,我们要做几件事来定制我们的 Git 环境。 每台计算机上只需要配置一次,程序升级时会保留配置信息。 你可以在任何时候再次通过运行命令来修改它们。
  2. Git 自带一个 git config 的工具来帮助设置控制 Git 外观和行为的配置变量。
  3. 我们通常需要配置用户信息(用户名和邮箱)以及文本编辑器这些变量

配置变量储存在哪

这些变量存储在三个不同的位置:

/et/gitconfig 文件: 包含系统上每一个用户及他们仓库的通用配置。 如果使用带有--system选项的 git config 时,它会从此文件读写配置变量。

~/.gitconfig~/.config/git/config 文件:只针对当前用户。 可以传递--global选项让 Git 读写此文件。

③当前使用仓库的 Git 目录中的 config 文件(就是 .git/config):针对该仓库。

注:每一个级别覆盖上一级别的配置,所以.git/config 的配置变量会覆盖 /etc/gitconfig 中的配置变量。

配置用户信息

  1. 当安装完 Git 应该做的第一件事就是设置你的用户名称与邮件地址。 这样做很重要,因为每一个 Git 的提交都会使用这些信息,并且它会写入到你的每一次提交中,不可更改:
git config --global user.name "name"
git config --global user.email Your email@example.com
  1. 再次强调,如果使用了--global 选项,那么该命令只需要运行一次,因为之后无论你在该系统上做任何事情, Git 都会使用那些信息。

  2. 当你想针对特定项目使用不同的用户名称与邮件地址时,可以在那个项目目录下运行没有 --global 选项的命令来配置。

配置文本编辑器

既然用户信息已经设置完毕,你可以配置默认文本编辑器了,当 Git 需要你输入信息时会调用它。 如果未配置,Git 会使用操作系统默认的文本编辑器,通常是 Vim。 如果你想使用不同的文本编辑器,例如 Emacs,可以这样做:

git config --global core.editor emacs

检查配置信息

  1. 如果想要检查你的配置,可以使用 git config --list 命令来列出所有 Git 当时能找到的配置。

你可能会看到重复的变量名,因为 Git 会从不同的文件中读取同一个配置(例如:/etc/gitconfig 与 ~/.gitconfig)。 这种情况下,Git 会使用它找到的每一个变量的最后一个配置。

  1. 你可以通过输入 git config <key>来检查 Git 的某一项配置

获取Git仓库

有两种取得 Git 项目仓库的方法。 第一种是在现有项目或目录下导入所有文件到 Git 中; 第二种是从一个服务器克隆一个现有的 Git 仓库。

在现有目录中初始化仓库

  1. 如果你打算使用 Git 来对现有的项目进行管理,你只需要进入该项目目录并输入:git init

    该命令将创建一个名为 .git 的子目录,这个子目录含有你初始化的 Git 仓库中所有的必须文件,这些文件是 Git 仓库的骨干。这样我们就在本地新建了一个仓库。 但是,在这个时候,我们仅仅是做了一个初始化的操作,你的项目里的文件还没有被跟踪。

  2. 如果你是在一个已经存在文件的文件夹(而不是空文件夹)中初始化 Git仓库来进行版本控制的话,你应该开始跟踪这些文件并提交。 你可通过 git add 命令来实现对指定文件的跟踪,然后执行 git commit 提交:

git add .

git commit -m 'initial project version'

(该内容具体看下一专题)

克隆现有的仓库

  1. 你从Github上发现了一个开源项目并且你想为该项目贡献自己的一份力,那么你就需要把这个项目的Git仓库克隆下来然后在本地进行操作。这时就要用到 git clone 命令。

  2. 克隆仓库的命令格式是 git clone [url]

    [url]中填入远程仓库的地址. 。

    比如, git clone git@github.com:yybb717/demo.git

  3. 当执行 git clone 命令的时候,会在当前目录下创建一个名为 “远程仓库名” 的目录,并在这个目录下初始化一个.git 文件夹,默认配置下远程 Git 仓库中的每一个文件的每一个版本的数据都将被拉取下来放入.git 文件夹。这样我们就成功的把远程仓库克隆到本地成为一个本地仓库。然后Git从中读取最新版本的文件的拷贝,如果你进入到这个新建的“远程仓库名” 文件夹(也就是我们的本地仓库),你会发现所有的项目文件已经在里面了,准备就绪等待后续的开发和使用。

  4. 如果你想在克隆远程仓库的时候,自定义本地仓库的名字,你可以使用如下命令:

    git clone [url] [自定义本地仓库名]

    比如,git clone git@github.com:yybb717/demo.git myserver

    这将执行与上一个命令相同的操作,不过在本地创建的仓库名字变为 myserver。

Git文件状态的演变

下图是文件的状态生命周期:

注:要查看哪些文件处于什么状态,可以用 git status 命令查看。

未追踪状态 Untracked

在本地仓库中新创建的文件属于未追踪状态(Untracked),git不会对未追踪的状态的文件进行管理。

* 图片注释:我们在本地仓库新建了index.html,他的状态为《Untracked files》

放入暂存区未提交状态 Staged

git add 命令格式为git add [file],他 用于

  1. 跟踪新文件(意思就是这个文件以后就是我们操作的目标对象了),把文件新增的变动暂存(stage)起来。
  2. 把已跟踪文件的修改和删除的变动暂存。

  • 图片注释:我们把刚创建的index.html文件暂存起来了,可以看到他的状态变为《Changes to be committed》,变动《new file: index.html》将要被提交,也就是已追踪放入暂存区未提交状态。

已提交未修改状态 Unmodified

git commit 命令格式为git commit -m "message"message中填写对变动的注释),他用于对暂存区中暂存的变动进行提交(也就是执行,放入本地仓库中去了),文件变成已提交尚未修改状态(Unmodified)。

* 图片注释:《Your branch is ahead of 'origin/master' by 1 commit》你已经进行了一次提交

提交后被修改状态 Modified

  1. 对于已提交未修改的文件(已经被追踪),被修改或者删除后变成已修改状态(Modified),需要通过 git add命令把修改的变动暂存。之后才能提交。
  2. 有两种方法可以提交

(1)

git add .
git commit -m "提交文件的修改或者文件删除"

(2)也可以直接提交,但需要加上-a参数, 上面的操作等同如下操作

git commit -am "提交文件的修改或者文件删除"

  • 图片注释:在已经追踪的文件index.html中写出hello,那么该文件已被修改,此时状态为《Changes not staged for commit》,也就是变动《modified:index.html》还未暂存。

  • 把已经追踪的文件index.html删除,那么该文件已被修改,此时状态为《Changes not staged for commit》,也就是变动《deleted:index.html》还未暂存。

问题:git add 与 git commit -a 有什么区别

答:1. 对于已提交未修改的文件,文件的编辑、删除都会使其变成已修改状态。可以通过 git add暂存变动,再 git commit。也可以直接通过git commit -a 一次性暂存变动并提交;

  1. 对于未追踪文件的新增,只能通过 git add来暂存新增变动,之后在git commit提交