在对版本控制系统有了初步认识后,让我们着手开始学习Git吧。使用了Git的软件项目跟普通的项目不会有太大的不同。你还是照旧写代码然后将之存入目录,唯一不同的是,你现在可以使用一些Git命令来操作这些文件了。
例如,你想将项目恢复到上一个版本,仅仅只需要执行一条简单的Git命令就可以搞定。当命令被执行时,Git会到内部数据库中取回项目的指定状态,然后更新当前的项目目录(也称为工作目录)中的相关文件。乍一看就好像项目奇迹般的穿越到过去了。
本节探讨了Git的一些基本用法:创建仓库(repository),暂存(staging)以及提交(committing)快照(snapshots),配置选项,以及查看仓库的当前状态。本节中还引入了将会贯穿整个教程的HTML网站项目。为了深刻的理解之后执行的每一条Git命令,一些HTML和CSS的基础知识将有所帮助,但也绝非必要。
在执行Git命令之前,我们需要创建一个示例项目。创建目录my-git-repo
,并且在其中添加文件index.html
。使用你喜爱的文本编辑器打开index.html
然后输入如下HTML。
<html lang="en">
<head>
<title>A Colorful Websitetitle>
<meta charset="utf-8" />
head>
<body>
<h1 style="color: #07F">A Colorful Websiteh1>
<p>This is a website about color!p>
<h2 style="color: #C00">Newsh2>
<ul>
<li>Nothing going on (yet)li>
ul>
body>
html>
保存文件,这就是我们示例项目的基础。不妨试着在浏览器中打开该文件预览一下网页效果。可能你觉得不咋地,但是能帮我们学习Git。
现在让我们来创建第一个Git仓库。打开命令提示符窗口(windows用户打开Git Bash)然后切换到项目目录:
cd /path/to/my-git-repo
/path/to/my-git-repo
是我们刚才创建的目录路径。如果你实在桌面创建的,你可能应该执行:
cd ~/Desktop/my-git-repo
接下来,执行如下命令,将项目目录变为Git仓库:
git init
这条命令初始化了仓库,接下来Git就可以大展拳脚了。请注意,现在项目目录中多了一个.git
目录(该目录为隐藏目录,请确保你能够查看隐藏文件),这儿保存着Git的所有跟踪信息。这个.git
目录是该Git仓库跟普通目录的唯一不同,这意味着删掉.git
目录,该Git仓库就变成了一个普通目录。
在我们修改代码之前,最好先查看一下仓库的状态。按照如下执行命令:
git status
应该输出类似如下信息:
# On branch master
#
# Initial commit
#
# Untracked files:
# (use "git add ..." to include in what will be committed)
#
# index.html
nothing added to commit but untracked files present (use "git add" to track)
暂时忽略On branch master
部分的信息,这条状态信息告诉我们,现在处于初始化提交(Initial commit)状态,但是没有需要提交的文件只有未跟踪文件(untracked file)。
未跟踪(untracked)的文件就是未被纳入版本控制系统管理的文件。Git不是默认跟踪记录文件的,因为项目中有些文件我们可能不需要版本控制。例如一些C程序生成的二进制文件,编译过的Python模块(.pyc文件),以及一些很大的文件。为了保持项目的精简和高效,你应该仅仅跟踪源代码文件然后忽略生成的文件。后者应该属于项目编译过程的一部分,而不在版本控制之列。
因此我们应该明确的告诉git将index.html
文件加入仓库。直观的git add
命令使得Git开始跟踪index.html
。
git add index.html
git status
这儿不再显示未跟踪文件列表,你应该会看到如下类似信息:
# Changes to be committed:
# (use "git rm --cached ..." to unstage)
#
# new file: index.html
刚才我们创建了index.html
的快照以备下次提交。快照代表了特定时间点的项目状态。本例中,我们创建了只包含一个文件index.html
的快照。如果以后我们希望Git恢复这个快照,整个项目目录将只剩下这一个文件,并且文件内容跟当前一样。
Git将创建一个快照称为暂存(staging),因为在正式提交到项目历史中之前,我们可以向暂存区中添加或者删除文件。有了暂存这个过程,我们就可以将相关的更改组成一个快照——这样做可以让软件项目的每个进度记录都是有意义的(而不是仅仅任意的代码)
刚才我们暂存了快照,现在我们需要将之提交到项目历史记录中。下面这条命令会打开文本编辑器,你需要输入提交信息:
git commit
输入Create index page
,保留编辑器中其余的文字,保存文件然后退出编辑器。这时你应该看到一堆输出信息,其中包括1 files changed
。这个更改的文件就是index.html
。
正如刚才演示的那样,保存项目的一个版本需要两步:
使用git add
暂存文件并没有最终影响到仓库——仅仅是让我们预备下一次提交的文件。只有在执行了git commit
命令之后这个快照才会被记录在仓库中。已提交的快照一般被视为该项目的可靠版本。Git不会更改这些可靠版本,这意味着你可以在当前的工作目录做任何动作,而不需担心数据的丢失。这也是所有版本控制系统的主要目标。
再次查看仓库状态,它会显示没有任何文件需要提交,这意味着项目当前状态和仓库中是一致的。git commit
只会显示未提交的更改,要查看项目的历史记录,我们需要另外一个命令:
git log
执行这条命令后,Git会输出我们仅有的一条提交信息,类似如下:
commit b650e4bd831aba05fa62d6f6d064e7ca02b5ee1b
Author: unknown <user@computer.(none)>
Date: Wed Jan 11 00:45:10 2012 -0600
Create index page
我们来分析一下这条信息。首先,我们的提交被分配了一个非常长看起来像随机生成的字符串(b650e4b…)。这是提交内容的SHA-1校验和,以确保不会发生冲突。由于提交时间和提交人不同,你看到的每个SHA-1校验和都不会和本教程中显示的一样。在下一节中,我们会看到校验和还被用来作为一次提交的唯一标识。
接下来一行,Git显示出了提交人。由于我还没有在Git中设置提交人的信息,这儿会显示unknown。Git同样还显示出了提交的日期,时间及时区。最后就是我们在提交时输入的提交描述。
在提交更多的快照之前,我们应该告诉Git提交人的信息。通过git config
命令可以做到:
git config --global user.name "Your Name"
git config --global user.email your.email@example.com
确保使用自己的真实名字和邮箱替换上面的Your Name
和[email protected]
。--global
选项使得Git将此项设置作为所有仓库的默认配置。省略该选项,此项设置将仅对当前仓库有效,这迟早会派上用场的。
继续开发我们的网站项目,创建一个名为orange.html
的文件,内容如下:
<html lang="en">
<head>
<title>The Orange Pagetitle>
<meta charset="utf-8" />
head>
<body>
<h1 style="color: #F90">The Orange Pageh1>
<p>Orange is so great it has a
<span style="color: #F90">fruitspan> named after it.p>
body>
html>
接着创建blue.html
文件:
<html lang="en">
<head>
<title>The Blue Pagetitle>
<meta charset="utf-8" />
head>
<body>
<h1 style="color: #00F">The Blue Pageh1>
<p>Blue is the color of the sky.p>
body>
html>
照旧如下暂存新创建的文件:
git add orange.html blue.html
git status
请留意git add
之后是可以添加多个文件的。暂存完文件,git status
的输出信息类似如下:
# On branch master
# Changes to be committed:
# (use "git reset HEAD ..." to unstage)
#
# new file: blue.html
# new file: orange.html
试着执行git log
。仅仅会显示第一次的提交,这表明blue.html
和orange.html
还没有加入仓库的历史记录。请注意,查看暂存区的变化使用git status
命令,而不是git log
。后者仅仅用来查看已提交的变化。
如下命令提交暂存的快照:
git commit
提交时填写Create blue and orange pages
作为描述信息,保存并关闭文件。现在,git log
应该会显示两个提交,第二次提交还反映出来刚刚配置的名字和邮箱信息。当前项目的历史记录可以用下图表达出来:
每个圆圈代表一次提交,红色的指示了当前的提交,箭头指向了前一次提交。这一部分可能有点违反直觉,但是这是所有提交的真实内在关系(那就是,新的提交引用了它的父提交)。后面的教程中,我们会看到非常多的这种图示。
事实上git add
命令不仅仅被用来暂存新添的文件,还被用来暂存修改过的文件。打开index.html
文件,在
标签前面添加:
<h2>Navigationh2>
<ul>
<li style="color: #F90">
<a href="orange.html">The Orange Pagea>
li>
<li style="color: #00F">
<a href="blue.html">The Blue Pagea>
li>
ul>
接下来在orange.html
和blue.html
底部添加一个到主页面到链接(标签之前):
<p><a href="index.html">Return to home pagea>p>
再次在浏览器中打开主页,你就可以在三个页面之间导航了。
我们再次按照如下命令暂存修改并提交快照:
git status
git add index.html orange.html blue.html
git status
git commit -m "Add navigation links"
-m
选项使得我们可以在命令行中直接输入提交描述而不需要打开本文编辑器。这只是一个快捷方式(效果跟前面的命令一致)。
现在项目的历史记录可以如下表示。请注意,代表当前提交的红色圆圈在每次提交快照后自动的前移了
git log
命令可以附加很多的选项,其中的一些会在后续教程中陆续提及,现在只使用其中一个--oneline
选项。
git log --oneline
将每个提交信息的输出压缩成一行,有利于从全局查看仓库历史记录。另外一个有用的用法是向git log
命令传入一个文件名。
git log --oneline blue.html
这将仅仅查看blue.html
的历史记录。留意,最开始的Create index page
没有被包含在输出中,因为blue.html
并不在那次快照中。
在本节中,我们介绍了基本的Git用法:编辑文件,暂存快照,提交快照。这其中每个过程我们都实际操练过了:
使用Git进行版本管理的核心涉及到三个部分,工作目录,快照暂存区,以及已提交到快照。基本上Git其他所有命令都在某种程度上操作其中的一个部分,因此理解这几个部分的交互是掌握Git的关键基础。
在下一节中我们会实际应用项目的历史记录并将项目恢复到之前的快照。下一节结束后,你就具备了开始将Git运用到你实际项目中的基本知识。
git init
在当前目录中创建Git仓库
git status
查看仓库中每个文件的状态
git add <file>
暂存文件以备下次提交
git commit
提交暂存的文件及其描述信息
git log
查看仓库的提交历史记录
git config --global user.name ""
设置供所有仓库使用的提交人名字
git config --global user.email
设置供所有仓库使用的提交人邮箱