Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1176971
  • 博文数量: 312
  • 博客积分: 12522
  • 博客等级: 上将
  • 技术积分: 3376
  • 用 户 组: 普通用户
  • 注册时间: 2008-02-27 18:35
文章分类

全部博文(312)

文章存档

2016年(3)

2015年(1)

2013年(1)

2012年(28)

2011年(101)

2010年(72)

2009年(13)

2008年(93)

分类: 项目管理

2010-08-19 13:17:04

第一课. git简介
 
内容:什么是git,为什么要使用git以及获取和学习git的途径。
 
 
欢迎来到github学习教程的第一课。本教程将通过一系列的实例来介绍如快速,轻松地使用Git。教程中会有很多屏幕截图,希望这样可以让你更好的学习和理解。
本节简要介绍git的概念和为什么应该使用它

 
git是一个快速,开源,分布式的版本控制系统。因此,它在(开源)和(协作编程社区)很快取代了svn。

版本控制系统 
首先,git是一个版本控制系统,用来保留工程源代码历史状态的命令行工具。类似于SVN,CVS或者Perforce等工具。

当你需要得到以前的一个保存点时,你可以利用它来追踪项目中的文件,并且得到某些时间点提交的项目状态。你可以和合作伙伴共享这些历史状态,将他们的工作和你的工作进行合并,可以对整个工程或某些文件跟历史版本进行比较或者恢复到早期的某个版本。

因为git根本上说是一个命令行工具,所以本教程中的大部分示例都会用命令行的方式给出。教程中使用现行git版本(1.6系列)编写示例。如果使用早期版本的话,我们也建议您升级到1.6系列。当然,现在已经有很多git UI的工具,使得git变得更加简单易用。

git的安装:
下载地址

安装过程:

1.$ tar xzvf git-1.6.5

2.$ cd git-1.6.5

3.$ ./config --prefix=/usr/local

4.$ make

5.$ sudo make install

6.$ git --version

如果需要命令帮助的话,可以键入'-help'就会显示出
操作手册。你也可以键入'git help command'实现同样的目的。

$ git log --help
$ git help log

开源 
git是一个开源项目,有很多年的历史了,它的大部分内容都是用C来写的。
你可以得到整个项目的源代码,加以分析和改进。下载源程序的地址:git-scm.com/download。git许可证:GNU通用公共许可证(GNU General Public License)
离线,速度快
   git是完全的分布式处理,这意味着它可以离线工作。跟VCS工具例如Perforce或者SVN完全不同,Git的所有操作几乎不需要网络连接,包括历史回顾,差异显示和提交。

这也意味着Git比其他的VCS工具要快很多,因为某些VCS工具对网络的依赖会导致时间上的延迟。下面来看看'log'命令分别运行在git和SVN上的结果:

[master]$ time git log > /dev/null

real 0m0.352s
user 0m0.300s
sys 0m0.034s 

$ time svn log > /dev/null

real 0m3.709s
user 0m0.482s
sys 0m0.168s

git仅用了0.3秒而SVN用了3.7秒。你会发现几乎所有的命令都有这样的时间差异。例如,添加知名的famfamfam出品的图标集并提交,因为使用git可以将【提交(commit)】和【上传('push')网络】这两个步骤分开,其中【提交(commit)】git只用1/4秒,而SVN会用到45秒。
time 'git add icons; git commit -m "added icons"'

real 0m0.273s
user 0m0.032s
sys 0m0.008s

time 'svn add icons; svn commit -m "added icons"'

real 0m45.276s
user 0m15.997s
sys 0m5.503s

即使是再加上用git 提交(commit)之后再上传(push)到网络共享仓库中的时间,也比SVN的耗时要少的多的多。
time git push

real 0m6.219s
user 0m0.023s
sys 0m0.011s

如果你仅仅是想提交然后继续工作,你就会感觉到时间上的巨大差异--因为git的工作流程跟以前的版本控制系统不大一样。git的命令大部分都是即时的,不像以前,执行'svn commit'命令之后,可以喝杯咖啡再回来继续工作。

