git入门与实践(一)
linux
· March 10th, 2010git
· Posted in UNIX环境编程github
· By ghosTM55算法
什么是版本控制
要了解什么是git,首先须要了解什么是版本控制(Version Control),版本控制系统(Version Control System,简称VCS)是一种记录一个或多个文件的变化的系统,这样的系统可以方便你从此调用找回某个特定时期(或版本)的文件。 版本控制系统普遍地应用于程序开发等领域,它能够协助你将某个指定的文件(甚至是一整个项目)返回至某个以前记录的状态,查看发生了哪些变化、对变化进行比较或者是修正致命错误。 版本控制系统主要经历了本地版本控制,集中式版本控制到分布式版本控制的发展:
编程
· 本地版本控制(Local Version Control System)顾名思义就是本地化的版本控制系统,没有网络协做等较为先进的版本控制的概念ubuntu
· 集中式版本控制意(Centralized Version Control System)为有一台版本控制服务器运行在那边存放并提供一个项目中全部版本文件的服务,在很长一段时间内占据主流,其中CVS与Subversion(SVN)为其表明小程序
· 分布式版本控制(Distributed Version Control System)克服了集中式版本控制可能由于单点失败形成的巨大损失的缺点,让每一台客户端在每一次checkout操做后都彻底镜像整个版本控制中的项目。在分布式版本控制系统中,任何一台机器均可以视为版本控制服务器。即便有一台服务器失去服务能力,其它机器与系统能够继续协做维持版本控制系统的正常运转。git就是分布式版本控制系统c#
git的历史
在2005年,Linux内核开发团队与其使用的分布式版本控制系统BitKeeper的开发公司关系破裂,他们没有了无偿使用BitKeeper的特权。这直接催生了Linux开发社区本身开发一套分布式版本控制系统的想法。 Linux开发社区借鉴了以前使用BitKeeper时看到的闪光点,并但愿可以在版本控制系统的速度、架构设计与各种特性支持中做出较好的改进与提高,因而,git诞生了。
基础概念与机制
git与其它主流的VCS最大的区别就是,在项目版本更新的过程当中,git记录的并不是是基于初始文件的变化数据,而是经过一系列快照(Snapshot,就像是个小型的文件系统)来保存记录每一个文件。若是有些文件在版本更新后没有发生任何变化,那么在新的版本中它会是一个指向最近一次更新的文件版本的连接。 此外,几乎全部git的操做都是在本地进行的,因此,没有了“延迟”,几乎全部的操做都是瞬间完成的。例如,当你想要查看项目历史时,不须要特意去服务器上抓取历史记录,直接在本地浏览便可。这意味着,你能够在本地对比两个不一样版本的文件的差异,能够在本地查看过去有哪些人对指定文件做出了修改与更新,能够……几乎彻底本地化的操做也让这样一种场景成为了可能: 当一我的在飞机、火车上,或者是任何因素致使没有网络链接条件可是又必须抓紧时间对本身的项目进行修改与开发,同时又须要有版本管理系统来记录每次他commit的历史,这时,git提供了他全部须要的便利。
git使用SHA-1 Hash算法加密生成的40位字符串(而不是文件名)来记录表明git中的每样东西。格式就像这样:
安全
6bafcdc09f3d6d416f6572f82082987a486d3098
git中的文件主要会处于三种状态,它们分别是:
· Committed: 文件或数据已经安全的存放在了git本地数据库中
· Modified: 文件或数据已经修改可是还没有commit到数据库
· Staged: 文件或数据已被标记要放入到下一次commit中
这样的机制导致git的镜像会由三个部分组成(假设有一个git目录叫git-repo):
· Git directory: 存放项目中全部元数据以及对象的地方(git-repo/.git/)
· Working directory: 在这里是从git项目数据库中checkout出的一个单独的(默认状况下是最新的)项目版本,用于对指定项目版本中的文件进行修改和编辑(git-repo/)
· Staging area: 通常是存放在Git directory中的一个简单的文件,里面存放着下一次须要commit的文件的信息(在git-repo/.git/中)
安装git
在快速了解了git的概念与历史后,咱们就要开始学习使用它了,天然而然的,第一步咱们须要将git安装到咱们的系统中去。 众所周知,不一样的Linux发行版本有着不一样的包管理模式,在大多数Linux发行版本的软件源中,都会有现成的git包已经打好以提供yum,aptitude之类的工具直接解决依赖问题下载与安装。 固然,你也能够手动下载最新的git源代码包,自行编译,不过须要注意一点的是,确保你已经解决了为手动编译git而须要解决的软件依赖问题:
使用yum工具先行解决包依赖问题(适用于RHEL,CentOS,Fedora等):
# yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel
使用aptitude工具先行解决包依赖问题(适用于Debian,ubuntu等):
# aptitude install curl-devel expat-devel gettext-devel openssl-devel zlib-devel
完成这些依赖的安装后,到这里下载最新的git源代码包,而后开始安装:
$ tar -zxf git-xxx.tar.gz # xxx表明版本号
$ cd git-xxx/$ make prefix=/usr/local all$ sudo make prefix=/usr/local install
一旦git的安装完成了,从此你可使用git自己来获取git最新的updates:
$ git clone git://git.kernel.org/pub/scm/git/git.git[/pre]git一样可以在Mac OS X与Windows上使用,具体的操做请参考这里和这里。
其余Linux发行版本(例如archlinux,gentoo等),可参照各发行版本的官方手册与说明使用各自的包管理工具安装。
配置git
完成git的安装后,不要急着使用,首先你须要对git进行一些小小的配置,它在git的应用(通常是项目开发中)是必要的。git提供了config工具(你也能够手动)来配置如下三份git配置文件:
· /etc/gitconfig: git的系统全局配置文件,该配置文件中的配置选项对操做系统上全部使用git的用户产生影响,使用git config –system能够针对此文件进行配置
· ~/.gitconfig: git的用户全局配置文件,该配置文件的配置选项对当前用户产生影响,而且会覆盖掉系统全局配置文件中已经存在的配置选项,使用git config –global能够针对此文件进行配置
· .git/config: 该文件存在每一个git镜像下,其配置文件的配置选项仅对该git镜像产生影响,它会覆盖掉用户全局配置文件中已经存在的配置选项
了解了配置git的文件位置与机制后,咱们首先就来尝试配置一下git的用户信息:
$ git config --global user.name "Thomas"
$ git config --global user.email ghosthomas@gmail.com
这时,你就会发如今~/.gitconfig文件中,多出了与用户信息相关的配置(2条赋值语句) 在git的配置文件中,你能够针对用户名、邮件地址、编辑器、diff工具等进行配置,具体的配置参数与方法使用命令
$ git help config
便可得到。
开始git
初始化/获取 git镜像
要开始使用git,首先要作的就是建立或者获取一个git镜像,建立一个文件夹,将其初始化为git镜像:
$ pwd/home/thomas/workspace/tmp
$ mkdir git-repo
$ cd git-repo/
$ git init
Initialized empty Git repository in /home/thomas/workspace/tmp/git-repo/.git/
在这里能够看到,我创建了一个名为git-repo的文件夹,而且将它初始化成为git镜像目录,初始化的命令为git init,完成初始化后,会在目录下建立一个名为.git的子目录,对了,这就是前面提到的Git directory。你也能够经过git clone命令来获取一个已存在的git镜像:
$ git clone git://github.com/schacon/grit.git
默认状况下,clone命令执行后会根据服务器上git镜像的目录名建立目录并进行git镜像的clone,你也能够在上述命令后加上本身但愿看到的目录名(好比repo123)来将远程的git镜像clone到该目录下:
$ git clone git://github.com/schacon/grit.git repo123
有了git镜像后,咱们就能够开始学习git的基本使用技巧了!
Modify -> Stage -> Commit -> Track
恭喜,如今你已经有一个git镜像来学习、实验或使用了。让我从实际应用出发,一步步为你介绍和解释git的基本应用。
在git的世界里,有两类文件,分别是未追踪(untracked)和已追踪(tracked),已追踪的文件是指已经放入了最新的git镜像(snapshot)里,已追踪的文件又分为三个状态,分别是:
· Unmodified: 文件没有作过任何修改
· Modified: 文件已被修改更新
· Staged: 文件已经修改更新,准备commit的状态
而未追踪的文件指的就是在git的工做目录下,全部还没有被提交放入git镜像目录中的文件。
在学会提交文件至git镜像前,先介绍一个很是重要的工具,git status,它会告诉你目前git镜像的状态,在使用git的过程当中,你将会始终依赖这个工具帮助你更出色的完成工做!
$ git status
# On branch master
#
# Initial commit
#nothing to commit (create/copy files and use "git add" to track)
能够看出,git status给出了至关详细的信息,第一行中首先给出的是git的分支(branch)状态信息,branch会在未来的文章中进一步为你们介绍,它是git的王牌特性之一。接着,git会告诉你如今尚未东西提交到镜像中,须要先使用命令git add来对文件进行追踪。
因此,假设咱们先在git的工做目录中使用C语言写一个helloworld的小程序,保存,咱们获得一个文件: helloworld.c,而后,咱们但愿将这个文件被git镜像追踪(track)到,那么咱们须要:
$ git add helloworld.c[/pre]这样,咱们就将helloworld.c加入到了git镜像中去进行版本控制,再次使用git status来查看目前的镜像状态:
$ git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
# (use "git rm --cached ..." to unstage)#
# new file: helloworld.c#
注意这里它提到了changes to be committed,意思是该文件已经处于staged状态,接下去你能够根据本身的须要将其提交(commit),或者若是你以为这是一个误操做,该文件不该当被提交,你能够经过git rm –cached命令来取消它的staged状态(你会发现status信息中做出了精确的提示)。
如今,咱们经过命令git commit将helloworld.c提交:
$ git commit
这时,会出现一个带有status信息的文本给你编辑(使用什么编辑器取决于你对git的配置),在以”#”开头的注释行下输入一些文本,用于注释这次提交,方便于其余代码协做者的维护与理解!
你也能够经过命令参数-m来直接输入注释内容,加快提交速度:
$ git commit -m "comment here"
至此,你的文件helloworld.c已经处于tracked状态!整个过程就是小标题中所说的从修改(建立)文件到最终提交的过程。
接下来,咱们将会探讨一些更为有趣的git使用技巧!
git应用进阶
在前一小节中,笔者举出的只是helloworld式的git基础应用,到这里你们应该有一个可用的git镜像以及一个已经被git追踪管理的文件了吧,是否是很方便和快捷呢?这个小节中我会带领你们了解更多git的工具与使用技巧。
修改已提交文件
如今,咱们有一个helloworld.c在镜像中进行版本控制了,咱们发现这个文件有一个小错误,oh,有一个循环的条件写错了,赶忙修改一下这个不大不小的bug,针对文件完成修改更新后,咱们能够经过git status看到:
# On branch master
# Changed but not updated:
# (use "git add ..." to update what will be committed)
# (use "git checkout -- ..." to discard changes in working directory)
#
# modified: helloworld.c
#no changes added to commit (use "git add" and/or "git commit -a")
git status告诉咱们,helloworld.c被修改过了,若是你想要提交,须要再次git add该文件,或者,你能够直接使用git commit -a跳过add的步骤,直接提交(还没有track的文件必须先git add才能进行提交)。
在提示中,还有提到说,若是你想撤销对helloworld.c的修改,就可使用git checkout命令来实现,这里的状况会是:
$ git checkout -- helloworld.c
若是你这么作了,你就会发现,你的helloworld.c又回到了以前没有被修改过的时候的状态。
git中的diff
在Unix/Unix-like系统中,几乎都会有一个小巧的对比文件不一样的工具叫作diff,在git中也有这么一个工具,来详细比较你修改后准备提交的文件与修改前的状态的不一样之处,恩,也许你猜到了,这个命令就是git diff。
如今咱们尝试着再次修改一下helloworld.c,而后运行git diff:
$ git diff
diff --git a/helloworld.c b/helloworld.c
index befc634..a86316b 100644
--- a/helloworld.c
+++ b/helloworld.c
@@ -1,3 +1,4 @@
+/* new comment line */
#include int main(void) {
经过git的diff工具,咱们很容易发现,此次我在程序中新加入了一行注释代码。
添加新文件
恩,有了一个像样的代码文件后,我须要为个人代码写些说明文档,同时我也须要对这样一篇文档进行维护,那么,就创建一个README.txt文件,而且将它track到git镜像中去,看到这里读者们能够先自行尝试一下:
$ echo README > README.txt
$ ls
helloworld.c README.txt
$ git status
# On branch master
# Untracked files:
# (use "git add ..." to include in what will be committed)
#
# README.txtnothing added to commit but untracked files present (use "git add" to track)[
至此,就有一个新的文件已经随时待命准备提交了,你能够清楚的看到git status很是聪明的将README.txt归类为了untracked files里,如今咱们将它加入git镜像:
$ git add README.txt
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD ..." to unstage)
#
# new file: README.txt
#
你能够像以前那样将README文件commit,可是此次咱们将会展现的是如何unstage一个文件,在git status信息中,它告诉用户使用git reset HEAD命令来unstage一个文件,咱们尝试一下:
$ git reset HEAD README.txt
$ git status
# On branch master
# Untracked files:
# (use "git add ..." to include in what will be committed)
#
# README.txt
nothing added to commit but untracked files present (use "git add" to track)
看,README.txt又回到了untracked状态!
重命名git中的文件
假设如今咱们须要修改README.txt的文件名,千万要记得咱们的文件在git的镜像中进行版本控制管理,因此,不要鲁莽的直接使用unix命令mv或者rm来对git镜像中的文件进行普通的文件操做,固然,若是你真的一不留神那么作了,也没关系。
git中,使用git mv工具来对文件进行重命名:
$ git mv README.txt tutorial.txt
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD ..." to unstage)
#
# renamed: README.txt -> tutorial.txt
#
$ git commit -a -m "renamed a file"
[master 55ce30d] renamed a file 1 files changed, 0 insertions(+), 0 deletions(-)
rename README.txt => tutorial.txt (100%)
能够看到,在提交变动后,README.txt在文件系统以及git镜像中都被成功地重命名为了tutorial.txt。一样的,你能够unstage来撤销对该文件的重命名,the choice is yours!
删除git中的文件
若是咱们再也不须要tutorial.txt这个文件,咱们能够将其从git镜像中删除,git中删除文件的命令是git rm:
$ git rm tutorial.txt
rm 'tutorial.txt'
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD ..." to unstage)
#
# deleted: tutorial.txt
#
$ git commit -a -m " deleted a file"
[master 7d81981] deleted a file 1 files changed, 0 insertions(+), 1 deletions(-)
delete mode 100644 tutorial.txt
正如以前所提到的,这些操做都是能够恢复的,由于git是版本控制系统,因此天然而然的就会有一套版本历史管理机制。
查看commit历史
工具git log提供了查看git镜像的commit历史:
$ git log
commit 7d819818530ce89322019ba5000723c973eb0420
Author: ghosTM55
Date: Sun Mar 14 15:26:22 2010 +0800
deleted a file
commit 55ce30d88fb5c81d20bdf86e2034053613fed632
Author: ghosTM55
Date: Sun Mar 14 15:11:39 2010 +0800
renamed a file
commit 2ed9f1f9bd1a7561cd7e57dcdbd7f2cda54668fb
Author: ghosTM55
Date: Sun Mar 14 14:58:11 2010 +0800
a little change
commit dde0bab46a9d9f29c50d2996a9efe20253be9f15
Author: ghosTM55
Date: Sun Mar 14 14:28:48 2010 +0800
新文件来了,旧文件改了
commit c06c4e5ebc3a5281a3400c31c20e95ebd43f1547
Author: ghosTM55
Date: Sun Mar 14 13:36:02 2010 +0800
第一次提交
能够看到,git详细记录了每次commit的信息(checksum值、提交者信息、提交时间)。
获取命令帮助
本(系列)文只是guide,不是manual,因此不会为读者详细解释每个git命令的使用。当读者想要详细了解某命令的使用时,学会本身阅读git自带的manual文件是关键。
例如,若是你想了解更多有关于git log的使用方法,输入命令:
$ git log help
便可。一样的,你也能够经过google等方法获取更多有关git的使用技巧!
总结
本文是git入门与实践系列的第一篇,对git进行了最为基础的介绍与入门引导,在之后的文章中,我会为你们进一步讲解git的应用与技巧。尽请期待!
ghosTM55
参考资料:
转自:http://my.oschina.net/zhangqingcai/blog/39102