rugged 0.18.0.gh.de28323 → 0.19.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +9 -4
- data/Rakefile +1 -1
- data/ext/rugged/extconf.rb +10 -0
- data/ext/rugged/rugged.c +153 -86
- data/ext/rugged/rugged.h +44 -33
- data/ext/rugged/rugged_blob.c +288 -60
- data/ext/rugged/rugged_branch.c +82 -57
- data/ext/rugged/rugged_commit.c +83 -86
- data/ext/rugged/rugged_config.c +68 -68
- data/ext/rugged/rugged_diff.c +509 -0
- data/ext/rugged/rugged_diff_delta.c +94 -0
- data/ext/rugged/rugged_diff_hunk.c +100 -0
- data/ext/rugged/rugged_diff_line.c +79 -0
- data/ext/rugged/rugged_diff_patch.c +169 -0
- data/ext/rugged/rugged_index.c +539 -8
- data/ext/rugged/rugged_note.c +74 -80
- data/ext/rugged/rugged_object.c +63 -8
- data/ext/rugged/rugged_reference.c +231 -145
- data/ext/rugged/rugged_remote.c +509 -53
- data/ext/rugged/rugged_repo.c +572 -236
- data/ext/rugged/rugged_revwalk.c +59 -36
- data/ext/rugged/rugged_settings.c +7 -9
- data/ext/rugged/rugged_signature.c +7 -11
- data/ext/rugged/rugged_tag.c +93 -39
- data/ext/rugged/rugged_tree.c +321 -58
- data/lib/rugged.rb +1 -0
- data/lib/rugged/commit.rb +16 -1
- data/lib/rugged/console.rb +9 -0
- data/lib/rugged/diff.rb +19 -0
- data/lib/rugged/diff/delta.rb +54 -0
- data/lib/rugged/diff/hunk.rb +23 -0
- data/lib/rugged/diff/line.rb +29 -0
- data/lib/rugged/diff/patch.rb +28 -0
- data/lib/rugged/repository.rb +36 -39
- data/lib/rugged/version.rb +1 -1
- data/test/blob_test.rb +308 -1
- data/test/branch_test.rb +7 -0
- data/test/commit_test.rb +7 -10
- data/test/coverage/cover.rb +9 -1
- data/test/diff_test.rb +777 -0
- data/test/fixtures/archive.tar.gz +0 -0
- data/test/fixtures/attr/attr0 +1 -0
- data/test/fixtures/attr/attr1 +29 -0
- data/test/fixtures/attr/attr2 +21 -0
- data/test/fixtures/attr/attr3 +4 -0
- data/test/fixtures/attr/binfile +1 -0
- data/test/fixtures/attr/dir/file +0 -0
- data/test/fixtures/attr/file +1 -0
- data/test/fixtures/attr/gitattributes +29 -0
- data/test/fixtures/attr/gitignore +2 -0
- data/test/fixtures/attr/ign +1 -0
- data/test/fixtures/attr/macro_bad +1 -0
- data/test/fixtures/attr/macro_test +1 -0
- data/test/fixtures/attr/root_test1 +1 -0
- data/test/fixtures/attr/root_test2 +6 -0
- data/test/fixtures/attr/root_test3 +19 -0
- data/test/fixtures/attr/root_test4.txt +14 -0
- data/test/fixtures/attr/sub/abc +37 -0
- data/test/fixtures/attr/sub/dir/file +0 -0
- data/test/fixtures/attr/sub/file +1 -0
- data/test/fixtures/attr/sub/ign/file +1 -0
- data/test/fixtures/attr/sub/ign/sub/file +1 -0
- data/test/fixtures/attr/sub/sub/dir +0 -0
- data/test/fixtures/attr/sub/sub/file +1 -0
- data/test/fixtures/attr/sub/sub/subsub.txt +1 -0
- data/test/fixtures/attr/sub/subdir_test1 +2 -0
- data/test/fixtures/attr/sub/subdir_test2.txt +1 -0
- data/test/fixtures/diff/another.txt +38 -0
- data/test/fixtures/diff/readme.txt +36 -0
- data/test/fixtures/mergedrepo/conflicts-one.txt +5 -0
- data/test/fixtures/mergedrepo/conflicts-two.txt +5 -0
- data/test/fixtures/mergedrepo/one.txt +10 -0
- data/test/fixtures/mergedrepo/two.txt +12 -0
- data/test/fixtures/status/current_file +1 -0
- data/test/fixtures/status/ignored_file +1 -0
- data/test/fixtures/status/modified_file +2 -0
- data/test/fixtures/status/new_file +1 -0
- data/test/fixtures/status/staged_changes +2 -0
- data/test/fixtures/status/staged_changes_modified_file +3 -0
- data/test/fixtures/status/staged_delete_modified_file +1 -0
- data/test/fixtures/status/staged_new_file +1 -0
- data/test/fixtures/status/staged_new_file_modified_file +2 -0
- data/test/fixtures/status/subdir.txt +2 -0
- data/test/fixtures/status/subdir/current_file +1 -0
- data/test/fixtures/status/subdir/modified_file +2 -0
- data/test/fixtures/status/subdir/new_file +1 -0
- data/test/fixtures/status//350/277/231 +1 -0
- data/test/fixtures/testrepo.git/config +5 -0
- data/test/fixtures/testrepo.git/objects/77/71329dfa3002caf8c61a0ceb62a31d09023f37 +0 -0
- data/test/fixtures/text_file.md +464 -0
- data/test/fixtures/unsymlinked.git/HEAD +1 -0
- data/test/fixtures/unsymlinked.git/config +6 -0
- data/test/fixtures/unsymlinked.git/description +1 -0
- data/test/fixtures/unsymlinked.git/info/exclude +2 -0
- data/test/fixtures/unsymlinked.git/objects/08/8b64704e0d6b8bd061dea879418cb5442a3fbf +0 -0
- data/test/fixtures/unsymlinked.git/objects/13/a5e939bca25940c069fd2169d993dba328e30b +0 -0
- data/test/fixtures/unsymlinked.git/objects/19/bf568e59e3a0b363cafb4106226e62d4a4c41c +0 -0
- data/test/fixtures/unsymlinked.git/objects/58/1fadd35b4cf320d102a152f918729011604773 +0 -0
- data/test/fixtures/unsymlinked.git/objects/5c/87b6791e8b13da658a14d1ef7e09b5dc3bac8c +0 -0
- data/test/fixtures/unsymlinked.git/objects/6f/e5f5398af85fb3de8a6aba0339b6d3bfa26a27 +0 -0
- data/test/fixtures/unsymlinked.git/objects/7f/ccd75616ec188b8f1b23d67506a334cc34a49d +0 -0
- data/test/fixtures/unsymlinked.git/objects/80/6999882bf91d24241e4077906b9017605eb1f3 +0 -0
- data/test/fixtures/unsymlinked.git/objects/83/7d176303c5005505ec1e4a30231c40930c0230 +0 -0
- data/test/fixtures/unsymlinked.git/objects/a8/595ccca04f40818ae0155c8f9c77a230e597b6 +2 -0
- data/test/fixtures/unsymlinked.git/objects/cf/8f1cf5cce859c438d6cc067284cb5e161206e7 +0 -0
- data/test/fixtures/unsymlinked.git/objects/d5/278d05c8607ec420bfee4cf219fbc0eeebfd6a +0 -0
- data/test/fixtures/unsymlinked.git/objects/f4/e16fb76536591a41454194058d048d8e4dd2e9 +0 -0
- data/test/fixtures/unsymlinked.git/objects/f9/e65619d93fdf2673882e0a261c5e93b1a84006 +0 -0
- data/test/fixtures/unsymlinked.git/refs/heads/exe-file +1 -0
- data/test/fixtures/unsymlinked.git/refs/heads/master +1 -0
- data/test/fixtures/unsymlinked.git/refs/heads/reg-file +1 -0
- data/test/index_test.rb +120 -0
- data/test/reference_test.rb +38 -3
- data/test/remote_test.rb +224 -3
- data/test/repo_reset_test.rb +2 -0
- data/test/repo_test.rb +147 -10
- data/test/test_helper.rb +5 -2
- data/vendor/libgit2/include/git2/attr.h +3 -3
- data/vendor/libgit2/include/git2/blob.h +11 -17
- data/vendor/libgit2/include/git2/branch.h +3 -2
- data/vendor/libgit2/include/git2/checkout.h +7 -0
- data/vendor/libgit2/include/git2/clone.h +3 -0
- data/vendor/libgit2/include/git2/commit.h +61 -66
- data/vendor/libgit2/include/git2/common.h +73 -42
- data/vendor/libgit2/include/git2/config.h +57 -71
- data/vendor/libgit2/include/git2/cred_helpers.h +2 -2
- data/vendor/libgit2/include/git2/diff.h +179 -30
- data/vendor/libgit2/include/git2/errors.h +3 -3
- data/vendor/libgit2/include/git2/index.h +225 -146
- data/vendor/libgit2/include/git2/indexer.h +2 -22
- data/vendor/libgit2/include/git2/inttypes.h +9 -9
- data/vendor/libgit2/include/git2/merge.h +123 -5
- data/vendor/libgit2/include/git2/odb.h +59 -38
- data/vendor/libgit2/include/git2/odb_backend.h +45 -104
- data/vendor/libgit2/include/git2/oid.h +30 -19
- data/vendor/libgit2/include/git2/pack.h +21 -3
- data/vendor/libgit2/include/git2/refdb.h +0 -35
- data/vendor/libgit2/include/git2/refs.h +93 -31
- data/vendor/libgit2/include/git2/refspec.h +17 -0
- data/vendor/libgit2/include/git2/remote.h +60 -20
- data/vendor/libgit2/include/git2/repository.h +48 -70
- data/vendor/libgit2/include/git2/reset.h +3 -3
- data/vendor/libgit2/include/git2/revparse.h +22 -0
- data/vendor/libgit2/include/git2/stash.h +1 -1
- data/vendor/libgit2/include/git2/status.h +131 -56
- data/vendor/libgit2/include/git2/strarray.h +2 -2
- data/vendor/libgit2/include/git2/submodule.h +16 -16
- data/vendor/libgit2/include/git2/sys/commit.h +46 -0
- data/vendor/libgit2/include/git2/sys/config.h +71 -0
- data/vendor/libgit2/include/git2/sys/index.h +179 -0
- data/vendor/libgit2/include/git2/sys/odb_backend.h +86 -0
- data/vendor/libgit2/include/git2/sys/refdb_backend.h +158 -0
- data/vendor/libgit2/include/git2/sys/refs.h +38 -0
- data/vendor/libgit2/include/git2/sys/repository.h +106 -0
- data/vendor/libgit2/include/git2/tag.h +44 -18
- data/vendor/libgit2/include/git2/trace.h +1 -2
- data/vendor/libgit2/include/git2/transport.h +74 -0
- data/vendor/libgit2/include/git2/tree.h +12 -22
- data/vendor/libgit2/include/git2/types.h +33 -0
- data/vendor/libgit2/include/git2/version.h +2 -2
- data/vendor/libgit2/src/array.h +66 -0
- data/vendor/libgit2/src/attr.c +26 -13
- data/vendor/libgit2/src/attr_file.c +3 -2
- data/vendor/libgit2/src/attr_file.h +3 -3
- data/vendor/libgit2/src/attrcache.h +4 -4
- data/vendor/libgit2/src/blob.c +13 -9
- data/vendor/libgit2/src/blob.h +2 -2
- data/vendor/libgit2/src/branch.c +67 -49
- data/vendor/libgit2/src/cache.c +224 -54
- data/vendor/libgit2/src/cache.h +33 -20
- data/vendor/libgit2/src/checkout.c +145 -85
- data/vendor/libgit2/src/clone.c +62 -50
- data/vendor/libgit2/src/commit.c +74 -40
- data/vendor/libgit2/src/commit.h +2 -3
- data/vendor/libgit2/src/commit_list.c +14 -8
- data/vendor/libgit2/src/config.c +119 -36
- data/vendor/libgit2/src/config.h +3 -0
- data/vendor/libgit2/src/config_cache.c +24 -7
- data/vendor/libgit2/src/config_file.c +9 -6
- data/vendor/libgit2/src/crlf.c +4 -2
- data/vendor/libgit2/src/date.c +3 -3
- data/vendor/libgit2/src/delta.c +1 -1
- data/vendor/libgit2/src/diff.c +681 -303
- data/vendor/libgit2/src/diff.h +34 -2
- data/vendor/libgit2/src/diff_driver.c +405 -0
- data/vendor/libgit2/src/diff_driver.h +49 -0
- data/vendor/libgit2/src/diff_file.c +447 -0
- data/vendor/libgit2/src/diff_file.h +58 -0
- data/vendor/libgit2/src/diff_patch.c +995 -0
- data/vendor/libgit2/src/diff_patch.h +46 -0
- data/vendor/libgit2/src/diff_print.c +430 -0
- data/vendor/libgit2/src/diff_tform.c +464 -203
- data/vendor/libgit2/src/diff_xdiff.c +166 -0
- data/vendor/libgit2/src/diff_xdiff.h +28 -0
- data/vendor/libgit2/src/fetch.c +11 -4
- data/vendor/libgit2/src/fileops.c +85 -61
- data/vendor/libgit2/src/fileops.h +4 -0
- data/vendor/libgit2/src/global.c +10 -2
- data/vendor/libgit2/src/global.h +0 -8
- data/vendor/libgit2/src/hash/hash_generic.h +3 -3
- data/vendor/libgit2/src/hash/hash_win32.h +4 -4
- data/vendor/libgit2/src/hashsig.c +0 -1
- data/vendor/libgit2/src/ignore.c +68 -28
- data/vendor/libgit2/src/ignore.h +10 -1
- data/vendor/libgit2/src/index.c +666 -84
- data/vendor/libgit2/src/index.h +6 -0
- data/vendor/libgit2/src/indexer.c +10 -28
- data/vendor/libgit2/src/iterator.c +427 -283
- data/vendor/libgit2/src/iterator.h +58 -4
- data/vendor/libgit2/src/merge.c +1892 -32
- data/vendor/libgit2/src/merge.h +132 -5
- data/vendor/libgit2/src/merge_file.c +174 -0
- data/vendor/libgit2/src/merge_file.h +71 -0
- data/vendor/libgit2/src/mwindow.c +1 -1
- data/vendor/libgit2/src/notes.c +45 -48
- data/vendor/libgit2/src/object.c +89 -127
- data/vendor/libgit2/src/object.h +0 -1
- data/vendor/libgit2/src/object_api.c +129 -0
- data/vendor/libgit2/src/odb.c +156 -59
- data/vendor/libgit2/src/odb.h +5 -2
- data/vendor/libgit2/src/odb_loose.c +31 -17
- data/vendor/libgit2/src/odb_pack.c +39 -43
- data/vendor/libgit2/src/oid.c +62 -27
- data/vendor/libgit2/src/oid.h +33 -0
- data/vendor/libgit2/src/oidmap.h +4 -6
- data/vendor/libgit2/src/pack-objects.c +54 -22
- data/vendor/libgit2/src/pack.c +98 -56
- data/vendor/libgit2/src/pack.h +3 -1
- data/vendor/libgit2/src/pathspec.c +26 -1
- data/vendor/libgit2/src/pathspec.h +14 -0
- data/vendor/libgit2/src/pool.c +5 -0
- data/vendor/libgit2/src/posix.c +2 -2
- data/vendor/libgit2/src/posix.h +3 -0
- data/vendor/libgit2/src/push.c +13 -10
- data/vendor/libgit2/src/refdb.c +82 -62
- data/vendor/libgit2/src/refdb.h +16 -16
- data/vendor/libgit2/src/refdb_fs.c +386 -133
- data/vendor/libgit2/src/reflog.c +3 -1
- data/vendor/libgit2/src/refs.c +247 -221
- data/vendor/libgit2/src/refs.h +2 -1
- data/vendor/libgit2/src/refspec.c +18 -1
- data/vendor/libgit2/src/refspec.h +3 -1
- data/vendor/libgit2/src/remote.c +434 -253
- data/vendor/libgit2/src/remote.h +5 -3
- data/vendor/libgit2/src/repository.c +197 -111
- data/vendor/libgit2/src/repository.h +26 -5
- data/vendor/libgit2/src/reset.c +1 -1
- data/vendor/libgit2/src/revparse.c +84 -79
- data/vendor/libgit2/src/revwalk.c +1 -1
- data/vendor/libgit2/src/signature.c +22 -10
- data/vendor/libgit2/src/stash.c +5 -2
- data/vendor/libgit2/src/status.c +311 -107
- data/vendor/libgit2/src/status.h +23 -0
- data/vendor/libgit2/src/submodule.c +21 -13
- data/vendor/libgit2/src/tag.c +42 -31
- data/vendor/libgit2/src/tag.h +2 -3
- data/vendor/libgit2/src/thread-utils.h +105 -3
- data/vendor/libgit2/src/trace.c +1 -2
- data/vendor/libgit2/src/trace.h +3 -3
- data/vendor/libgit2/src/transport.c +18 -6
- data/vendor/libgit2/src/transports/cred.c +103 -1
- data/vendor/libgit2/src/transports/local.c +19 -9
- data/vendor/libgit2/src/transports/smart_protocol.c +32 -12
- data/vendor/libgit2/src/transports/ssh.c +519 -0
- data/vendor/libgit2/src/transports/winhttp.c +3 -1
- data/vendor/libgit2/src/tree.c +26 -28
- data/vendor/libgit2/src/tree.h +3 -3
- data/vendor/libgit2/src/unix/posix.h +2 -0
- data/vendor/libgit2/src/util.c +43 -6
- data/vendor/libgit2/src/util.h +40 -12
- data/vendor/libgit2/src/vector.c +3 -5
- data/vendor/libgit2/src/vector.h +9 -0
- data/vendor/libgit2/src/win32/dir.c +1 -1
- data/vendor/libgit2/src/win32/error.c +2 -0
- data/vendor/libgit2/src/win32/findfile.c +3 -6
- data/vendor/libgit2/src/win32/posix_w32.c +85 -59
- data/vendor/libgit2/src/win32/pthread.c +16 -8
- data/vendor/libgit2/src/win32/pthread.h +7 -4
- metadata +407 -306
- data/test/coverage/HEAD.json +0 -1
- data/vendor/libgit2/include/git2/refdb_backend.h +0 -109
- data/vendor/libgit2/src/diff_output.c +0 -1819
- data/vendor/libgit2/src/diff_output.h +0 -93
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
* binary
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# a comment followed by some blank lines
|
2
|
+
|
3
|
+
|
4
|
+
|
5
|
+
# another comment that is indented
|
6
|
+
|
7
|
+
# variations on fnmatch
|
8
|
+
|
9
|
+
pat0 attr0
|
10
|
+
!pat1 attr1
|
11
|
+
pat2/ attr2
|
12
|
+
pat3dir/pat3file attr3
|
13
|
+
pat4.* attr4
|
14
|
+
*.pat5 attr5
|
15
|
+
pat6/pat6/*.pat6 attr6
|
16
|
+
|
17
|
+
pat7[a-e]??[xyz] attr7 # with a comment on the line
|
18
|
+
|
19
|
+
pat8\ with\ spaces attr8
|
20
|
+
|
21
|
+
invalid # attr with no assignments doesn't count
|
22
|
+
|
23
|
+
also/invalid
|
24
|
+
|
25
|
+
invalid.again/
|
26
|
+
|
27
|
+
# next attr is at eof
|
28
|
+
|
29
|
+
pat9 attr9
|
@@ -0,0 +1,21 @@
|
|
1
|
+
|
2
|
+
# variations on assignments
|
3
|
+
|
4
|
+
pat0 simple
|
5
|
+
pat1 -neg
|
6
|
+
* notundef
|
7
|
+
pat2 !notundef
|
8
|
+
pat3 assigned=test-value
|
9
|
+
pat4 rule-with-more-chars=value-with-more-chars
|
10
|
+
pat5 empty=
|
11
|
+
pat6 -negempty=
|
12
|
+
pat7 multiple -single values=1 also=a-really-long-value/* happy=yes!
|
13
|
+
# the next line has trailing spaces
|
14
|
+
pat8 again= another=12321
|
15
|
+
patbad0 # empty assignment does not count
|
16
|
+
# next line will be another simple empty assign that should not count
|
17
|
+
patbad1
|
18
|
+
|
19
|
+
# BTW I think there are 11 valid rules and two "invalid" empty ones
|
20
|
+
|
21
|
+
pat9 -at-eof
|
@@ -0,0 +1 @@
|
|
1
|
+
123
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
hi
|
@@ -0,0 +1,29 @@
|
|
1
|
+
* rootattr
|
2
|
+
root_test2 -rootattr
|
3
|
+
root_test3 !rootattr
|
4
|
+
binfile binary
|
5
|
+
abc foo bar baz
|
6
|
+
does-not-exist foo=yes
|
7
|
+
|
8
|
+
root_test2 multiattr
|
9
|
+
root_test3 multi2=foo
|
10
|
+
|
11
|
+
root_test3 multiattr=1 multiattr=2 multiattr=3 multi2=abc !multi2
|
12
|
+
root_test2 multiattr=string -multiattr
|
13
|
+
|
14
|
+
[attr]mymacro positive -negative !rootattr
|
15
|
+
macro* mymacro another=77
|
16
|
+
|
17
|
+
[attr]macro2 multi2 -multi2 multi3 !multi3 multi3=answer
|
18
|
+
macro* macro2 macro2 macro2
|
19
|
+
|
20
|
+
# let's try some malicious macro defs
|
21
|
+
[attr]firstmacro -thirdmacro -secondmacro
|
22
|
+
[attr]secondmacro firstmacro -firstmacro
|
23
|
+
[attr]thirdmacro secondmacro=hahaha
|
24
|
+
|
25
|
+
macro_bad firstmacro secondmacro thirdmacro
|
26
|
+
|
27
|
+
# another test that Peff found was failing
|
28
|
+
[attr]notest !test
|
29
|
+
|
@@ -0,0 +1 @@
|
|
1
|
+
ignore me
|
@@ -0,0 +1 @@
|
|
1
|
+
boo
|
@@ -0,0 +1 @@
|
|
1
|
+
Yo
|
@@ -0,0 +1 @@
|
|
1
|
+
Hello from the root
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# Test file from gitattributes(5) example:
|
2
|
+
|
3
|
+
If you have these three gitattributes file:
|
4
|
+
|
5
|
+
(in $GIT_DIR/info/attributes)
|
6
|
+
|
7
|
+
a* foo !bar -baz
|
8
|
+
|
9
|
+
(in .gitattributes)
|
10
|
+
abc foo bar baz
|
11
|
+
|
12
|
+
(in t/.gitattributes)
|
13
|
+
ab* merge=filfre
|
14
|
+
abc -foo -bar
|
15
|
+
*.c frotz
|
16
|
+
|
17
|
+
the attributes given to path t/abc are computed as follows:
|
18
|
+
|
19
|
+
1. By examining t/.gitattributes (which is in the same directory as the path
|
20
|
+
in question), git finds that the first line matches. merge attribute is
|
21
|
+
set. It also finds that the second line matches, and attributes foo and
|
22
|
+
bar are unset.
|
23
|
+
2. Then it examines .gitattributes (which is in the parent directory), and
|
24
|
+
finds that the first line matches, but t/.gitattributes file already
|
25
|
+
decided how merge, foo and bar attributes should be given to this path,
|
26
|
+
so it leaves foo and bar unset. Attribute baz is set.
|
27
|
+
3. Finally it examines $GIT_DIR/info/attributes. This file is used to
|
28
|
+
override the in-tree settings. The first line is a match, and foo is set,
|
29
|
+
bar is reverted to unspecified state, and baz is unset.
|
30
|
+
|
31
|
+
As the result, the attributes assignment to t/abc becomes:
|
32
|
+
|
33
|
+
foo set to true
|
34
|
+
bar unspecified
|
35
|
+
baz set to false
|
36
|
+
merge set to string value "filfre"
|
37
|
+
frotz unspecified
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
hi
|
@@ -0,0 +1 @@
|
|
1
|
+
in ignored dir
|
@@ -0,0 +1 @@
|
|
1
|
+
below ignored dir
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
hi
|
@@ -0,0 +1 @@
|
|
1
|
+
subsub
|
@@ -0,0 +1 @@
|
|
1
|
+
Hello again
|
@@ -0,0 +1,38 @@
|
|
1
|
+
Git is fast. With Git, nearly all operations are performed locally, giving
|
2
|
+
it an huge speed advantage on centralized systems that constantly have to
|
3
|
+
communicate with a server somewh3r3.
|
4
|
+
|
5
|
+
For testing, large AWS instances were set up in the same availability
|
6
|
+
zone. Git and SVN were installed on both machines, the Ruby repository was
|
7
|
+
copied to both Git and SVN servers, and common operations were performed on
|
8
|
+
both.
|
9
|
+
|
10
|
+
In some cases the commands don't match up exactly. Here, matching on the
|
11
|
+
lowest common denominator was attempted. For example, the 'commit' tests
|
12
|
+
also include the time to push for Git, though most of the time you would not
|
13
|
+
actually be pushing to the server immediately after a commit where the two
|
14
|
+
commands cannot be separated in SVN.
|
15
|
+
|
16
|
+
Note that this is the best case scenario for SVN - a server with no load
|
17
|
+
with an 80MB/s bandwidth connection to the client machine. Nearly all of
|
18
|
+
these times would be even worse for SVN if that connection was slower, while
|
19
|
+
many of the Git times would not be affected.
|
20
|
+
|
21
|
+
Clearly, in many of these common version control operations, Git is one or
|
22
|
+
two orders of magnitude faster than SVN, even under ideal conditions for
|
23
|
+
SVN.
|
24
|
+
|
25
|
+
Let's see how common operations stack up against Subversion, a common
|
26
|
+
centralized version control system that is similar to CVS or
|
27
|
+
Perforce. Smaller is faster.
|
28
|
+
|
29
|
+
One place where Git is slower is in the initial clone operation. Here, Git
|
30
|
+
One place where Git is slower is in the initial clone operation. Here, Git
|
31
|
+
One place where Git is slower is in the initial clone operation. Here, Git
|
32
|
+
seen in the above charts, it's not considerably slower for an operation that
|
33
|
+
is only performed once.
|
34
|
+
|
35
|
+
It's also interesting to note that the size of the data on the client side
|
36
|
+
is very similar even though Git also has every version of every file for the
|
37
|
+
entire history of the project. This illustrates how efficient it is at
|
38
|
+
compressing and storing data on the client side.
|
@@ -0,0 +1,36 @@
|
|
1
|
+
The Git feature that r3ally mak3s it stand apart from n3arly 3v3ry other SCM
|
2
|
+
out there is its branching model.
|
3
|
+
|
4
|
+
Git allows and encourages you to have multiple local branches that can be
|
5
|
+
entirely independent of each other. The creation, merging, and deletion of
|
6
|
+
those lines of development takes seconds.
|
7
|
+
|
8
|
+
Git allows and encourages you to have multiple local branches that can be
|
9
|
+
entirely independent of each other. The creation, merging, and deletion of
|
10
|
+
those lines of development takes seconds.
|
11
|
+
|
12
|
+
This means that you can do things like:
|
13
|
+
|
14
|
+
Role-Bas3d Codelin3s. Have a branch that always contains only what goes to
|
15
|
+
production, another that you merge work into for testing, and several
|
16
|
+
smaller ones for day to day work.
|
17
|
+
|
18
|
+
Feature Based Workflow. Create new branches for each new feature you're
|
19
|
+
working on so you can seamlessly switch back and forth between them, then
|
20
|
+
delete each branch when that feature gets merged into your main line.
|
21
|
+
|
22
|
+
Disposable Experimentation. Create a branch to experiment in, realize it's
|
23
|
+
not going to work, and just delete it - abandoning the work—with nobody else
|
24
|
+
ever seeing it (even if you've pushed other branches in the meantime).
|
25
|
+
|
26
|
+
Notably, when you push to a remote repository, you do not have to push all
|
27
|
+
share it with others.
|
28
|
+
|
29
|
+
Git allows and encourages you to have multiple local branches that can be
|
30
|
+
entirely independent of each other. The creation, merging, and deletion of
|
31
|
+
those lines of development takes seconds.
|
32
|
+
|
33
|
+
There are ways to accomplish some of this with other systems, but the work
|
34
|
+
involved is much more difficult and error-prone. Git makes this process
|
35
|
+
incredibly easy and it changes the way most developers work when they learn
|
36
|
+
it.!
|
@@ -0,0 +1 @@
|
|
1
|
+
current_file
|
@@ -0,0 +1 @@
|
|
1
|
+
ignored_file
|
@@ -0,0 +1 @@
|
|
1
|
+
new_file
|
@@ -0,0 +1 @@
|
|
1
|
+
staged_delete_modified_file
|
@@ -0,0 +1 @@
|
|
1
|
+
staged_new_file
|
@@ -0,0 +1 @@
|
|
1
|
+
subdir/current_file
|
@@ -0,0 +1 @@
|
|
1
|
+
subdir/new_file
|
@@ -0,0 +1 @@
|
|
1
|
+
This
|
@@ -6,3 +6,8 @@
|
|
6
6
|
ignorecase = true
|
7
7
|
[remote "libgit2"]
|
8
8
|
url = git://github.com/libgit2/libgit2.git
|
9
|
+
[remote "test_remote"]
|
10
|
+
url = git://github.com/libgit2/rugged.git
|
11
|
+
pushurl = git://github.com/libgit2/TestEmptyRepository.git
|
12
|
+
fetch = +refs/heads/*:refs/remotes/test_remote/*
|
13
|
+
push = refs/heads/*:refs/heads/testing/*
|
@@ -0,0 +1,464 @@
|
|
1
|
+
# Rugged
|
2
|
+
**libgit2 bindings in Ruby**
|
3
|
+
|
4
|
+
Rugged is a library for accessing [libgit2](https://github.com/libgit2/libgit2) in Ruby. It gives you the speed and
|
5
|
+
portability of libgit2 with the beauty of the Ruby language.
|
6
|
+
|
7
|
+
### libgit2
|
8
|
+
|
9
|
+
libgit2 is a pure C implementation of the Git core methods. It's designed to be
|
10
|
+
fast and portable. For more information about libgit2,
|
11
|
+
[check out libgit2's website](http://libgit2.github.com) or browse the
|
12
|
+
[libgit2 organization](https://github.com/libgit2) on GitHub.
|
13
|
+
|
14
|
+
## Install
|
15
|
+
|
16
|
+
Rugged is a self-contained gem. You can install it by running:
|
17
|
+
|
18
|
+
$ gem install rugged
|
19
|
+
|
20
|
+
To load Rugged, you'll usually want to add something like this:
|
21
|
+
|
22
|
+
```ruby
|
23
|
+
require 'rugged'
|
24
|
+
```
|
25
|
+
|
26
|
+
## Usage
|
27
|
+
|
28
|
+
Rugged gives you access to the many parts of a Git repository. You can read and
|
29
|
+
write objects, walk a tree, access the staging area, and lots more. Let's look
|
30
|
+
at each area individually.
|
31
|
+
|
32
|
+
### Repositories
|
33
|
+
|
34
|
+
#### Instantiation
|
35
|
+
|
36
|
+
The repository is naturally central to Git. Rugged has a `Repository` class that
|
37
|
+
you can instantiate with a path to open an existing repository :
|
38
|
+
|
39
|
+
```ruby
|
40
|
+
repo = Rugged::Repository.new('path/to/my/repository')
|
41
|
+
# => #<Rugged::Repository:2228536260 {path: "path/to/my/repository/.git/"}>
|
42
|
+
```
|
43
|
+
|
44
|
+
You can create a new repository with `init_at`. Add a second parameter `:bare` to make a bare repository:
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
Rugged::Repository.init_at('.', :bare)
|
48
|
+
```
|
49
|
+
|
50
|
+
You can also let Rugged discover the path to the .git directory if you give it a
|
51
|
+
subdirectory.
|
52
|
+
|
53
|
+
```ruby
|
54
|
+
Rugged::Repository.discover("/Users/me/projects/repo/lib/subdir/")
|
55
|
+
# => "/Users/me/projects/repo/.git/"
|
56
|
+
```
|
57
|
+
|
58
|
+
Once your Repository instantiated (in the following examples, as `repo`), you
|
59
|
+
can access or modify it.
|
60
|
+
|
61
|
+
#### Accessing a Repository
|
62
|
+
|
63
|
+
```ruby
|
64
|
+
# Does the given SHA1 exist in this repository?
|
65
|
+
repo.exists?('07b44cbda23b726e5d54e2ef383495922c024202')
|
66
|
+
# => true
|
67
|
+
|
68
|
+
# Boolean repository state values:
|
69
|
+
repo.bare?
|
70
|
+
# => false
|
71
|
+
repo.empty?
|
72
|
+
# => true
|
73
|
+
repo.head_orphan?
|
74
|
+
# => false
|
75
|
+
repo.head_detached?
|
76
|
+
# => false
|
77
|
+
|
78
|
+
# Path accessors
|
79
|
+
repo.path
|
80
|
+
# => "path/to/my/repository/.git/"
|
81
|
+
repo.workdir
|
82
|
+
# => "path/to/my/repository/"
|
83
|
+
|
84
|
+
# The HEAD of the repository.
|
85
|
+
ref = repo.head
|
86
|
+
# => #<Rugged::Reference:2228467240 {name: "refs/heads/master", target: "07b44cbda23b726e5d54e2ef383495922c024202"}>
|
87
|
+
|
88
|
+
# From the returned ref, you can also access the `name` and `target`:
|
89
|
+
ref.name
|
90
|
+
# => "refs/heads/master"
|
91
|
+
ref.target
|
92
|
+
# => "07b44cbda23b726e5d54e2ef383495922c024202"
|
93
|
+
|
94
|
+
# Reading an object
|
95
|
+
object = repo.read('a0ae5566e3c8a3bddffab21022056f0b5e03ef07')
|
96
|
+
# => #<Rugged::OdbObject:0x109a64780>
|
97
|
+
object.len
|
98
|
+
# => 237
|
99
|
+
object.data
|
100
|
+
# => "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"
|
101
|
+
object.type
|
102
|
+
# => :commit
|
103
|
+
```
|
104
|
+
|
105
|
+
#### Writing to a Repository
|
106
|
+
|
107
|
+
There's a few ways to write to a repository. To write directly from your
|
108
|
+
instantiated repository object:
|
109
|
+
|
110
|
+
```ruby
|
111
|
+
sha = repo.write(content, type)
|
112
|
+
```
|
113
|
+
|
114
|
+
You can also use the `Commit` object directly to craft a commit; this is a bit
|
115
|
+
more high-level, so it may be preferable:
|
116
|
+
|
117
|
+
```ruby
|
118
|
+
oid = repo.write("This is a blob.", :blob)
|
119
|
+
index = Rugged::Index.new
|
120
|
+
index.add(:path => "README.md", :oid => oid, :mode => 0100644)
|
121
|
+
|
122
|
+
options = {}
|
123
|
+
options[:tree] = index.write_tree(repo)
|
124
|
+
|
125
|
+
options[:author] = { :email => "testuser@github.com", :name => 'Test Author', :time => Time.now }
|
126
|
+
options[:committer] = { :email => "testuser@github.com", :name => 'Test Author', :time => Time.now }
|
127
|
+
options[:message] ||= "Making a commit via Rugged!"
|
128
|
+
options[:parents] = repo.empty? ? [] : [ repo.head.target ].compact
|
129
|
+
options[:update_ref] = 'HEAD'
|
130
|
+
|
131
|
+
Rugged::Commit.create(repo, options)
|
132
|
+
```
|
133
|
+
|
134
|
+
---
|
135
|
+
|
136
|
+
### Objects
|
137
|
+
|
138
|
+
`Object` is the main object class - it shouldn't be created directly, but all of
|
139
|
+
these methods should be useful in their derived classes.
|
140
|
+
|
141
|
+
```ruby
|
142
|
+
obj = repo.lookup(sha)
|
143
|
+
obj.oid # object sha
|
144
|
+
obj.type # One of :commit, :tree, :blob or :tag
|
145
|
+
|
146
|
+
robj = obj.read_raw
|
147
|
+
str = robj.data
|
148
|
+
int = robj.len
|
149
|
+
```
|
150
|
+
|
151
|
+
There are four base object types in Git: **blobs**, **commits**, **tags**, and
|
152
|
+
**trees**. Each of these object types have a corresponding class within Rugged.
|
153
|
+
|
154
|
+
### Commit Objects
|
155
|
+
|
156
|
+
```ruby
|
157
|
+
commit = repo.lookup('a0ae5566e3c8a3bddffab21022056f0b5e03ef07')
|
158
|
+
# => #<Rugged::Commit:2245304380>
|
159
|
+
|
160
|
+
commit.message
|
161
|
+
# => "Add `Repository#blob_at`\n"
|
162
|
+
|
163
|
+
commit.time
|
164
|
+
# => Sat Apr 07 21:23:25 -0700 2012
|
165
|
+
|
166
|
+
commit.author
|
167
|
+
# => {:email=>"tanoku@gmail.com", :name=>"Vicent Mart\303\255", :time=>Sun Apr 08 04:23:25 UTC 2012}
|
168
|
+
|
169
|
+
commit.tree
|
170
|
+
# => #<Rugged::Tree:2245269740>
|
171
|
+
|
172
|
+
commit.parents
|
173
|
+
=> [#<Rugged::Commit:2245264600 {message: "Merge pull request #47 from isaac/remotes\n\nAdd Rugged::Repository#remotes", tree: #<Rugged::Tree:2245264240 {oid: 6a2aee58a41fa007d07aa55565e2231f9b39b4a9}>
|
174
|
+
```
|
175
|
+
|
176
|
+
You can also write new objects to the database this way:
|
177
|
+
|
178
|
+
```ruby
|
179
|
+
author = {:email=>"tanoku@gmail.com", :time=>Time.now, :name=>"Vicent Mart\303\255"}
|
180
|
+
|
181
|
+
Rugged::Commit.create(r,
|
182
|
+
:author => author,
|
183
|
+
:message => "Hello world\n\n",
|
184
|
+
:committer => author,
|
185
|
+
:parents => ["2cb831a8aea28b2c1b9c63385585b864e4d3bad1"],
|
186
|
+
:tree => some_tree,
|
187
|
+
:update_ref => "HEAD") #=> "f148106ca58764adc93ad4e2d6b1d168422b9796"
|
188
|
+
```
|
189
|
+
|
190
|
+
### Tag Objects
|
191
|
+
|
192
|
+
```ruby
|
193
|
+
tag = repo.lookup(tag_sha)
|
194
|
+
|
195
|
+
object = tag.target
|
196
|
+
sha = tag.target.oid
|
197
|
+
str = tag.target_type # :commit, :tag, :blob
|
198
|
+
str = tag.name # "v1.0"
|
199
|
+
str = tag.message
|
200
|
+
person = tag.tagger
|
201
|
+
```
|
202
|
+
|
203
|
+
### Tree Objects
|
204
|
+
|
205
|
+
```ruby
|
206
|
+
tree = repo.lookup('779fbb1e17e666832773a9825875300ea736c2da')
|
207
|
+
# => #<Rugged::Tree:2245194360>
|
208
|
+
|
209
|
+
# number of tree entries
|
210
|
+
tree.count
|
211
|
+
|
212
|
+
tree[0] # or...
|
213
|
+
tree.first # or...
|
214
|
+
tree.get_entry(0)
|
215
|
+
# => {:type=>:blob, :oid=>"99e7edb53db9355f10c6f2dfaa5a183f205d93bf", :filemode=>33188, :name=>".gitignore"}
|
216
|
+
```
|
217
|
+
|
218
|
+
The tree object is an Enumerable, so you can also do stuff like this:
|
219
|
+
|
220
|
+
```ruby
|
221
|
+
tree.each { |e| puts e[:oid] }
|
222
|
+
tree.sort { |a, b| a[:oid] <=> b[:oid] }.map { |e| e[:name] }.join(':')
|
223
|
+
```
|
224
|
+
|
225
|
+
And there are some Rugged-specific methods, too:
|
226
|
+
|
227
|
+
```ruby
|
228
|
+
tree.each_tree { |entry| puts entry[:name] } # list subdirs
|
229
|
+
tree.each_blob { |entry| puts entry[:name] } # list only files
|
230
|
+
```
|
231
|
+
|
232
|
+
You can also write trees with the `TreeBuilder`:
|
233
|
+
|
234
|
+
```ruby
|
235
|
+
oid = repo.write("This is a blob.", :blob)
|
236
|
+
builder = Rugged::Tree::Builder.new
|
237
|
+
builder << { :type => :blob, :name => "README.md", :oid => oid, :filemode => 0100644 }
|
238
|
+
|
239
|
+
options = {}
|
240
|
+
options[:tree] = builder.write(repo)
|
241
|
+
|
242
|
+
options[:author] = { :email => "testuser@github.com", :name => 'Test Author', :time => Time.now }
|
243
|
+
options[:committer] = { :email => "testuser@github.com", :name => 'Test Author', :time => Time.now }
|
244
|
+
options[:message] ||= "Making a commit via Rugged!"
|
245
|
+
options[:parents] = repo.empty? ? [] : [ repo.head.target ].compact
|
246
|
+
options[:update_ref] = 'HEAD'
|
247
|
+
|
248
|
+
Rugged::Commit.create(repo, options)
|
249
|
+
```
|
250
|
+
|
251
|
+
---
|
252
|
+
|
253
|
+
### Commit Walker
|
254
|
+
|
255
|
+
`Rugged::Walker` is a class designed to help you traverse a set of commits over
|
256
|
+
a repository.
|
257
|
+
|
258
|
+
You first push head SHAs onto the walker, and then call next to get a list of
|
259
|
+
the reachable commit objects one at a time. You can also `hide()` commits if you
|
260
|
+
are not interested in anything beneath them (useful in situations like when
|
261
|
+
you're running something like `git log master ^origin/master`).
|
262
|
+
|
263
|
+
```ruby
|
264
|
+
walker = Rugged::Walker.new(repo)
|
265
|
+
walker.sorting(Rugged::SORT_TOPO | Rugged::SORT_REVERSE) # optional
|
266
|
+
walker.push(hex_sha_interesting)
|
267
|
+
walker.hide(hex_sha_uninteresting)
|
268
|
+
walker.each { |c| puts c.inspect }
|
269
|
+
walker.reset
|
270
|
+
```
|
271
|
+
|
272
|
+
---
|
273
|
+
|
274
|
+
### Index ("staging") area
|
275
|
+
|
276
|
+
We can inspect and manipulate the Git Index as well. To work with the index
|
277
|
+
inside an existing repository, instantiate it by using the `Repository.index`
|
278
|
+
method instead of manually opening the Index by its path.
|
279
|
+
|
280
|
+
```ruby
|
281
|
+
index = Rugged::Index.new(path)
|
282
|
+
|
283
|
+
# Re-read the index file from disk.
|
284
|
+
index.reload
|
285
|
+
|
286
|
+
# Count up index entries.
|
287
|
+
count = index.count
|
288
|
+
|
289
|
+
# The collection of index entries.
|
290
|
+
index.entries
|
291
|
+
|
292
|
+
# Iterating over index entries.
|
293
|
+
index.each { |i| puts i.inspect }
|
294
|
+
|
295
|
+
# Get a particular entry in the index.
|
296
|
+
index[path]
|
297
|
+
|
298
|
+
# Unstage.
|
299
|
+
index.remove(path)
|
300
|
+
|
301
|
+
# Stage. Also updates existing entry if there is one.
|
302
|
+
index.add(ientry)
|
303
|
+
|
304
|
+
# Stage. Create ientry from file in path, updates the index.
|
305
|
+
index.add(path)
|
306
|
+
```
|
307
|
+
|
308
|
+
---
|
309
|
+
|
310
|
+
### Refs
|
311
|
+
|
312
|
+
The `Rugged::Reference` class allows you to list, create and delete packed and loose refs.
|
313
|
+
|
314
|
+
```ruby
|
315
|
+
ref = repo.head # or...
|
316
|
+
ref = Rugged::Reference.lookup(repo, "refs/heads/master")
|
317
|
+
|
318
|
+
sha = ref.target
|
319
|
+
str = ref.type # :direct
|
320
|
+
str = ref.name # "refs/heads/master"
|
321
|
+
```
|
322
|
+
|
323
|
+
You can also easily get an array of references:
|
324
|
+
|
325
|
+
```ruby
|
326
|
+
repo.refs.each do |ref|
|
327
|
+
puts ref.name
|
328
|
+
end
|
329
|
+
```
|
330
|
+
|
331
|
+
Or use a pattern (regex):
|
332
|
+
|
333
|
+
```ruby
|
334
|
+
repo.refs(/tags/).each do |ref|
|
335
|
+
puts ref.name
|
336
|
+
end
|
337
|
+
```
|
338
|
+
|
339
|
+
It is also easy to create, update, rename or delete a reference:
|
340
|
+
|
341
|
+
```ruby
|
342
|
+
ref = Rugged::Reference.create(repo, "refs/heads/unit_test", some_commit_sha)
|
343
|
+
|
344
|
+
ref.set_target(new_sha)
|
345
|
+
|
346
|
+
ref.rename("refs/heads/blead")
|
347
|
+
|
348
|
+
ref.delete!
|
349
|
+
```
|
350
|
+
|
351
|
+
Finally, you can access the reflog for any branch:
|
352
|
+
|
353
|
+
```ruby
|
354
|
+
ref = Rugged::Reference.lookup(repo, "refs/heads/master")
|
355
|
+
entry = ref.log.first
|
356
|
+
sha = entry[:id_old]
|
357
|
+
sha = entry[:id_new]
|
358
|
+
str = entry[:message]
|
359
|
+
prsn = entry[:committer]
|
360
|
+
```
|
361
|
+
|
362
|
+
---
|
363
|
+
|
364
|
+
### Branches
|
365
|
+
|
366
|
+
`Rugged::Branch` will help you with all of your branch-related needs.
|
367
|
+
|
368
|
+
Iterate over all branches:
|
369
|
+
|
370
|
+
```ruby
|
371
|
+
Rugged::Branch.each_name(repo).sort
|
372
|
+
# => ["master", "origin/HEAD", "origin/master", "origin/packed"]
|
373
|
+
|
374
|
+
Rugged::Branch.each_name(repo, :local).sort
|
375
|
+
# => ["master"]
|
376
|
+
|
377
|
+
Rugged::Branch.each_name(repo, :remote).sort
|
378
|
+
# => ["origin/HEAD", "origin/master", "origin/packed"]
|
379
|
+
```
|
380
|
+
|
381
|
+
Look up branches and get attributes:
|
382
|
+
|
383
|
+
```ruby
|
384
|
+
branch = Rugged::Branch.lookup(repo, "master")
|
385
|
+
branch.name # => 'master'
|
386
|
+
branch.canonical_name # => 'refs/heads/master'
|
387
|
+
```
|
388
|
+
|
389
|
+
Look up the oid for the tip of a branch:
|
390
|
+
|
391
|
+
```ruby
|
392
|
+
Rugged::Branch.lookup(repo, "master").tip.oid
|
393
|
+
# => "36060c58702ed4c2a40832c51758d5344201d89a"
|
394
|
+
```
|
395
|
+
|
396
|
+
Creation and deletion:
|
397
|
+
|
398
|
+
```ruby
|
399
|
+
branch = repo.create_branch("test_branch")
|
400
|
+
branch.move("new_branch")
|
401
|
+
branch.delete!
|
402
|
+
```
|
403
|
+
|
404
|
+
---
|
405
|
+
|
406
|
+
### Config files
|
407
|
+
|
408
|
+
It's also easy to read and manipulate the Git config file data with Rugged.
|
409
|
+
|
410
|
+
```ruby
|
411
|
+
# Read values
|
412
|
+
repo.config['core.bare']
|
413
|
+
|
414
|
+
# Set values
|
415
|
+
repo.config['user.name'] = true
|
416
|
+
|
417
|
+
# Delete values
|
418
|
+
repo.config.delete('user.name')
|
419
|
+
```
|
420
|
+
|
421
|
+
---
|
422
|
+
|
423
|
+
### General methods
|
424
|
+
|
425
|
+
Rugged also includes a general library for handling basic Git operations. One of
|
426
|
+
these is converting a raw sha (20 bytes) into a readable hex sha (40
|
427
|
+
characters).
|
428
|
+
|
429
|
+
```ruby
|
430
|
+
Rugged.hex_to_raw('bfde59cdd0dfac1d892814f66a95641abd8a1faf')
|
431
|
+
# => "\277\336Y\315\320\337\254\035\211(\024\366j\225d\032\275\212\037\257"
|
432
|
+
|
433
|
+
Rugged.raw_to_hex("\277\336Y\315\320\337\254\035\211(\024\366j\225d\032\275\212\037\257")
|
434
|
+
=> "bfde59cdd0dfac1d892814f66a95641abd8a1faf"
|
435
|
+
```
|
436
|
+
|
437
|
+
---
|
438
|
+
|
439
|
+
## Contributing
|
440
|
+
|
441
|
+
Fork libgit2/rugged on GitHub, make it awesomer (preferably in a branch named
|
442
|
+
for the topic), send a pull request.
|
443
|
+
|
444
|
+
|
445
|
+
## Development
|
446
|
+
|
447
|
+
Simply clone and install:
|
448
|
+
|
449
|
+
$ git clone https://github.com/libgit2/rugged.git
|
450
|
+
$ cd rugged
|
451
|
+
$ bundle install
|
452
|
+
$ rake compile
|
453
|
+
$ rake test
|
454
|
+
|
455
|
+
|
456
|
+
## Authors
|
457
|
+
|
458
|
+
* Vicent Marti <tanoku@gmail.com>
|
459
|
+
* Scott Chacon <schacon@gmail.com>
|
460
|
+
|
461
|
+
|
462
|
+
## License
|
463
|
+
|
464
|
+
MIT. See LICENSE file.
|