Class: Rugged::Tree
- Inherits:
-
RuggedObject
- Object
- RuggedObject
- Rugged::Tree
- Includes:
- Enumerable
- Defined in:
- lib/rugged/tree.rb,
ext/rugged/rugged_tree.c
Defined Under Namespace
Classes: Builder
Instance Method Summary collapse
-
#[](entry_id) ⇒ Object
Return one of the entries from a tree as a
Hash
. -
#count ⇒ Object
Return the number of entries contained in the tree.
-
#diff(diffable[, options]) ⇒ Object
Returns a diff between the tree and the diffable object that was given.
-
#diff_workdir([options]) ⇒ Object
Returns a diff between a tree and the current workdir.
-
#each ⇒ Object
Call
block
with each of the entries of the subtree as aHash
. -
#each_blob ⇒ Object
Iterate over the blobs in this tree.
-
#each_tree ⇒ Object
Iterat over the subtrees in this tree.
-
#get_entry(entry_id) ⇒ Object
Return one of the entries from a tree as a
Hash
. -
#get_entry_by_oid(rb_oid) ⇒ Object
Return one of the entries from a tree as a
Hash
, based off the oid SHA. - #inspect ⇒ Object
-
#length ⇒ Object
Return the number of entries contained in the tree.
-
#path(path) ⇒ Object
Retrieve and return a tree entry by its relative path.
-
#walk(rb_mode) ⇒ Object
Walk
tree
with the given mode (either:preorder
or:postorder
) and yield toblock
every entry intree
and all its subtrees, as aHash
. -
#walk_blobs(mode = :postorder) ⇒ Object
Walks the tree but only yields blobs.
-
#walk_trees(mode = :postorder) ⇒ Object
Walks the tree but only yields subtrees.
Instance Method Details
#[](e) ⇒ Object #get_entry(e) ⇒ Object
Return one of the entries from a tree as a Hash
. If e
is a number, the enth entry from the tree will be returned. If e
is a string, the entry with that name will be returned.
If the entry doesn’t exist, nil
will be returned.
tree[3] #=> {:name => "foo.txt", :type => :blob, :oid => "d8786bfc97485e8d7b19b21fb88c8ef1f199fc3f", :filemode => 0}
tree['bar.txt'] #=> {:name => "bar.txt", :type => :blob, :oid => "de5ba987198bcf2518885f0fc1350e5172cded78", :filemode => 0}
tree['baz.txt'] #=> nil
107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'ext/rugged/rugged_tree.c', line 107
static VALUE rb_git_tree_get_entry(VALUE self, VALUE entry_id)
{
git_tree *tree;
Data_Get_Struct(self, git_tree, tree);
if (TYPE(entry_id) == T_FIXNUM)
return rb_git_treeentry_fromC(git_tree_entry_byindex(tree, FIX2INT(entry_id)));
else if (TYPE(entry_id) == T_STRING)
return rb_git_treeentry_fromC(git_tree_entry_byname(tree, StringValueCStr(entry_id)));
else
rb_raise(rb_eTypeError, "entry_id must be either an index or a filename");
}
|
#count ⇒ Object #length ⇒ Object
Return the number of entries contained in the tree.
Note that this only applies to entries in the root of the tree, not any other entries contained in sub-folders.
84 85 86 87 88 89 90 |
# File 'ext/rugged/rugged_tree.c', line 84
static VALUE rb_git_tree_entrycount(VALUE self)
{
git_tree *tree;
Data_Get_Struct(self, git_tree, tree);
return INT2FIX(git_tree_entrycount(tree));
}
|
#diff(diffable[, options]) ⇒ Object
Returns a diff between the tree and the diffable object that was given. diffable
can either be a Rugged::Commit
, a Rugged::Tree
, a Rugged::Index
, or nil
.
The tree
object will be used as the “old file” side of the diff, while the parent tree or the diffable
object will be used for the “new file” side.
If diffable
is nil, it will be treated as an empty tree.
The following options can be passed in the options
Hash:
- :paths
-
An array of paths / fnmatch patterns to constrain the diff to a specific set of files. Also see
:disable_pathspec_match
. - :max_size
-
An integer specifying the maximum byte size of a file before a it will be treated as binary. The default value is 512MB.
- :context_lines
-
The number of unchanged lines that define the boundary of a hunk (and to display before and after the actual changes). The default is 3.
- :interhunk_lines
-
The maximum number of unchanged lines between hunk boundaries before the hunks will be merged into a one. The default is 0.
- :reverse
-
If true, the sides of the diff will be reversed.
- :force_text
-
If true, all files will be treated as text, disabling binary attributes & detection.
- :ignore_whitespace
-
If true, all whitespace will be ignored.
- :ignore_whitespace_change
-
If true, changes in amount of whitespace will be ignored.
- :ignore_whitespace_eol
-
If true, whitespace at end of line will be ignored.
- :ignore_submodules
-
if true, submodules will be excluded from the diff completely.
- :patience
-
If true, the “patience diff” algorithm will be used (currenlty unimplemented).
- :include_ignored
-
If true, ignored files will be included in the diff.
- :include_untracked
-
If true, untracked files will be included in the diff.
- :include_unmodified
-
If true, unmodified files will be included in the diff.
- :recurse_untracked_dirs
-
Even if
:include_untracked
is true, untracked directories will only be marked with a single entry in the diff. If this flag is set to true, all files under ignored directories will be included in the diff, too. - :disable_pathspec_match
-
If true, the given
:paths
will be applied as exact matches, instead of as fnmatch patterns. - :deltas_are_icase
-
If true, filename comparisons will be made with case-insensitivity.
- :include_untracked_content
-
if true, untracked content will be contained in the the diff patch text.
- :skip_binary_check
-
If true, diff deltas will be generated without spending time on binary detection. This is useful to improve performance in cases where the actual file content difference is not needed.
- :include_typechange
-
If true, type changes for files will not be interpreted as deletion of the “old file” and addition of the “new file”, but will generate typechange records.
- :include_typechange_trees
-
Even if
:include_typechange
is true, blob -> tree changes will still usually be handled as a deletion of the blob. If this flag is set to true, blob -> tree changes will be marked as typechanges. - :ignore_filemode
-
If true, file mode changes will be ignored.
- :recurse_ignored_dirs
-
Even if
:include_ignored
is true, ignored directories will only be marked with a single entry in the diff. If this flag is set to true, all files under ignored directories will be included in the diff, too.
Examples:
# Emulating `git diff <treeish>`
tree = Rugged::Tree.lookup(repo, "d70d245ed97ed2aa596dd1af6536e4bfdb047b69")
diff = tree.diff(repo.index)
diff.merge!(tree.diff)
# Tree-to-Tree Diff
tree = Rugged::Tree.lookup(repo, "d70d245ed97ed2aa596dd1af6536e4bfdb047b69")
other_tree = Rugged::Tree.lookup(repo, "7a9e0b02e63179929fed24f0a3e0f19168114d10")
diff = tree.diff(other_tree)
382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 |
# File 'ext/rugged/rugged_tree.c', line 382
static VALUE rb_git_tree_diff(int argc, VALUE *argv, VALUE self)
{
git_tree *tree;
git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
git_repository *repo;
git_diff_list *diff = NULL;
VALUE owner, rb_other, rb_options;
int error;
rb_scan_args(argc, argv, "10:", &rb_other, &rb_options);
rugged_parse_diff_options(&opts, rb_options);
Data_Get_Struct(self, git_tree, tree);
owner = rugged_owner(self);
Data_Get_Struct(owner, git_repository, repo);
if (NIL_P(rb_other)) {
error = git_diff_tree_to_tree(&diff, repo, tree, NULL, &opts);
} else {
if (TYPE(rb_other) == T_STRING) {
rb_other = rugged_object_rev_parse(owner, rb_other, 1);
}
if (rb_obj_is_kind_of(rb_other, rb_cRuggedCommit)) {
git_tree *other_tree;
git_commit *commit;
Data_Get_Struct(rb_other, git_commit, commit);
error = git_commit_tree(&other_tree, commit);
if (!error) {
error = git_diff_tree_to_tree(&diff, repo, tree, other_tree, &opts);
git_tree_free(other_tree);
}
} else if (rb_obj_is_kind_of(rb_other, rb_cRuggedTree)) {
git_tree *other_tree;
Data_Get_Struct(rb_other, git_tree, other_tree);
error = git_diff_tree_to_tree(&diff, repo, tree, other_tree, &opts);
} else if (rb_obj_is_kind_of(rb_other, rb_cRuggedIndex)) {
git_index *index;
Data_Get_Struct(rb_other, git_index, index);
error = git_diff_tree_to_index(&diff, repo, tree, index, &opts);
} else {
xfree(opts.pathspec.strings);
rb_raise(rb_eTypeError, "A Rugged::Commit, Rugged::Tree or Rugged::Index instance is required");
}
}
xfree(opts.pathspec.strings);
rugged_exception_check(error);
return rugged_diff_new(rb_cRuggedDiff, self, diff);
}
|
#diff_workdir([options]) ⇒ Object
Returns a diff between a tree and the current workdir.
The tree
object will be used as the “old file” side of the diff, while the content of the current workdir will be used for the “new file” side.
See Rugged::Tree#diff for a list of options that can be passed.
448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 |
# File 'ext/rugged/rugged_tree.c', line 448
static VALUE rb_git_tree_diff_workdir(int argc, VALUE *argv, VALUE self)
{
git_tree *tree;
git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
git_repository *repo;
git_diff_list *diff;
VALUE owner, rb_options;
int error;
rb_scan_args(argc, argv, "00:", &rb_options);
rugged_parse_diff_options(&opts, rb_options);
Data_Get_Struct(self, git_tree, tree);
owner = rugged_owner(self);
Data_Get_Struct(owner, git_repository, repo);
error = git_diff_tree_to_workdir(&diff, repo, tree, &opts);
xfree(opts.pathspec.strings);
rugged_exception_check(error);
return rugged_diff_new(rb_cRuggedDiff, self, diff);
}
|
#each {|entry| ... } ⇒ Object #each ⇒ Object
Call block
with each of the entries of the subtree as a Hash
. If no block
is given, an enumerator
is returned instead.
Note that only the entries in the root of the tree are yielded; if you need to list also entries in subfolders, use tree.walk
instead.
tree.each { |entry| puts entry.inspect }
generates:
{:name => "foo.txt", :type => :blob, :oid => "d8786bfc97485e8d7b19b21fb88c8ef1f199fc3f", :filemode => 0}
{:name => "bar.txt", :type => :blob, :oid => "de5ba987198bcf2518885f0fc1350e5172cded78", :filemode => 0}
...
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 |
# File 'ext/rugged/rugged_tree.c', line 168
static VALUE rb_git_tree_each(VALUE self)
{
git_tree *tree;
size_t i, count;
Data_Get_Struct(self, git_tree, tree);
if (!rb_block_given_p())
return rb_funcall(self, rb_intern("to_enum"), 0);
count = git_tree_entrycount(tree);
for (i = 0; i < count; ++i) {
const git_tree_entry *entry = git_tree_entry_byindex(tree, i);
rb_yield(rb_git_treeentry_fromC(entry));
}
return Qnil;
}
|
#each_blob ⇒ Object
Iterate over the blobs in this tree
22 23 24 |
# File 'lib/rugged/tree.rb', line 22 def each_blob self.each { |e| yield e if e[:type] == :blob } end |
#each_tree ⇒ Object
Iterat over the subtrees in this tree
27 28 29 |
# File 'lib/rugged/tree.rb', line 27 def each_tree self.each { |e| yield e if e[:type] == :tree } end |
#[](e) ⇒ Object #get_entry(e) ⇒ Object
Return one of the entries from a tree as a Hash
. If e
is a number, the enth entry from the tree will be returned. If e
is a string, the entry with that name will be returned.
If the entry doesn’t exist, nil
will be returned.
tree[3] #=> {:name => "foo.txt", :type => :blob, :oid => "d8786bfc97485e8d7b19b21fb88c8ef1f199fc3f", :filemode => 0}
tree['bar.txt'] #=> {:name => "bar.txt", :type => :blob, :oid => "de5ba987198bcf2518885f0fc1350e5172cded78", :filemode => 0}
tree['baz.txt'] #=> nil
107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'ext/rugged/rugged_tree.c', line 107
static VALUE rb_git_tree_get_entry(VALUE self, VALUE entry_id)
{
git_tree *tree;
Data_Get_Struct(self, git_tree, tree);
if (TYPE(entry_id) == T_FIXNUM)
return rb_git_treeentry_fromC(git_tree_entry_byindex(tree, FIX2INT(entry_id)));
else if (TYPE(entry_id) == T_STRING)
return rb_git_treeentry_fromC(git_tree_entry_byname(tree, StringValueCStr(entry_id)));
else
rb_raise(rb_eTypeError, "entry_id must be either an index or a filename");
}
|
#get_entry_by_oid(rb_oid) ⇒ Object
Return one of the entries from a tree as a Hash
, based off the oid SHA.
If the entry doesn’t exist, nil
will be returned.
This does a full traversal of the every element in the tree, so this method is not especially fast.
tree.get_entry_by_oid("d8786bfc97485e8d7b19b21fb88c8ef1f199fc3f")
#=> {:name => "foo.txt", :type => :blob, :oid => "d8786bfc97485e8d7b19b21fb88c8ef1f199fc3f", :filemode => 0}
137 138 139 140 141 142 143 144 145 146 147 |
# File 'ext/rugged/rugged_tree.c', line 137
static VALUE rb_git_tree_get_entry_by_oid(VALUE self, VALUE rb_oid)
{
git_tree *tree;
git_oid oid;
Data_Get_Struct(self, git_tree, tree);
Check_Type(rb_oid, T_STRING);
rugged_exception_check(git_oid_fromstr(&oid, StringValueCStr(rb_oid)));
return rb_git_treeentry_fromC(git_tree_entry_byoid(tree, &oid));
}
|
#inspect ⇒ Object
5 6 7 8 9 |
# File 'lib/rugged/tree.rb', line 5 def inspect data = "#<Rugged::Tree:#{object_id} {oid: #{oid}}>\n" self.each { |e| data << " <\"#{e[:name]}\" #{e[:oid]}>\n" } data end |
#count ⇒ Object #length ⇒ Object
Return the number of entries contained in the tree.
Note that this only applies to entries in the root of the tree, not any other entries contained in sub-folders.
84 85 86 87 88 89 90 |
# File 'ext/rugged/rugged_tree.c', line 84
static VALUE rb_git_tree_entrycount(VALUE self)
{
git_tree *tree;
Data_Get_Struct(self, git_tree, tree);
return INT2FIX(git_tree_entrycount(tree));
}
|
#path(path) ⇒ Object
Retrieve and return a tree entry by its relative path.
253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 |
# File 'ext/rugged/rugged_tree.c', line 253
static VALUE rb_git_tree_path(VALUE self, VALUE rb_path)
{
int error;
git_tree *tree;
git_tree_entry *entry;
VALUE rb_entry;
Data_Get_Struct(self, git_tree, tree);
Check_Type(rb_path, T_STRING);
error = git_tree_entry_bypath(&entry, tree, StringValueCStr(rb_path));
rugged_exception_check(error);
rb_entry = rb_git_treeentry_fromC(entry);
git_tree_entry_free(entry);
return rb_entry;
}
|
#walk(mode) {|root, entry| ... } ⇒ Object #walk(mode) ⇒ Iterator
Walk tree
with the given mode (either :preorder
or :postorder
) and yield to block
every entry in tree
and all its subtrees, as a Hash
. The block
also takes a root
, the relative path in the traversal, starting from the root of the original tree.
If no block
is given, an Iterator
is returned instead.
tree.walk(:postorder) { |root, entry| puts "#{root}#{entry[:name]} [#{entry[:oid]}]" }
generates:
USAGE.rb [02bae86c91f96b5fdb6b1cf06f5aa3612139e318]
ext [23f135b3c576b6ac4785821888991d7089f35db1]
ext/rugged [25c88faa9302e34e16664eb9c990deb2bcf77849]
ext/rugged/extconf.rb [40c1aa8a8cec8ca444ed5758e3f00ecff093070a]
...
219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 |
# File 'ext/rugged/rugged_tree.c', line 219
static VALUE rb_git_tree_walk(VALUE self, VALUE rb_mode)
{
git_tree *tree;
int error, mode = 0;
ID id_mode;
Data_Get_Struct(self, git_tree, tree);
if (!rb_block_given_p())
return rb_funcall(self, rb_intern("to_enum"), 2, CSTR2SYM("walk"), rb_mode);
Check_Type(rb_mode, T_SYMBOL);
id_mode = SYM2ID(rb_mode);
if (id_mode == rb_intern("preorder"))
mode = GIT_TREEWALK_PRE;
else if (id_mode == rb_intern("postorder"))
mode = GIT_TREEWALK_POST;
else
rb_raise(rb_eTypeError,
"Invalid iteration mode. Expected `:preorder` or `:postorder`");
error = git_tree_walk(tree, mode, &rugged__treewalk_cb, (void *)rb_block_proc());
rugged_exception_check(error);
return Qnil;
}
|