文档章节

libgit2的ruby开发库rugged(一)

zouqilin
 zouqilin
发布于 2014/10/13 18:07
字数 2273
阅读 288
收藏 0

1.概念

    a.rugged是基于ruby语言开发的libgit2访问库, 提供了很好的速度和可移植性并且拥有ruby语言优美的特性.

    b.libgit2是一套git核心方法的纯c实现,被设计兼具速度和可移植性.

2.安装

    前提:首先当然按照ruby环境以及gem ruby包管理器(此处不介绍,可google),环境ubuntu

    安装命令如下:

    $>gem install rugged

    可能问题:包的依赖问题,亦可据错误google之

3.文档

    $>gem server

    可打开gem内置的web服务器,可以浏览所有安装的软件和它们的说明文档,打开http://localhost:8808

4.rugged库内部模块和常用类

   主要有一个module Rugged,其中拥有Rugged::Repository,Rugged::Commit,Rugged::Branch,

Rugged::BranchCollections,Rugged::Object,Rugged:Tag,Rugged::Config,Rugged::Remote,

Rugged::Index,Rugged::SettingsRugged::Reference,Rugged::Patch,Rugged::Tree,Rugged::Diff,

Rugged::Error,Rugged::Credentials等相关模块和类,后面会一一介绍.

5.简单上手一试

require 'rugged'
#导入rugged模块
 
repo = Rugged::Repository.new('/home/lry/workspace/ruby_test/git_test/.git')
#从参数给定的git路径打开git repository,返回Rugged::Repository对象
 
puts Rugged::Repository.discover("/home/lry/workspace/ruby_test/git_test/.git")
# => "/home/lry/workspace/ruby_test/git_test/.git"
 
puts repo.exists?('e6a40e934434e11d1e8dad08cb95a49e9d5b2aec')
#判断给定的sha1 oid表示的对象是否存在于repository中,sha1可通过在git status查看
# => true
 
puts repo.bare?
# => false
puts repo.empty?
#由于我的工作目录中存在已提交文件,所以一下为空
# => false
puts repo.head_detached?
# => false
 
puts repo.path
# => "/home/lry/workspace/ruby_test/git_test/.git/"
puts repo.workdir
# => "/home/lry/workspace/ruby_test/git_test/"
 
# The HEAD of the repository.
puts ref = repo.head
# => #<Rugged::Reference:0x00000002520218>

puts ref.name
# => "refs/heads/master"
ref.target
# => #<Rugged::Commit:0x00000002520150>

object = repo.read('e6a40e934434e11d1e8dad08cb95a49e9d5b2aec')
# => #<Rugged::Commit:0x00000002520150>
puts object.len
# => 171
puts object.data
# => "tree 203809dc435dd4e78d203cbf766a17581d77b2fa
      author ###
      committer ###
      
      add readme"
puts object.type
# => :commit

6.Rugged的类结构组织

    首先说明一下git, git存储每一个文件,而不是像svn一样纪录版本之间的差别。

    Repository包含很多Reference,Reference可以是是Reference或者Branch或者Tag或者AnnotationTag,Reference指向一个target,Reference类型type为:symbolic或者:direct, 如果type为:direct类型,则

target为Commit,否则为其他Reference。

    Reference如refs/heads/master, refs/remotes/origin/master, refs/heads/zql/master, refs/tags/v1.0

    Branch如refs/heads/master, refs/heads/zql/master,refs/remotes/origin/master

    Tag如refs/tags/v1.0

    AnnotationTag指加了message的tag


    Commit即提交,一个提交即代表一个版本,每个Commit包含了该版本的所有文件,如下图所示

a) Version 1包含文件A,B,C

b) 修改了文件A,C; 进化为Version 2, 包含文件A1,B,C1

c) 修改了文件C1;进化为Version 3,包含文件A1, B, C2

d) 修改了文件A1,B;进化为Version 4,包含文件A2,B1,C2

e) 修改了文件B1,C2; 进化为Version 5, 包含文件A2,B2, C3