比svn更小
git比较节省空间。举例来说,一个Django项目如果使用现行的源代码控制系统(source control systems)来实现版本控制的话,git克隆(clone)是最小的。
$ du -d 1 -h
108M ./django-bzr
 44M ./django-git
 53M ./django-hg
 53M ./django-svn

更神奇的是,虽然git克隆比SVN要小很多,但是git克隆包含整个项目的历史版本---从第一次提交之后的每一个文件的每一次提交的版本都囊括了。然而,SVN只包含项目的最后一个版本。

快照,而不是变更集

跟其他的VCS工具不同,git是基于快照的。不再是考虑将提交点存储成补丁文件,而是在你提交项目的时候对项目做一个简单的快照。

提交的东西包含一些元数据(提交信息(message),作者,日期等等),一个提交点指向这次提交时项目的快照。

记住这个图对于给定情形下使用Git是非常有帮助的。
如果要了解更深层次的Git存储数据的只是,可以访问
分支和合并
也许git最显著的一个特点就是它的分枝模型了,因为它改变了开发者工作的基本模式。以前的VCS工具分枝的方法是对每一个分枝都放到一个独立的目录中。而git可以让你在同一个工作目录中切换(switch)到不同的分枝。创建和切换分枝几乎是即时的(instant),而且并不是所有的分枝都需要上传到git仓库中去共享,对于某些你更愿意隐藏在本地的工作来说,git无疑提供了很大的便利。从这点上来说,git确是有其独到之处。
摒弃了CVS只对项目开发主线创建分枝的做法,git开发者可以随时创建,合并,删除多个分枝。通常对于实现某个功能或者每个debug阶段,都可以创建它的分枝,当完成之后再将其进行合并。这种模式可以让开发者体验更加快速,简便,安全的方式来开发项目。它鼓励一种非线性的开发周期,它可以说是并行的多线程模式而不是多个步骤串行的模式。
安装git
参见中对于git安装在不同操作系统中的说明。
资源
关于git的更多信息,可以参考
 
第二课.配置和初始化

 
配置git

在使用git之前你需要配置一下git。git在你创建提交的时候会记录你的名字和email地址,所以你应该告诉git这些内容。可以使用'git config'命令来设置,如果传递参数'-global' ,它会将这些值记录在~/.gitconfig文件里,作为这些配置的默认值。
$ git config --global user.name "Scott Chacon"
$ git config --global user.email "schacon@gmail.com"

在使用git的过程中,经常会用到文本编辑器。默认情况下它使用的是vim。如果你喜欢用其他的编辑器,例如emacs,你可以这样设置:
$ git config --global core.editor 'emacs'

查看设置值可以通过这样的命令:
$ git config user.name

你也可以自己编辑文件内容。git首先会检查'/etc/gitconfig',然后是'~/.gitconfig'最后是'.git/config',这些文件里的内容格式类似这样:
$ cat ~/.gitconfig
 
[user]
name = Scott Chacon
email =
schacon@gmail.com
 

2.初始化一个新的git仓库
在一个已存在的目录中初始化git存储,只要在目录下输入'git init'命令即可。这样会为这个目录生成一个基本的git存储框架。
$ rails myproject
$ cd myproject
$ git init

现在,就有了一个空的git存储(你可以查看目录下的'.git'目录)。现在就可以stage和提交(commit)文件到这个目录了。分别使用'git add'和'git commit'命令。下一节深入讲解这些命令。
$ git add .
$ git commit -m 'initial commit'

这样你就有了一个完整的提交之后的git存储了,可以运行'git log'(下一节深入讲解)
$ git log
 
commit eac2f939e6a1cb3189fedd19919888d998ab0431
Author: Scott Chacon
Date:   Sun Feb 8 07:55:57 2009 -0800
    initial commit