上述代表了git的文件变迁历史。进一步说明,Commit指向一个Tree,Tree项目有Trees和Blobs以及Commits,Commit指向的Tree为根树,Tree代表一个目录,当然根树代表顶级目录,路径为"";Blob代表文件;Commit代表子模块。 每个目录下也可以拥有子目录和文件以及子模块;如下图所示:

每个Commit的parents指向其父提交,也即是其上一个提交(当然也可以有多个,如merge),如上述Version 5的父提交时Version 4。下图是Commit的组织方式:

值得注意的是,文件(目录)信息和内容是分开存储的,文件信息包含文件的oid,通过oid再去仓库通过idx去pack查找文件内容。

7.相关模块和类详解

    1).当然,最重要的类就是Rugged::Repository了,使用它我们可以操作磁盘上的git repository.

        a.初始化方法              

    bare(path[, alternates]) → repository

        打开一个bare git repository,参数path为的.git的路径(包括.git).返回Rugged::Repository表示该repository的对象

    init_at(path, is_bare = false) → repository
    示例:Rugged::Repository.init_at('~/repository', :bare) 
    #=> #<Rugged::Repository:0x108849488>

        若不存在则初始化repository,否则重新初始化,参数path为.git的上一级路径(不包括.git),参数is_bare表示是否以bare初始化repository,默认为false.返回Rugged::Repository表示该repository的对象

    new(path, options = {}) → repository
    示例:Rugged::Repository.new('~/test/.git') 
    #=> #<Rugged::Repository:0x108849488>
    Rugged::Repository.new(path, :alternates => ['./other/repo/.git/objects'])

         打开一个repository,参数path为.git的路径或者其上一级路径,options表示可选参数,接.git中子目录的路径.返回Rugged::Repository表示该repository的对象. 如果需要创建一个repository,请使用Rugged::init_at代替.

    clone_at(url, local_path[, options]) → repository
    示例:Repository.clone_at("https://github.com/libgit2/rugged.git", "./some/dir", 
    {  transfer_progress: lambda { |total_objects, indexed_objects, received_objects, 
        local_objects, total_deltas, indexed_deltas, received_bytes|
        # ...}
    })

      从远程地址得到一个git的拷贝.url为项目仓库的地址,local_path为本地拷贝的目录.返回Rugged::Repository表示该repository的对象.

    options有如下Hash选项:

  • :bare

  • Iftrue, the clone will be created as a bare repository. Defaults tofalse.

  • :checkout_branch

  • The name of a branch to checkout. Defaults to the remote’sHEAD.

  • :remote

  • The name to give to the “origin” remote. Defaults to"origin".

  • :ignore_cert_errors

  • If set totrue, errors while validating the remote’s host certificate will be ignored.

  • :credentials

  • The credentials to use for the clone operation. Can be either an instance of one of the Rugged::Credentials types, or a proc returning one of the former. The proc will be called with theurl, theusernamefrom the url (if applicable) and a list of applicable credential types.

  • :progress

  • A callback that will be executed with the textual progress received from the remote. This is the text send over the progress side-band (ie. the “counting objects” output).

  • :transfer_progress

  • A callback that will be executed to report clone progress information. It will be passed the amount oftotal_objects,indexed_objects,received_objects,local_objects,total_deltas,indexed_deltas, andreceived_bytes.

  • :update_tips

  • A callback that will be executed each time a reference was updated locally. It will be passed therefname,old_oidandnew_oid.

        b.基本方法

    discover(path = nil, across_fs = true) → repository

    由path传递的路径向上搜索.git文件夹,然后打开并生成一个Rugged::Repository对象,如果path为nil,则以当前路径为起始点

    hash_data(str, type) → oid
    Repository.hash_data('hello world', :commit) #=> "de5ba987198bcf2518885f0fc1350e5172cded78"
    Repository.hash_data('hello_world', :tag) #=> "9d09060c850defbc7711d08b57def0d14e742f4e"

    返回str的hash值.将str作为原始数据加上type相应的头部进行散列.返回该结果的hash值字符串

    hash_file(path, type) → oid

    返回path指向的文件的hash值.返回sha1值的字符串

    create_branch(name, sha_or_ref = "HEAD")

        在仓库中创建分支,name指定分支名,sha_ora_ref目标分支,可以为oid,reference name或者Rugged::Object实例.返回Rugged::Branch对象

    branches()

        返回当前repository中的分支,返回Rugged::Branch的BranchCollection对象集合

    checkout(target, options = {})

        切换到由target指定的branch, reference or commit.

    checkout_head([options]) → nil

        切换到HEAD

    ref(ref_name) 
    示例:repo.ref 'refs/heads/master'
    # => #<Rugged::Reference:2199125780 {name: "refs/heads/master",
         target: "25b5d3b40c4eadda8098172b26c68cf151109799"}>

        查找ref_name制定的Rugged::Reference对象

    ref_names(glob = nil)  
    references()#得到仓库中的所有Referece,ReferenceCollection表示
    refs(glob = nil)
    head → ref

        获取指向repository Head的Rugged::Reference对象

    head = str

        设置repository的Head

    index → idx
    index = idx

        获取或设置repository的默认的index,idx为Rugged::Index对象

    namespace → str
    namespace = new_namespace

        设置或设置repository的活动命名空间

    path → path

        获取完整的,标准的.git的路径

    workdir → path or nil
    workdir = path

        获取或设置repository的工作目录

    config → cfg
    config = cfg

        获取和设置配置.cfg为Rugged::Config对象

    lookup(oid)

        查找一个SHA1,返回继承Rugged::Object四个类中的某一个类的对象

    exists?(oid) → true or false

        是否给定的SHA1 OID (represented as a 40-character string)存在于repository

    include?(oid) → true or false
    repo.include?("d8786bfc97485e8d7b19b21fb88c8ef1f199fc3f") #=> true

        是否给定的SHA1 OID (represented as a 40-character string)存在于repository

    tags()

       获取repository的所有tag.返回Rugged::Tag的集合Rugged::TagCollection对象

    remotes()

        获取repository的所有remotes. 返回Rugged::Remote的集合Rugged::RemoteCollection对象

    push(remote_or_url, *args)

        推送refspecs到remote_or_url.返回refspecs为键值,如果成功值为nil,失败为错误消息

    last_commit()

        获取最后一次commit, 返回Rugged::Commit对象

    read(oid) → str

        读取oid对象标识的对象原始数据

    read_header(oid) → hash

        读取repository的Head信息.返回一个Hash对象,可能的键值对如下

        :type =>A Symbol denoting the object’s type.可能的值:tree,:blob,:commit或:tag.

        :len =>上述对象的长度

    rev_parse(spec)

        通过revision字符串查找对象.返回继承Rugged::Object四个类中的某一个类的对象

    rev_parse_oid(spec)

        通过revision字符串查找oid.返回匹配revision的oid

    write(buffer, type) → oid

        将buffer中的数据作为被给定类型type写入repository’s object database.

        type可取值为:tag,:commit,:treeor:blob.

        返回新建对象的oid

    blob_at(revision, path)

        获取指定路径path的revision的blob.

        revision - The String SHA1.

        path     - The String file path.

        返回字符串

    diff(left, right, opts = {}) 
    diff_workdir(left, opts = {})

        指定两个版本的diff

    merge_base(oid1, oid2, ...)          
    merge_base(ref1, ref2, ...)          
    merge_base(commit1, commit2, ...)

        找到合并的base

    merge_commits(our_commit, their_commit, options = {}) → index

        合并操作.our_commitandtheir_commitcan either be Rugged::Commit objects, or OIDs resolving to the former. 返回合并后的Rugged::Index对象

    each_id { |id| block }          
    each_id → Iterator

        对在repository中发现的每一个object ID执行块迭代,id为40个字符的字符串

    status { |file, status_data| block }          
    status(path) → status_data
    示例:repo.status { |file, status_data| puts "#{file} has status: #{status_data.inspect}" }
    repo.status('src/diff.c') #=> [:index_new, :worktree_new]

        获取工作目录中文件的状态.

        c.操作对象数据库

    read(oid)
    示例:object = repo.read('a0ae5566e3c8a3bddffab21022056f0b5e03ef07')
    # => #<Rugged::OdbObject:0x109a64780>

            通过oid读取Rugged::OdbObject对象

    Rugged::OdbObject.data()
    Rugged::OdbObject.len()
    Rugged::OdbObject.type()
    Rugged::OdbObject.oid()
    示例:object.len# => 237
    object.data
    # => "tree 76f23f186076fc291742816721ea8c3e95567241\nparent 8e3c5c52b8f29da0adc7e8be8a037cbeaea6de6b\nauthor Vicent Mart\303\255 <tanoku@gmail.com> 1333859005 +0200\ncommitter Vicent Mart\303\255 <tanoku@gmail.com> 1333859005 +0200\n\nAdd `Repository#blob_at`\n"
    object.type# => :commit
    object.oid#=> "d8786bfc97485e8d7b19b21fb88c8ef1f199fc3f"