克隆一个git仓库
git可以通过很多的协议进行网络通信,其中有三个最主要的协议,分别是ssh,http,git(专职为git服务的协议)

匿名访问方式:通过git://或者http.
不管使用何种协议克隆git存储,格式都是这样:'git clone uri', uri的格式:
"git://(hostname)/(path).git"

 
$ git clone git://github.com/schacon/munger.git
$ cd munger
$ git log

当然也可以使用http克隆,跟上面的类似,就是将git换成了http。
$ git clone

这仅仅适用于服务器支持这两种协议的情况。如果服务器是GitHub的话,这两种方式都是可以的。
 
第三课   Git 工作流程
    与远程仓库同步,修改,载入(stage)和提交项目
 

现在你已经有一个git本地仓库,一切都配置完毕。然后该怎么办?
一般来说,跟其他的源码控制系统的工作流程没什么两样,唯一一个区别就是载入(stage)的过程。整个工作流程大致是这样(流程1):
  • 与远程仓库同步
  • 修改文件
  • 查看变更
  • 载入变更
  • 提交载入的变更
  • 重复
  • 上传

  • 这是最复杂的情况,如果你不与别人合作开发的话,就不需要上传到仓库中去(流程2):
    * 修改文件
    * 提交变更
    * 重复
    简单吧。要记得,git是分布式的,所以如果不是合作项目的话,实际上不需要提交到一个公共的共享服务器上--你可以像使用RCS一样,只用来追踪本地文件变更。下面,让我们先来看个简单的示例,紧接着再来看用git协作开发的实例。
    简单示例
    如果你想跟着做这个例子,请克隆这个项目:
    $ git clone git://github.com/schacon/simplegit
     

    例子开始,按照流程2,我们首先要修改README文件,将自己添加到项目作者中去。所以我们修改这个文件。然后我们希望提交这个变更,所以我们运行'git commit -a' 命令。 -a 的意思是告诉git先将变更了的文件先载入(stage),然后提交-我们后面会通过'staging area'命令实现,但是现在运行 'git commit -a' 命令,效果跟在SVN中使用'commit'命令一样。
    $ git commit -a
    执行完之后,一个提交信息的提示会出现在编辑器中(这里$EDITOR环境变量或'core.editor'这两个git配置变量的默认值都是vim)类似下面这样的内容:
    _
    # Please enter the commit message for your changes. Lines starting
    # with '#' will be ignored, and an empty message aborts the commit.
    # On branch main
    # Changes to be committed:
    #   (use "git reset HEAD ..." to unstage)
    #
    # modified:   README
    #                                                                     
    ~                                                                                     
    ~                                                                                     
    ".git/COMMIT_EDITMSG" 9L, 253C
    输入一些提交的信息,譬如"added myself to the README as an author"然后退出。
    vim操作提示:
    按下I,o,a进入编辑模式,编辑完毕按Esc,输入:wq保存退出。
    然后会看到这样的提示:

    [master]: created 5896d4d: "added myself to the README as an author"
     1 files changed, 2 insertions(+), 1 deletions(-)
     
    显示我们刚刚输入的提交信息,并且有一组关于这次提交项目中文件变更的统计数字。同时还给我们一个提交的校验和,'5896d4d',这个校验和可以用来日后确切的查看这次提交的细节。
    这就是简单用例。修改文件,'git commit -a',重复
    协作开发示例
    现在,我们来介绍一个复杂点的实例,这次我们使用远程仓库,将项目上传上去,从而跟其他的开发者一起协同工作。同时,我们会介绍staging area。
    如果你会从远程仓库中克隆项目,那么与远程仓库项目同步也是相当简单的--只需要执行'git pull'.如果是远程仓库项目没有变化,也就是说其他的开发者没有对项目进行变更,会显示这样的信息:
    Already up-to-date.
    相反,执行这条命令之后会将你上次同步之后远程仓库中的变更同步到本地项目中,并且git会合并这些新的变更:
    $ git pull
    Updating c264051..b04dc3d
    Fast forward
     lib/simplegit.rb |    4 ++++
     1 files changed, 4 insertions(+), 0 deletions(-)
    例子开始,重新克隆远程仓库中的项目,修改README文件和lib/simplegit.rb文件(不要执行git commit -a)。现在你可以使用'git status'命令来查看工作目录发生了什么变更:
    $ 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:   README
    modified:   lib/simplegit.rb
    #
    no changes added to commit (use "git add" and/or "git commit -a")
    我们看到,有两个文件是在"changed but not updated"段落中出现 ,这意味着这两个文件还没有载入(unstaged). 如果现在我们提交,什么也不会发生。也就是说文件必须先载入(stage),然后才能提交。
    所以,我们先来载入(stage) 文件,git中使用'git add'命令不仅可以开始追逐文件而且可以对他们载入stage变更。所以让我们载入(stage) README文件的变更,然后再来查看一下状态。
    $ git add README
    $ git status
    # On branch master
    # Changes to be committed:
    #   (use "git reset HEAD ..." to unstage)
    #
    # modified:   README
    #
    # Changed but not updated:
    #   (use "git add ..." to update what will be committed)
    #   (use "git checkout -- ..." to discard changes in working directory)
    #
    modified:   lib/simplegit.rb
    现在'lib/simplegit.rb'文件还是未载入(unstaged), 但是README文件现在已经到了'changes to be committed'段落中-它几经载入(stage)了。现在如果我们运行提交命令(不要-a,这个会自动stage所有的东西),只有这个文件会被提交-而simplegit.rb依然是unstaged。这时,我们使用-m选项来执行'git commit',这样后面跟上字符串表示这次提交的信息。
    $ git commit -m 'updated the README'
    [master]: created 14bb3c6: "updated the README"
     1 files changed, 1 insertions(+), 2 deletions(-)
    如果现在再执行'git status',我们会看到stage之后的文件现在已经提交了,只剩下了unstaged的'simplegit.rb'文件。
    $ git status
    # On branch master
    # Your branch is ahead of 'origin/master' by 1 commit.
    #
    # Changed but not updated:
    #   (use "git add ..." to update what will be committed)
    #   (use "git checkout -- ..." to discard changes in working directory)
    #
    modified:   lib/simplegit.rb
    #

    现在我们可以stage并且提交这个文件:
    $ git commit -a -m 'added a staging command to the library'
    [master]: created bbaee85: "added a staging command to the library"
     1 files changed, 4 insertions(+), 0 deletions(-)
    $ git status
    # On branch master
    # Your branch is ahead of 'origin/master' by 2 commits.
    #
    nothing to commit (working directory clean)
    现在我们已经将两次提交的变更都搞定了,而且加了提交信息,可以让我们的合作伙伴很容易理解我们做的变更。经过最后一次提交,我们看到'git status'执行之后显示我们的工作目录clean了(同时提示我们现在的分枝上有两个提交还没有上传)
    所以,现在我们将这些变更上传到服务器端与我们的合作伙伴分享,前提是我们有上传的权限,(如果没有上传的权限,我们可以在网络上创建一个自己的git仓库,将其上传),然后让朋友下载。
    运行'git push'会将我们的变更上传到服务器。
    $ git push
    Counting objects: 11, done.
    Compressing objects: 100% (6/6), done.
    Writing objects: 100% (7/7), 744 bytes, done.
    Total 7 (delta 3), reused 0 (delta 0)
    To git@github.com:schacon/simplegit.git
       b04dc3d..bbaee85  master -> master

    到目前为止,我们看到了新数据都已经上传完毕,服务器上的主分支也已经更新了。现在我们可以复习一下这整个的过程,让我们可以更加熟练的将git应用到我们的项目中去。
    阅读(2353) | 评论(0) | 转发(3) |
    给主人留下些什么吧!~~