以上是Rugged::Repository提供的方法.


© 著作权归作者所有

zouqilin

zouqilin

粉丝 44
博文 9
码字总数 4504
作品 0
深圳
后端工程师
私信 提问
加载中

评论(1)

moli
moli
顶一个
Git仓库文件版本号遍历算法的优化

背景: 目前Git@OSC使用的基于libgit2的Rugged(http://github.com/libgit2/rugged) Git开发库,替换了原来Gitlab的底层Grit Git开发库,目前遇到的问题时在查找文件的提交历史上效率相当低下...

Zoker
2015/10/09
37
5
Git开发包--libgit2

libgit2 是一个可移植、纯C语言实现的 Git 核心开发包,你可以使用它来编写自定义的 Git 应用。 libgit2已被广泛应用在许多应用程序上,包括GitHub网站,还被应用在Plastic SCM和强大的微软V...

匿名
2010/11/30
6.5K
3
rugged 进行git push 操作时 报了401错误

@zouqilin 你好,想跟你请教个问题:我在使用rugged 进行git push 操作时 报了401错误。 C:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/rugged-0.24.0/lib/rugged/repository.rb:22 4:in `push': ......

imzack
2016/04/07
324
3
基于gollum的wiki搭建

基于gollum的wiki搭建 gollum是个啥 gollum是一个基于git的,解析markdown文件的wiki系统;gollum项目托管在github上:gollum (https://github.com/gollum/gollum),项目的wiki地址:https...

alex
2016/07/12
1K
0
libgit2 0.27.1 发布,Git 核心开发包

libgit2 0.27.1 发布了,此版本这是一个安全发布,修复了对子模块名称的验证不足的问题(CVE-2018-11235)。 当子模块名称来自不可信的“.gitmodules”文件时,我们将其盲目追加到 $GIT_DIR...

h4cd
2018/05/31
429
0

没有更多内容

加载失败,请刷新页面

加载更多

基于Prometheus和Grafana的监控平台 - 环境搭建

相关概念 微服务中的监控分根据作用领域分为三大类,Logging,Tracing,Metrics。 Logging - 用于记录离散的事件。例如,应用程序的调试信息或错误信息。它是我们诊断问题的依据。比如我们说...

JAVA日知录
53分钟前
5
0
PHP运行时全局构造体

struct _php_core_globals { zend_bool magic_quotes_gpc; // 是否对输入的GET/POST/Cookie数据使用自动字符串转义。 zend_bool magic_quotes_runtime; //是否对运行时从外部资源产生的数据使...

冻结not
54分钟前
4
0
webpack插件html-webpack-plugin

本文转载于:专业的前端网站→webpack插件html-webpack-plugin 1、插件安装 npm install html-webpack-plugin --save-dev 2、插件使用 webpack.config.js配置文件为: var htmlWebpackPlugin=...

前端老手
今天
6
0
数据挖掘

zhengchen1996
今天
4
0
nginx配置反向代理

文章来源 运维公会:nginx配置反向代理 1、简介 Nginx最为常见的一种功能就是配置反向代理。配置也是十分的简单,只需要用到proxy模块即可。 怎么查看nginx默认的安装模块? 在nginx的安装目...

运维团
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部