rugged 0.17.0.b7 → 0.18.0.b1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +1 -1
- data/README.md +88 -32
- data/ext/rugged/extconf.rb +4 -2
- data/ext/rugged/rugged.c +72 -10
- data/ext/rugged/rugged.h +14 -10
- data/ext/rugged/rugged_blob.c +8 -10
- data/ext/rugged/rugged_branch.c +11 -14
- data/ext/rugged/rugged_commit.c +31 -24
- data/ext/rugged/rugged_config.c +2 -2
- data/ext/rugged/rugged_index.c +133 -198
- data/ext/rugged/rugged_note.c +372 -0
- data/ext/rugged/rugged_object.c +50 -22
- data/ext/rugged/rugged_reference.c +122 -130
- data/ext/rugged/rugged_remote.c +72 -29
- data/ext/rugged/rugged_repo.c +402 -20
- data/ext/rugged/rugged_revwalk.c +7 -3
- data/ext/rugged/rugged_settings.c +110 -0
- data/ext/rugged/rugged_signature.c +23 -7
- data/ext/rugged/rugged_tag.c +32 -16
- data/ext/rugged/rugged_tree.c +44 -15
- data/lib/rugged.rb +1 -0
- data/lib/rugged/index.rb +8 -0
- data/lib/rugged/remote.rb +13 -0
- data/lib/rugged/repository.rb +3 -3
- data/lib/rugged/version.rb +1 -1
- data/test/blob_test.rb +13 -15
- data/test/branch_test.rb +32 -67
- data/test/commit_test.rb +50 -12
- data/test/config_test.rb +12 -11
- data/test/coverage/HEAD.json +1 -1
- data/test/coverage/cover.rb +40 -21
- data/test/errors_test.rb +34 -0
- data/test/fixtures/alternate/objects/14/6ae76773c91e3b1d00cf7a338ec55ae58297e2 +0 -0
- data/test/fixtures/alternate/objects/14/9c32d47e99d0a3572ff1e70a2e0051bbf347a9 +0 -0
- data/test/fixtures/alternate/objects/14/fb3108588f9421bf764041e5e3ac305eb6277f +0 -0
- data/test/fixtures/testrepo.git/logs/refs/notes/commits +1 -0
- data/test/fixtures/testrepo.git/objects/44/1034f860c1d5d90e4188d11ae0d325176869a8 +1 -0
- data/test/fixtures/testrepo.git/objects/60/d415052a33de2150bf68757f6461df4f563ae4 +0 -0
- data/test/fixtures/testrepo.git/objects/68/8a8f4ef7496901d15322972f96e212a9e466cc +1 -0
- data/test/fixtures/testrepo.git/objects/94/eca2de348d5f672faf56b0decafa5937e3235e +0 -0
- data/test/fixtures/testrepo.git/objects/9b/7384fe1676186192842f5d3e129457b62db9e3 +0 -0
- data/test/fixtures/testrepo.git/objects/b7/4713326bc972cc15751ed504dca6f6f3b91f7a +3 -0
- data/test/fixtures/testrepo.git/refs/notes/commits +1 -0
- data/test/index_test.rb +65 -69
- data/test/lib_test.rb +76 -11
- data/test/note_test.rb +158 -0
- data/test/object_test.rb +8 -11
- data/test/reference_test.rb +77 -85
- data/test/remote_test.rb +86 -8
- data/test/repo_pack_test.rb +9 -7
- data/test/repo_reset_test.rb +80 -0
- data/test/repo_test.rb +176 -53
- data/test/tag_test.rb +44 -7
- data/test/test_helper.rb +63 -35
- data/test/tree_test.rb +34 -13
- data/test/walker_test.rb +14 -14
- data/vendor/libgit2/Makefile.embed +1 -1
- data/vendor/libgit2/deps/http-parser/http_parser.c +974 -578
- data/vendor/libgit2/deps/http-parser/http_parser.h +106 -70
- data/vendor/libgit2/deps/regex/regcomp.c +7 -6
- data/vendor/libgit2/deps/regex/regex_internal.c +1 -1
- data/vendor/libgit2/deps/regex/regex_internal.h +12 -3
- data/vendor/libgit2/deps/regex/regexec.c +5 -5
- data/vendor/libgit2/include/git2.h +5 -1
- data/vendor/libgit2/include/git2/attr.h +4 -2
- data/vendor/libgit2/include/git2/blob.h +39 -12
- data/vendor/libgit2/include/git2/branch.h +123 -35
- data/vendor/libgit2/include/git2/checkout.h +206 -48
- data/vendor/libgit2/include/git2/clone.h +72 -27
- data/vendor/libgit2/include/git2/commit.h +20 -17
- data/vendor/libgit2/include/git2/common.h +67 -1
- data/vendor/libgit2/include/git2/config.h +81 -60
- data/vendor/libgit2/include/git2/cred_helpers.h +53 -0
- data/vendor/libgit2/include/git2/diff.h +459 -150
- data/vendor/libgit2/include/git2/errors.h +9 -1
- data/vendor/libgit2/include/git2/graph.h +41 -0
- data/vendor/libgit2/include/git2/ignore.h +7 -6
- data/vendor/libgit2/include/git2/index.h +323 -97
- data/vendor/libgit2/include/git2/indexer.h +27 -59
- data/vendor/libgit2/include/git2/inttypes.h +4 -0
- data/vendor/libgit2/include/git2/merge.h +13 -3
- data/vendor/libgit2/include/git2/message.h +14 -8
- data/vendor/libgit2/include/git2/net.h +9 -7
- data/vendor/libgit2/include/git2/notes.h +88 -29
- data/vendor/libgit2/include/git2/object.h +16 -6
- data/vendor/libgit2/include/git2/odb.h +80 -17
- data/vendor/libgit2/include/git2/odb_backend.h +47 -11
- data/vendor/libgit2/include/git2/oid.h +26 -17
- data/vendor/libgit2/include/git2/pack.h +62 -8
- data/vendor/libgit2/include/git2/push.h +131 -0
- data/vendor/libgit2/include/git2/refdb.h +103 -0
- data/vendor/libgit2/include/git2/refdb_backend.h +109 -0
- data/vendor/libgit2/include/git2/reflog.h +30 -21
- data/vendor/libgit2/include/git2/refs.h +215 -193
- data/vendor/libgit2/include/git2/refspec.h +22 -2
- data/vendor/libgit2/include/git2/remote.h +158 -37
- data/vendor/libgit2/include/git2/repository.h +150 -31
- data/vendor/libgit2/include/git2/reset.h +43 -9
- data/vendor/libgit2/include/git2/revparse.h +48 -4
- data/vendor/libgit2/include/git2/revwalk.h +25 -10
- data/vendor/libgit2/include/git2/signature.h +20 -12
- data/vendor/libgit2/include/git2/stash.h +121 -0
- data/vendor/libgit2/include/git2/status.h +122 -53
- data/vendor/libgit2/include/git2/strarray.h +17 -11
- data/vendor/libgit2/include/git2/submodule.h +42 -7
- data/vendor/libgit2/include/git2/tag.h +72 -59
- data/vendor/libgit2/include/git2/threads.h +4 -2
- data/vendor/libgit2/include/git2/trace.h +68 -0
- data/vendor/libgit2/include/git2/transport.h +328 -0
- data/vendor/libgit2/include/git2/tree.h +149 -120
- data/vendor/libgit2/include/git2/types.h +13 -12
- data/vendor/libgit2/include/git2/version.h +3 -3
- data/vendor/libgit2/src/amiga/map.c +2 -2
- data/vendor/libgit2/src/attr.c +58 -48
- data/vendor/libgit2/src/attr.h +4 -18
- data/vendor/libgit2/src/attr_file.c +30 -6
- data/vendor/libgit2/src/attr_file.h +6 -8
- data/vendor/libgit2/src/attrcache.h +24 -0
- data/vendor/libgit2/src/blob.c +30 -7
- data/vendor/libgit2/src/blob.h +1 -1
- data/vendor/libgit2/src/branch.c +361 -68
- data/vendor/libgit2/src/branch.h +17 -0
- data/vendor/libgit2/src/bswap.h +1 -1
- data/vendor/libgit2/src/buf_text.c +291 -0
- data/vendor/libgit2/src/buf_text.h +122 -0
- data/vendor/libgit2/src/buffer.c +27 -101
- data/vendor/libgit2/src/buffer.h +54 -39
- data/vendor/libgit2/src/cache.c +15 -6
- data/vendor/libgit2/src/cache.h +1 -1
- data/vendor/libgit2/src/cc-compat.h +3 -1
- data/vendor/libgit2/src/checkout.c +1165 -222
- data/vendor/libgit2/src/checkout.h +24 -0
- data/vendor/libgit2/src/clone.c +171 -86
- data/vendor/libgit2/src/commit.c +44 -45
- data/vendor/libgit2/src/commit.h +3 -3
- data/vendor/libgit2/src/commit_list.c +194 -0
- data/vendor/libgit2/src/commit_list.h +49 -0
- data/vendor/libgit2/src/common.h +44 -10
- data/vendor/libgit2/src/compress.c +1 -1
- data/vendor/libgit2/src/compress.h +1 -1
- data/vendor/libgit2/src/config.c +211 -124
- data/vendor/libgit2/src/config.h +23 -4
- data/vendor/libgit2/src/config_cache.c +2 -2
- data/vendor/libgit2/src/config_file.c +129 -53
- data/vendor/libgit2/src/config_file.h +10 -8
- data/vendor/libgit2/src/crlf.c +66 -67
- data/vendor/libgit2/src/date.c +12 -12
- data/vendor/libgit2/src/delta-apply.c +14 -1
- data/vendor/libgit2/src/delta-apply.h +18 -1
- data/vendor/libgit2/src/delta.c +40 -107
- data/vendor/libgit2/src/delta.h +19 -17
- data/vendor/libgit2/src/diff.c +347 -496
- data/vendor/libgit2/src/diff.h +27 -1
- data/vendor/libgit2/src/diff_output.c +564 -249
- data/vendor/libgit2/src/diff_output.h +15 -8
- data/vendor/libgit2/src/diff_tform.c +687 -0
- data/vendor/libgit2/src/errors.c +27 -36
- data/vendor/libgit2/src/fetch.c +13 -351
- data/vendor/libgit2/src/fetch.h +13 -3
- data/vendor/libgit2/src/fetchhead.c +295 -0
- data/vendor/libgit2/src/fetchhead.h +34 -0
- data/vendor/libgit2/src/filebuf.c +42 -15
- data/vendor/libgit2/src/filebuf.h +4 -2
- data/vendor/libgit2/src/fileops.c +466 -113
- data/vendor/libgit2/src/fileops.h +154 -28
- data/vendor/libgit2/src/filter.c +3 -75
- data/vendor/libgit2/src/filter.h +1 -29
- data/vendor/libgit2/src/fnmatch.c +1 -1
- data/vendor/libgit2/src/fnmatch.h +1 -1
- data/vendor/libgit2/src/global.c +54 -10
- data/vendor/libgit2/src/global.h +10 -1
- data/vendor/libgit2/src/graph.c +178 -0
- data/vendor/libgit2/src/hash.c +25 -52
- data/vendor/libgit2/src/hash.h +21 -9
- data/vendor/libgit2/src/{sha1/sha1.c → hash/hash_generic.c} +20 -12
- data/vendor/libgit2/src/hash/hash_generic.h +24 -0
- data/vendor/libgit2/src/hash/hash_openssl.h +45 -0
- data/vendor/libgit2/src/hash/hash_win32.c +291 -0
- data/vendor/libgit2/src/hash/hash_win32.h +140 -0
- data/vendor/libgit2/src/hashsig.c +368 -0
- data/vendor/libgit2/src/hashsig.h +72 -0
- data/vendor/libgit2/src/ignore.c +22 -15
- data/vendor/libgit2/src/ignore.h +6 -1
- data/vendor/libgit2/src/index.c +770 -171
- data/vendor/libgit2/src/index.h +13 -5
- data/vendor/libgit2/src/indexer.c +286 -431
- data/vendor/libgit2/src/iterator.c +854 -466
- data/vendor/libgit2/src/iterator.h +134 -109
- data/vendor/libgit2/src/map.h +1 -1
- data/vendor/libgit2/src/merge.c +296 -0
- data/vendor/libgit2/src/merge.h +22 -0
- data/vendor/libgit2/src/message.c +1 -1
- data/vendor/libgit2/src/message.h +1 -1
- data/vendor/libgit2/src/mwindow.c +35 -30
- data/vendor/libgit2/src/mwindow.h +2 -2
- data/vendor/libgit2/src/netops.c +162 -98
- data/vendor/libgit2/src/netops.h +50 -15
- data/vendor/libgit2/src/notes.c +109 -58
- data/vendor/libgit2/src/notes.h +2 -1
- data/vendor/libgit2/src/object.c +46 -57
- data/vendor/libgit2/src/object.h +1 -8
- data/vendor/libgit2/src/odb.c +151 -40
- data/vendor/libgit2/src/odb.h +5 -1
- data/vendor/libgit2/src/odb_loose.c +4 -5
- data/vendor/libgit2/src/odb_pack.c +122 -80
- data/vendor/libgit2/src/offmap.h +65 -0
- data/vendor/libgit2/src/oid.c +12 -4
- data/vendor/libgit2/src/oidmap.h +1 -1
- data/vendor/libgit2/src/pack-objects.c +88 -61
- data/vendor/libgit2/src/pack-objects.h +8 -8
- data/vendor/libgit2/src/pack.c +293 -28
- data/vendor/libgit2/src/pack.h +49 -4
- data/vendor/libgit2/src/path.c +103 -14
- data/vendor/libgit2/src/path.h +23 -7
- data/vendor/libgit2/src/pathspec.c +168 -0
- data/vendor/libgit2/src/pathspec.h +40 -0
- data/vendor/libgit2/src/pool.c +29 -4
- data/vendor/libgit2/src/pool.h +8 -1
- data/vendor/libgit2/src/posix.c +26 -27
- data/vendor/libgit2/src/posix.h +2 -3
- data/vendor/libgit2/src/pqueue.c +23 -1
- data/vendor/libgit2/src/pqueue.h +23 -1
- data/vendor/libgit2/src/push.c +653 -0
- data/vendor/libgit2/src/push.h +51 -0
- data/vendor/libgit2/src/refdb.c +185 -0
- data/vendor/libgit2/src/refdb.h +46 -0
- data/vendor/libgit2/src/refdb_fs.c +1024 -0
- data/vendor/libgit2/src/refdb_fs.h +15 -0
- data/vendor/libgit2/src/reflog.c +77 -45
- data/vendor/libgit2/src/reflog.h +1 -3
- data/vendor/libgit2/src/refs.c +366 -1326
- data/vendor/libgit2/src/refs.h +22 -13
- data/vendor/libgit2/src/refspec.c +46 -7
- data/vendor/libgit2/src/refspec.h +11 -1
- data/vendor/libgit2/src/remote.c +758 -120
- data/vendor/libgit2/src/remote.h +10 -5
- data/vendor/libgit2/src/repo_template.h +6 -6
- data/vendor/libgit2/src/repository.c +315 -96
- data/vendor/libgit2/src/repository.h +5 -3
- data/vendor/libgit2/src/reset.c +99 -81
- data/vendor/libgit2/src/revparse.c +157 -84
- data/vendor/libgit2/src/revwalk.c +68 -470
- data/vendor/libgit2/src/revwalk.h +44 -0
- data/vendor/libgit2/src/sha1_lookup.c +1 -1
- data/vendor/libgit2/src/sha1_lookup.h +1 -1
- data/vendor/libgit2/src/signature.c +68 -200
- data/vendor/libgit2/src/signature.h +1 -1
- data/vendor/libgit2/src/stash.c +663 -0
- data/vendor/libgit2/src/status.c +101 -79
- data/vendor/libgit2/src/strmap.h +1 -1
- data/vendor/libgit2/src/submodule.c +67 -51
- data/vendor/libgit2/src/submodule.h +1 -1
- data/vendor/libgit2/src/tag.c +35 -29
- data/vendor/libgit2/src/tag.h +1 -1
- data/vendor/libgit2/src/thread-utils.c +1 -1
- data/vendor/libgit2/src/thread-utils.h +2 -2
- data/vendor/libgit2/src/trace.c +39 -0
- data/vendor/libgit2/src/trace.h +56 -0
- data/vendor/libgit2/src/transport.c +81 -34
- data/vendor/libgit2/src/transports/cred.c +60 -0
- data/vendor/libgit2/src/transports/cred_helpers.c +49 -0
- data/vendor/libgit2/src/transports/git.c +234 -127
- data/vendor/libgit2/src/transports/http.c +761 -433
- data/vendor/libgit2/src/transports/local.c +460 -64
- data/vendor/libgit2/src/transports/smart.c +345 -0
- data/vendor/libgit2/src/transports/smart.h +179 -0
- data/vendor/libgit2/src/{pkt.c → transports/smart_pkt.c} +131 -12
- data/vendor/libgit2/src/transports/smart_protocol.c +856 -0
- data/vendor/libgit2/src/transports/winhttp.c +1136 -0
- data/vendor/libgit2/src/tree-cache.c +2 -2
- data/vendor/libgit2/src/tree-cache.h +1 -1
- data/vendor/libgit2/src/tree.c +239 -166
- data/vendor/libgit2/src/tree.h +11 -2
- data/vendor/libgit2/src/tsort.c +39 -23
- data/vendor/libgit2/src/unix/map.c +1 -1
- data/vendor/libgit2/src/unix/posix.h +12 -2
- data/vendor/libgit2/src/unix/realpath.c +30 -0
- data/vendor/libgit2/src/util.c +250 -13
- data/vendor/libgit2/src/util.h +71 -14
- data/vendor/libgit2/src/vector.c +123 -60
- data/vendor/libgit2/src/vector.h +24 -22
- data/vendor/libgit2/src/win32/dir.c +1 -1
- data/vendor/libgit2/src/win32/dir.h +1 -1
- data/vendor/libgit2/src/win32/error.c +77 -0
- data/vendor/libgit2/src/win32/error.h +13 -0
- data/vendor/libgit2/src/win32/findfile.c +143 -54
- data/vendor/libgit2/src/win32/findfile.h +10 -6
- data/vendor/libgit2/src/win32/map.c +1 -1
- data/vendor/libgit2/src/win32/mingw-compat.h +1 -1
- data/vendor/libgit2/src/win32/msvc-compat.h +10 -1
- data/vendor/libgit2/src/win32/posix.h +10 -1
- data/vendor/libgit2/src/win32/posix_w32.c +132 -63
- data/vendor/libgit2/src/win32/precompiled.c +1 -1
- data/vendor/libgit2/src/win32/pthread.c +1 -1
- data/vendor/libgit2/src/win32/pthread.h +1 -1
- data/vendor/libgit2/src/win32/utf-conv.c +5 -5
- data/vendor/libgit2/src/win32/utf-conv.h +3 -3
- data/vendor/libgit2/src/win32/version.h +20 -0
- metadata +308 -252
- data/test/fixtures/testrepo.git/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904 +0 -0
- data/test/fixtures/testrepo.git/objects/7f/043268ea43ce18e3540acaabf9e090c91965b0 +0 -0
- data/test/fixtures/testrepo.git/objects/a3/e05719b428a2d0ed7a55c4ce53dcc5768c6d5e +0 -0
- data/test/index_test.rb~ +0 -218
- data/vendor/libgit2/src/pkt.h +0 -91
- data/vendor/libgit2/src/ppc/sha1.c +0 -70
- data/vendor/libgit2/src/ppc/sha1.h +0 -26
- data/vendor/libgit2/src/protocol.c +0 -110
- data/vendor/libgit2/src/protocol.h +0 -21
- data/vendor/libgit2/src/sha1.h +0 -33
- data/vendor/libgit2/src/transport.h +0 -148
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright (C)
|
|
2
|
+
* Copyright (C) the libgit2 contributors. All rights reserved.
|
|
3
3
|
*
|
|
4
4
|
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
|
5
5
|
* a Linking Exception. For full terms see the included COPYING file.
|
|
@@ -104,7 +104,7 @@ static int read_tree_internal(git_tree_cache **out,
|
|
|
104
104
|
tree->name[name_len] = '\0';
|
|
105
105
|
|
|
106
106
|
/* Blank-terminated ASCII decimal number of entries in this tree */
|
|
107
|
-
if (git__strtol32(&count, buffer, &buffer, 10) < 0
|
|
107
|
+
if (git__strtol32(&count, buffer, &buffer, 10) < 0)
|
|
108
108
|
goto corrupted;
|
|
109
109
|
|
|
110
110
|
tree->entries = count;
|
data/vendor/libgit2/src/tree.c
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright (C)
|
|
2
|
+
* Copyright (C) the libgit2 contributors. All rights reserved.
|
|
3
3
|
*
|
|
4
4
|
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
|
5
5
|
* a Linking Exception. For full terms see the included COPYING file.
|
|
@@ -18,25 +18,65 @@ static bool valid_filemode(const int filemode)
|
|
|
18
18
|
{
|
|
19
19
|
return (filemode == GIT_FILEMODE_TREE
|
|
20
20
|
|| filemode == GIT_FILEMODE_BLOB
|
|
21
|
-
|| filemode == GIT_FILEMODE_BLOB_GROUP_WRITABLE
|
|
22
21
|
|| filemode == GIT_FILEMODE_BLOB_EXECUTABLE
|
|
23
22
|
|| filemode == GIT_FILEMODE_LINK
|
|
24
23
|
|| filemode == GIT_FILEMODE_COMMIT);
|
|
25
24
|
}
|
|
26
25
|
|
|
26
|
+
GIT_INLINE(git_filemode_t) normalize_filemode(git_filemode_t filemode)
|
|
27
|
+
{
|
|
28
|
+
/* Tree bits set, but it's not a commit */
|
|
29
|
+
if (filemode & GIT_FILEMODE_TREE && !(filemode & 0100000))
|
|
30
|
+
return GIT_FILEMODE_TREE;
|
|
31
|
+
|
|
32
|
+
/* If any of the x bits is set */
|
|
33
|
+
if (filemode & 0111)
|
|
34
|
+
return GIT_FILEMODE_BLOB_EXECUTABLE;
|
|
35
|
+
|
|
36
|
+
/* 16XXXX means commit */
|
|
37
|
+
if ((filemode & GIT_FILEMODE_COMMIT) == GIT_FILEMODE_COMMIT)
|
|
38
|
+
return GIT_FILEMODE_COMMIT;
|
|
39
|
+
|
|
40
|
+
/* 12XXXX means commit */
|
|
41
|
+
if ((filemode & GIT_FILEMODE_LINK) == GIT_FILEMODE_LINK)
|
|
42
|
+
return GIT_FILEMODE_LINK;
|
|
43
|
+
|
|
44
|
+
/* Otherwise, return a blob */
|
|
45
|
+
return GIT_FILEMODE_BLOB;
|
|
46
|
+
}
|
|
47
|
+
|
|
27
48
|
static int valid_entry_name(const char *filename)
|
|
28
49
|
{
|
|
29
|
-
return *filename != '\0' &&
|
|
50
|
+
return *filename != '\0' &&
|
|
51
|
+
strchr(filename, '/') == NULL &&
|
|
52
|
+
(*filename != '.' ||
|
|
53
|
+
(strcmp(filename, ".") != 0 &&
|
|
54
|
+
strcmp(filename, "..") != 0 &&
|
|
55
|
+
strcmp(filename, DOT_GIT) != 0));
|
|
30
56
|
}
|
|
31
57
|
|
|
32
58
|
static int entry_sort_cmp(const void *a, const void *b)
|
|
33
59
|
{
|
|
34
|
-
const git_tree_entry *
|
|
35
|
-
const git_tree_entry *
|
|
60
|
+
const git_tree_entry *e1 = (const git_tree_entry *)a;
|
|
61
|
+
const git_tree_entry *e2 = (const git_tree_entry *)b;
|
|
36
62
|
|
|
37
63
|
return git_path_cmp(
|
|
38
|
-
|
|
39
|
-
|
|
64
|
+
e1->filename, e1->filename_len, git_tree_entry__is_tree(e1),
|
|
65
|
+
e2->filename, e2->filename_len, git_tree_entry__is_tree(e2),
|
|
66
|
+
git__strncmp);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
int git_tree_entry_cmp(const git_tree_entry *e1, const git_tree_entry *e2)
|
|
70
|
+
{
|
|
71
|
+
return entry_sort_cmp(e1, e2);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
int git_tree_entry_icmp(const git_tree_entry *e1, const git_tree_entry *e2)
|
|
75
|
+
{
|
|
76
|
+
return git_path_cmp(
|
|
77
|
+
e1->filename, e1->filename_len, git_tree_entry__is_tree(e1),
|
|
78
|
+
e2->filename, e2->filename_len, git_tree_entry__is_tree(e2),
|
|
79
|
+
git__strncasecmp);
|
|
40
80
|
}
|
|
41
81
|
|
|
42
82
|
static git_tree_entry *alloc_entry(const char *filename)
|
|
@@ -96,46 +136,57 @@ static int homing_search_cmp(const void *key, const void *array_member)
|
|
|
96
136
|
* ambiguous because of folder vs file sorting, we look linearly
|
|
97
137
|
* around the area for our target file.
|
|
98
138
|
*/
|
|
99
|
-
static int tree_key_search(
|
|
139
|
+
static int tree_key_search(
|
|
140
|
+
size_t *at_pos, git_vector *entries, const char *filename, size_t filename_len)
|
|
100
141
|
{
|
|
101
142
|
struct tree_key_search ksearch;
|
|
102
143
|
const git_tree_entry *entry;
|
|
103
|
-
|
|
104
|
-
int homing, i;
|
|
144
|
+
size_t homing, i;
|
|
105
145
|
|
|
106
146
|
ksearch.filename = filename;
|
|
107
147
|
ksearch.filename_len = filename_len;
|
|
108
148
|
|
|
109
149
|
/* Initial homing search; find an entry on the tree with
|
|
110
150
|
* the same prefix as the filename we're looking for */
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
return homing;
|
|
151
|
+
if (git_vector_bsearch2(&homing, entries, &homing_search_cmp, &ksearch) < 0)
|
|
152
|
+
return GIT_ENOTFOUND;
|
|
114
153
|
|
|
115
154
|
/* We found a common prefix. Look forward as long as
|
|
116
155
|
* there are entries that share the common prefix */
|
|
117
|
-
for (i = homing; i <
|
|
156
|
+
for (i = homing; i < entries->length; ++i) {
|
|
118
157
|
entry = entries->contents[i];
|
|
119
158
|
|
|
120
159
|
if (homing_search_cmp(&ksearch, entry) < 0)
|
|
121
160
|
break;
|
|
122
161
|
|
|
123
162
|
if (entry->filename_len == filename_len &&
|
|
124
|
-
memcmp(filename, entry->filename, filename_len) == 0)
|
|
125
|
-
|
|
163
|
+
memcmp(filename, entry->filename, filename_len) == 0) {
|
|
164
|
+
if (at_pos)
|
|
165
|
+
*at_pos = i;
|
|
166
|
+
|
|
167
|
+
return 0;
|
|
168
|
+
}
|
|
126
169
|
}
|
|
127
170
|
|
|
128
171
|
/* If we haven't found our filename yet, look backwards
|
|
129
172
|
* too as long as we have entries with the same prefix */
|
|
130
|
-
|
|
131
|
-
|
|
173
|
+
if (homing > 0) {
|
|
174
|
+
i = homing - 1;
|
|
132
175
|
|
|
133
|
-
|
|
134
|
-
|
|
176
|
+
do {
|
|
177
|
+
entry = entries->contents[i];
|
|
135
178
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
179
|
+
if (homing_search_cmp(&ksearch, entry) > 0)
|
|
180
|
+
break;
|
|
181
|
+
|
|
182
|
+
if (entry->filename_len == filename_len &&
|
|
183
|
+
memcmp(filename, entry->filename, filename_len) == 0) {
|
|
184
|
+
if (at_pos)
|
|
185
|
+
*at_pos = i;
|
|
186
|
+
|
|
187
|
+
return 0;
|
|
188
|
+
}
|
|
189
|
+
} while (i-- > 0);
|
|
139
190
|
}
|
|
140
191
|
|
|
141
192
|
/* The filename doesn't exist at all */
|
|
@@ -164,25 +215,30 @@ git_tree_entry *git_tree_entry_dup(const git_tree_entry *entry)
|
|
|
164
215
|
return NULL;
|
|
165
216
|
|
|
166
217
|
memcpy(copy, entry, total_size);
|
|
218
|
+
|
|
167
219
|
return copy;
|
|
168
220
|
}
|
|
169
221
|
|
|
170
222
|
void git_tree__free(git_tree *tree)
|
|
171
223
|
{
|
|
172
|
-
|
|
224
|
+
size_t i;
|
|
225
|
+
git_tree_entry *e;
|
|
173
226
|
|
|
174
|
-
|
|
175
|
-
git_tree_entry *e = git_vector_get(&tree->entries, i);
|
|
227
|
+
git_vector_foreach(&tree->entries, i, e)
|
|
176
228
|
git_tree_entry_free(e);
|
|
177
|
-
}
|
|
178
229
|
|
|
179
230
|
git_vector_free(&tree->entries);
|
|
180
231
|
git__free(tree);
|
|
181
232
|
}
|
|
182
233
|
|
|
183
|
-
const git_oid *git_tree_id(const git_tree *
|
|
234
|
+
const git_oid *git_tree_id(const git_tree *t)
|
|
184
235
|
{
|
|
185
|
-
return git_object_id((const git_object *)
|
|
236
|
+
return git_object_id((const git_object *)t);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
git_repository *git_tree_owner(const git_tree *t)
|
|
240
|
+
{
|
|
241
|
+
return git_object_owner((const git_object *)t);
|
|
186
242
|
}
|
|
187
243
|
|
|
188
244
|
git_filemode_t git_tree_entry_filemode(const git_tree_entry *entry)
|
|
@@ -223,31 +279,36 @@ int git_tree_entry_to_object(
|
|
|
223
279
|
return git_object_lookup(object_out, repo, &entry->oid, GIT_OBJ_ANY);
|
|
224
280
|
}
|
|
225
281
|
|
|
226
|
-
static git_tree_entry *entry_fromname(
|
|
282
|
+
static const git_tree_entry *entry_fromname(
|
|
283
|
+
git_tree *tree, const char *name, size_t name_len)
|
|
227
284
|
{
|
|
228
|
-
|
|
229
|
-
|
|
285
|
+
size_t idx;
|
|
286
|
+
|
|
287
|
+
if (tree_key_search(&idx, &tree->entries, name, name_len) < 0)
|
|
230
288
|
return NULL;
|
|
231
289
|
|
|
232
290
|
return git_vector_get(&tree->entries, idx);
|
|
233
291
|
}
|
|
234
292
|
|
|
235
|
-
const git_tree_entry *git_tree_entry_byname(
|
|
293
|
+
const git_tree_entry *git_tree_entry_byname(
|
|
294
|
+
git_tree *tree, const char *filename)
|
|
236
295
|
{
|
|
237
296
|
assert(tree && filename);
|
|
238
297
|
return entry_fromname(tree, filename, strlen(filename));
|
|
239
298
|
}
|
|
240
299
|
|
|
241
|
-
const git_tree_entry *git_tree_entry_byindex(
|
|
300
|
+
const git_tree_entry *git_tree_entry_byindex(
|
|
301
|
+
git_tree *tree, size_t idx)
|
|
242
302
|
{
|
|
243
303
|
assert(tree);
|
|
244
304
|
return git_vector_get(&tree->entries, idx);
|
|
245
305
|
}
|
|
246
306
|
|
|
247
|
-
const git_tree_entry *git_tree_entry_byoid(
|
|
307
|
+
const git_tree_entry *git_tree_entry_byoid(
|
|
308
|
+
const git_tree *tree, const git_oid *oid)
|
|
248
309
|
{
|
|
249
|
-
|
|
250
|
-
git_tree_entry *e;
|
|
310
|
+
size_t i;
|
|
311
|
+
const git_tree_entry *e;
|
|
251
312
|
|
|
252
313
|
assert(tree);
|
|
253
314
|
|
|
@@ -263,13 +324,16 @@ int git_tree__prefix_position(git_tree *tree, const char *path)
|
|
|
263
324
|
{
|
|
264
325
|
git_vector *entries = &tree->entries;
|
|
265
326
|
struct tree_key_search ksearch;
|
|
266
|
-
|
|
327
|
+
size_t at_pos;
|
|
328
|
+
|
|
329
|
+
if (!path)
|
|
330
|
+
return 0;
|
|
267
331
|
|
|
268
332
|
ksearch.filename = path;
|
|
269
333
|
ksearch.filename_len = strlen(path);
|
|
270
334
|
|
|
271
335
|
/* Find tree entry with appropriate prefix */
|
|
272
|
-
|
|
336
|
+
git_vector_bsearch2(&at_pos, entries, &homing_search_cmp, &ksearch);
|
|
273
337
|
|
|
274
338
|
for (; at_pos < entries->length; ++at_pos) {
|
|
275
339
|
const git_tree_entry *entry = entries->contents[at_pos];
|
|
@@ -283,18 +347,27 @@ int git_tree__prefix_position(git_tree *tree, const char *path)
|
|
|
283
347
|
break;
|
|
284
348
|
}
|
|
285
349
|
|
|
286
|
-
return at_pos;
|
|
350
|
+
return (int)at_pos;
|
|
287
351
|
}
|
|
288
352
|
|
|
289
|
-
|
|
353
|
+
size_t git_tree_entrycount(const git_tree *tree)
|
|
290
354
|
{
|
|
291
355
|
assert(tree);
|
|
292
|
-
return
|
|
356
|
+
return tree->entries.length;
|
|
293
357
|
}
|
|
294
358
|
|
|
295
|
-
|
|
359
|
+
unsigned int git_treebuilder_entrycount(git_treebuilder *bld)
|
|
296
360
|
{
|
|
297
|
-
|
|
361
|
+
assert(bld);
|
|
362
|
+
return (unsigned int)bld->entrycount;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
static int tree_error(const char *str, const char *path)
|
|
366
|
+
{
|
|
367
|
+
if (path)
|
|
368
|
+
giterr_set(GITERR_TREE, "%s - %s", str, path);
|
|
369
|
+
else
|
|
370
|
+
giterr_set(GITERR_TREE, "%s", str);
|
|
298
371
|
return -1;
|
|
299
372
|
}
|
|
300
373
|
|
|
@@ -307,23 +380,26 @@ static int tree_parse_buffer(git_tree *tree, const char *buffer, const char *buf
|
|
|
307
380
|
git_tree_entry *entry;
|
|
308
381
|
int attr;
|
|
309
382
|
|
|
310
|
-
if (git__strtol32(&attr, buffer, &buffer, 8) < 0 ||
|
|
311
|
-
|
|
312
|
-
|
|
383
|
+
if (git__strtol32(&attr, buffer, &buffer, 8) < 0 || !buffer)
|
|
384
|
+
return tree_error("Failed to parse tree. Can't parse filemode", NULL);
|
|
385
|
+
|
|
386
|
+
attr = normalize_filemode(attr); /* make sure to normalize the filemode */
|
|
313
387
|
|
|
314
388
|
if (*buffer++ != ' ')
|
|
315
|
-
return tree_error("Failed to parse tree. Object is corrupted");
|
|
389
|
+
return tree_error("Failed to parse tree. Object is corrupted", NULL);
|
|
316
390
|
|
|
317
391
|
if (memchr(buffer, 0, buffer_end - buffer) == NULL)
|
|
318
|
-
return tree_error("Failed to parse tree. Object is corrupted");
|
|
392
|
+
return tree_error("Failed to parse tree. Object is corrupted", NULL);
|
|
319
393
|
|
|
320
394
|
/** Allocate the entry and store it in the entries vector */
|
|
321
395
|
{
|
|
322
396
|
entry = alloc_entry(buffer);
|
|
323
397
|
GITERR_CHECK_ALLOC(entry);
|
|
324
398
|
|
|
325
|
-
if (git_vector_insert(&tree->entries, entry) < 0)
|
|
399
|
+
if (git_vector_insert(&tree->entries, entry) < 0) {
|
|
400
|
+
git__free(entry);
|
|
326
401
|
return -1;
|
|
402
|
+
}
|
|
327
403
|
|
|
328
404
|
entry->attr = attr;
|
|
329
405
|
}
|
|
@@ -346,14 +422,13 @@ int git_tree__parse(git_tree *tree, git_odb_object *obj)
|
|
|
346
422
|
return tree_parse_buffer(tree, (char *)obj->raw.data, (char *)obj->raw.data + obj->raw.len);
|
|
347
423
|
}
|
|
348
424
|
|
|
349
|
-
static
|
|
425
|
+
static size_t find_next_dir(const char *dirname, git_index *index, size_t start)
|
|
350
426
|
{
|
|
351
|
-
|
|
352
|
-
size_t dirlen;
|
|
427
|
+
size_t dirlen, i, entries = git_index_entrycount(index);
|
|
353
428
|
|
|
354
429
|
dirlen = strlen(dirname);
|
|
355
430
|
for (i = start; i < entries; ++i) {
|
|
356
|
-
git_index_entry *entry =
|
|
431
|
+
const git_index_entry *entry = git_index_get_byindex(index, i);
|
|
357
432
|
if (strlen(entry->path) < dirlen ||
|
|
358
433
|
memcmp(entry->path, dirname, dirlen) ||
|
|
359
434
|
(dirlen > 0 && entry->path[dirlen] != '/')) {
|
|
@@ -372,15 +447,21 @@ static int append_entry(
|
|
|
372
447
|
{
|
|
373
448
|
git_tree_entry *entry;
|
|
374
449
|
|
|
450
|
+
if (!valid_entry_name(filename))
|
|
451
|
+
return tree_error("Failed to insert entry. Invalid name for a tree entry", filename);
|
|
452
|
+
|
|
375
453
|
entry = alloc_entry(filename);
|
|
376
454
|
GITERR_CHECK_ALLOC(entry);
|
|
377
455
|
|
|
378
456
|
git_oid_cpy(&entry->oid, id);
|
|
379
457
|
entry->attr = (uint16_t)filemode;
|
|
380
458
|
|
|
381
|
-
if (git_vector_insert(&bld->entries, entry) < 0)
|
|
459
|
+
if (git_vector_insert(&bld->entries, entry) < 0) {
|
|
460
|
+
git__free(entry);
|
|
382
461
|
return -1;
|
|
462
|
+
}
|
|
383
463
|
|
|
464
|
+
bld->entrycount++;
|
|
384
465
|
return 0;
|
|
385
466
|
}
|
|
386
467
|
|
|
@@ -389,11 +470,10 @@ static int write_tree(
|
|
|
389
470
|
git_repository *repo,
|
|
390
471
|
git_index *index,
|
|
391
472
|
const char *dirname,
|
|
392
|
-
|
|
473
|
+
size_t start)
|
|
393
474
|
{
|
|
394
475
|
git_treebuilder *bld = NULL;
|
|
395
|
-
|
|
396
|
-
unsigned int i, entries = git_index_entrycount(index);
|
|
476
|
+
size_t i, entries = git_index_entrycount(index);
|
|
397
477
|
int error;
|
|
398
478
|
size_t dirname_len = strlen(dirname);
|
|
399
479
|
const git_tree_cache *cache;
|
|
@@ -401,13 +481,11 @@ static int write_tree(
|
|
|
401
481
|
cache = git_tree_cache_get(index->tree, dirname);
|
|
402
482
|
if (cache != NULL && cache->entries >= 0){
|
|
403
483
|
git_oid_cpy(oid, &cache->oid);
|
|
404
|
-
return find_next_dir(dirname, index, start);
|
|
484
|
+
return (int)find_next_dir(dirname, index, start);
|
|
405
485
|
}
|
|
406
486
|
|
|
407
|
-
error = git_treebuilder_create(&bld, NULL)
|
|
408
|
-
if (bld == NULL) {
|
|
487
|
+
if ((error = git_treebuilder_create(&bld, NULL)) < 0 || bld == NULL)
|
|
409
488
|
return -1;
|
|
410
|
-
}
|
|
411
489
|
|
|
412
490
|
/*
|
|
413
491
|
* This loop is unfortunate, but necessary. The index doesn't have
|
|
@@ -415,8 +493,8 @@ static int write_tree(
|
|
|
415
493
|
* need to keep track of the current position.
|
|
416
494
|
*/
|
|
417
495
|
for (i = start; i < entries; ++i) {
|
|
418
|
-
git_index_entry *entry =
|
|
419
|
-
char *filename, *next_slash;
|
|
496
|
+
const git_index_entry *entry = git_index_get_byindex(index, i);
|
|
497
|
+
const char *filename, *next_slash;
|
|
420
498
|
|
|
421
499
|
/*
|
|
422
500
|
* If we've left our (sub)tree, exit the loop and return. The
|
|
@@ -447,7 +525,8 @@ static int write_tree(
|
|
|
447
525
|
/* Write out the subtree */
|
|
448
526
|
written = write_tree(&sub_oid, repo, index, subdir, i);
|
|
449
527
|
if (written < 0) {
|
|
450
|
-
tree_error("Failed to write subtree");
|
|
528
|
+
tree_error("Failed to write subtree", subdir);
|
|
529
|
+
git__free(subdir);
|
|
451
530
|
goto on_error;
|
|
452
531
|
} else {
|
|
453
532
|
i = written - 1; /* -1 because of the loop increment */
|
|
@@ -465,18 +544,15 @@ static int write_tree(
|
|
|
465
544
|
} else {
|
|
466
545
|
last_comp = subdir;
|
|
467
546
|
}
|
|
547
|
+
|
|
468
548
|
error = append_entry(bld, last_comp, &sub_oid, S_IFDIR);
|
|
469
549
|
git__free(subdir);
|
|
470
|
-
if (error < 0)
|
|
471
|
-
tree_error("Failed to insert dir");
|
|
550
|
+
if (error < 0)
|
|
472
551
|
goto on_error;
|
|
473
|
-
}
|
|
474
552
|
} else {
|
|
475
553
|
error = append_entry(bld, filename, &entry->oid, entry->mode);
|
|
476
|
-
if (error < 0)
|
|
477
|
-
tree_error("Failed to insert file");
|
|
554
|
+
if (error < 0)
|
|
478
555
|
goto on_error;
|
|
479
|
-
}
|
|
480
556
|
}
|
|
481
557
|
}
|
|
482
558
|
|
|
@@ -484,50 +560,48 @@ static int write_tree(
|
|
|
484
560
|
goto on_error;
|
|
485
561
|
|
|
486
562
|
git_treebuilder_free(bld);
|
|
487
|
-
return i;
|
|
563
|
+
return (int)i;
|
|
488
564
|
|
|
489
565
|
on_error:
|
|
490
566
|
git_treebuilder_free(bld);
|
|
491
567
|
return -1;
|
|
492
568
|
}
|
|
493
569
|
|
|
494
|
-
int
|
|
570
|
+
int git_tree__write_index(
|
|
571
|
+
git_oid *oid, git_index *index, git_repository *repo)
|
|
495
572
|
{
|
|
496
573
|
int ret;
|
|
497
|
-
|
|
574
|
+
bool old_ignore_case = false;
|
|
498
575
|
|
|
499
|
-
|
|
576
|
+
assert(oid && index && repo);
|
|
500
577
|
|
|
501
|
-
if (
|
|
502
|
-
|
|
503
|
-
|
|
578
|
+
if (git_index_has_conflicts(index)) {
|
|
579
|
+
giterr_set(GITERR_INDEX,
|
|
580
|
+
"Cannot create a tree from a not fully merged index.");
|
|
581
|
+
return GIT_EUNMERGED;
|
|
582
|
+
}
|
|
504
583
|
|
|
505
584
|
if (index->tree != NULL && index->tree->entries >= 0) {
|
|
506
585
|
git_oid_cpy(oid, &index->tree->oid);
|
|
507
586
|
return 0;
|
|
508
587
|
}
|
|
509
588
|
|
|
510
|
-
/* The tree cache didn't help us
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
589
|
+
/* The tree cache didn't help us; we'll have to write
|
|
590
|
+
* out a tree. If the index is ignore_case, we must
|
|
591
|
+
* make it case-sensitive for the duration of the tree-write
|
|
592
|
+
* operation. */
|
|
514
593
|
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
}
|
|
594
|
+
if (index->ignore_case) {
|
|
595
|
+
old_ignore_case = true;
|
|
596
|
+
git_index__set_ignore_case(index, false);
|
|
597
|
+
}
|
|
519
598
|
|
|
520
|
-
|
|
521
|
-
{
|
|
522
|
-
/* 100664 mode is an early design mistake. Tree entries may bear
|
|
523
|
-
* this mode in some old git repositories, but it's now deprecated.
|
|
524
|
-
* We silently normalize while inserting new entries in a tree
|
|
525
|
-
* being built.
|
|
526
|
-
*/
|
|
527
|
-
if (filemode == GIT_FILEMODE_BLOB_GROUP_WRITABLE)
|
|
528
|
-
return GIT_FILEMODE_BLOB;
|
|
599
|
+
ret = write_tree(oid, repo, index, "", 0);
|
|
529
600
|
|
|
530
|
-
|
|
601
|
+
if (old_ignore_case)
|
|
602
|
+
git_index__set_ignore_case(index, true);
|
|
603
|
+
|
|
604
|
+
return ret < 0 ? ret : 0;
|
|
531
605
|
}
|
|
532
606
|
|
|
533
607
|
int git_treebuilder_create(git_treebuilder **builder_p, const git_tree *source)
|
|
@@ -547,13 +621,13 @@ int git_treebuilder_create(git_treebuilder **builder_p, const git_tree *source)
|
|
|
547
621
|
goto on_error;
|
|
548
622
|
|
|
549
623
|
if (source != NULL) {
|
|
550
|
-
|
|
551
|
-
git_tree_entry *entry_src = source->entries.contents[i];
|
|
624
|
+
git_tree_entry *entry_src;
|
|
552
625
|
|
|
626
|
+
git_vector_foreach(&source->entries, i, entry_src) {
|
|
553
627
|
if (append_entry(
|
|
554
628
|
bld, entry_src->filename,
|
|
555
629
|
&entry_src->oid,
|
|
556
|
-
|
|
630
|
+
entry_src->attr) < 0)
|
|
557
631
|
goto on_error;
|
|
558
632
|
}
|
|
559
633
|
}
|
|
@@ -574,53 +648,51 @@ int git_treebuilder_insert(
|
|
|
574
648
|
git_filemode_t filemode)
|
|
575
649
|
{
|
|
576
650
|
git_tree_entry *entry;
|
|
577
|
-
|
|
651
|
+
size_t pos;
|
|
578
652
|
|
|
579
653
|
assert(bld && id && filename);
|
|
580
654
|
|
|
581
655
|
if (!valid_filemode(filemode))
|
|
582
|
-
return tree_error("Failed to insert entry. Invalid filemode");
|
|
583
|
-
|
|
584
|
-
filemode = normalize_filemode(filemode);
|
|
656
|
+
return tree_error("Failed to insert entry. Invalid filemode for file", filename);
|
|
585
657
|
|
|
586
658
|
if (!valid_entry_name(filename))
|
|
587
|
-
return tree_error("Failed to insert entry. Invalid name for a tree entry");
|
|
588
|
-
|
|
589
|
-
pos = tree_key_search(&bld->entries, filename, strlen(filename));
|
|
659
|
+
return tree_error("Failed to insert entry. Invalid name for a tree entry", filename);
|
|
590
660
|
|
|
591
|
-
if (pos
|
|
661
|
+
if (!tree_key_search(&pos, &bld->entries, filename, strlen(filename))) {
|
|
592
662
|
entry = git_vector_get(&bld->entries, pos);
|
|
593
|
-
if (entry->removed)
|
|
663
|
+
if (entry->removed) {
|
|
594
664
|
entry->removed = 0;
|
|
665
|
+
bld->entrycount++;
|
|
666
|
+
}
|
|
595
667
|
} else {
|
|
596
668
|
entry = alloc_entry(filename);
|
|
597
669
|
GITERR_CHECK_ALLOC(entry);
|
|
670
|
+
|
|
671
|
+
if (git_vector_insert(&bld->entries, entry) < 0) {
|
|
672
|
+
git__free(entry);
|
|
673
|
+
return -1;
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
bld->entrycount++;
|
|
598
677
|
}
|
|
599
678
|
|
|
600
679
|
git_oid_cpy(&entry->oid, id);
|
|
601
680
|
entry->attr = filemode;
|
|
602
681
|
|
|
603
|
-
if (
|
|
604
|
-
if (git_vector_insert(&bld->entries, entry) < 0)
|
|
605
|
-
return -1;
|
|
606
|
-
}
|
|
607
|
-
|
|
608
|
-
if (entry_out != NULL) {
|
|
682
|
+
if (entry_out)
|
|
609
683
|
*entry_out = entry;
|
|
610
|
-
}
|
|
611
684
|
|
|
612
685
|
return 0;
|
|
613
686
|
}
|
|
614
687
|
|
|
615
688
|
static git_tree_entry *treebuilder_get(git_treebuilder *bld, const char *filename)
|
|
616
689
|
{
|
|
617
|
-
|
|
690
|
+
size_t idx;
|
|
618
691
|
git_tree_entry *entry;
|
|
619
692
|
|
|
620
693
|
assert(bld && filename);
|
|
621
694
|
|
|
622
|
-
|
|
623
|
-
if (idx < 0)
|
|
695
|
+
if (tree_key_search(&idx, &bld->entries, filename, strlen(filename)) < 0)
|
|
624
696
|
return NULL;
|
|
625
697
|
|
|
626
698
|
entry = git_vector_get(&bld->entries, idx);
|
|
@@ -640,27 +712,29 @@ int git_treebuilder_remove(git_treebuilder *bld, const char *filename)
|
|
|
640
712
|
git_tree_entry *remove_ptr = treebuilder_get(bld, filename);
|
|
641
713
|
|
|
642
714
|
if (remove_ptr == NULL || remove_ptr->removed)
|
|
643
|
-
return tree_error("Failed to remove entry. File isn't in the tree");
|
|
715
|
+
return tree_error("Failed to remove entry. File isn't in the tree", filename);
|
|
644
716
|
|
|
645
717
|
remove_ptr->removed = 1;
|
|
718
|
+
bld->entrycount--;
|
|
646
719
|
return 0;
|
|
647
720
|
}
|
|
648
721
|
|
|
649
722
|
int git_treebuilder_write(git_oid *oid, git_repository *repo, git_treebuilder *bld)
|
|
650
723
|
{
|
|
651
|
-
|
|
724
|
+
int error = 0;
|
|
725
|
+
size_t i;
|
|
652
726
|
git_buf tree = GIT_BUF_INIT;
|
|
653
727
|
git_odb *odb;
|
|
654
728
|
|
|
655
729
|
assert(bld);
|
|
656
730
|
|
|
657
|
-
|
|
731
|
+
git_vector_sort(&bld->entries);
|
|
658
732
|
|
|
659
733
|
/* Grow the buffer beforehand to an estimated size */
|
|
660
|
-
git_buf_grow(&tree, bld->entries.length * 72);
|
|
734
|
+
error = git_buf_grow(&tree, bld->entries.length * 72);
|
|
661
735
|
|
|
662
|
-
for (i = 0; i < bld->entries.length; ++i) {
|
|
663
|
-
git_tree_entry *entry = bld->entries
|
|
736
|
+
for (i = 0; i < bld->entries.length && !error; ++i) {
|
|
737
|
+
git_tree_entry *entry = git_vector_get(&bld->entries, i);
|
|
664
738
|
|
|
665
739
|
if (entry->removed)
|
|
666
740
|
continue;
|
|
@@ -668,50 +742,49 @@ int git_treebuilder_write(git_oid *oid, git_repository *repo, git_treebuilder *b
|
|
|
668
742
|
git_buf_printf(&tree, "%o ", entry->attr);
|
|
669
743
|
git_buf_put(&tree, entry->filename, entry->filename_len + 1);
|
|
670
744
|
git_buf_put(&tree, (char *)entry->oid.id, GIT_OID_RAWSZ);
|
|
671
|
-
}
|
|
672
|
-
|
|
673
|
-
if (git_buf_oom(&tree))
|
|
674
|
-
goto on_error;
|
|
675
745
|
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
if (git_odb_write(oid, odb, tree.ptr, tree.size, GIT_OBJ_TREE) < 0)
|
|
681
|
-
goto on_error;
|
|
746
|
+
if (git_buf_oom(&tree))
|
|
747
|
+
error = -1;
|
|
748
|
+
}
|
|
682
749
|
|
|
683
|
-
|
|
684
|
-
|
|
750
|
+
if (!error &&
|
|
751
|
+
!(error = git_repository_odb__weakptr(&odb, repo)))
|
|
752
|
+
error = git_odb_write(oid, odb, tree.ptr, tree.size, GIT_OBJ_TREE);
|
|
685
753
|
|
|
686
|
-
on_error:
|
|
687
754
|
git_buf_free(&tree);
|
|
688
|
-
return
|
|
755
|
+
return error;
|
|
689
756
|
}
|
|
690
757
|
|
|
691
|
-
void git_treebuilder_filter(
|
|
758
|
+
void git_treebuilder_filter(
|
|
759
|
+
git_treebuilder *bld,
|
|
760
|
+
git_treebuilder_filter_cb filter,
|
|
761
|
+
void *payload)
|
|
692
762
|
{
|
|
693
|
-
|
|
763
|
+
size_t i;
|
|
764
|
+
git_tree_entry *entry;
|
|
694
765
|
|
|
695
766
|
assert(bld && filter);
|
|
696
767
|
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
if (!entry->removed && filter(entry, payload))
|
|
768
|
+
git_vector_foreach(&bld->entries, i, entry) {
|
|
769
|
+
if (!entry->removed && filter(entry, payload)) {
|
|
700
770
|
entry->removed = 1;
|
|
771
|
+
bld->entrycount--;
|
|
772
|
+
}
|
|
701
773
|
}
|
|
702
774
|
}
|
|
703
775
|
|
|
704
776
|
void git_treebuilder_clear(git_treebuilder *bld)
|
|
705
777
|
{
|
|
706
|
-
|
|
778
|
+
size_t i;
|
|
779
|
+
git_tree_entry *e;
|
|
780
|
+
|
|
707
781
|
assert(bld);
|
|
708
782
|
|
|
709
|
-
|
|
710
|
-
git_tree_entry *e = bld->entries.contents[i];
|
|
783
|
+
git_vector_foreach(&bld->entries, i, e)
|
|
711
784
|
git_tree_entry_free(e);
|
|
712
|
-
}
|
|
713
785
|
|
|
714
786
|
git_vector_clear(&bld->entries);
|
|
787
|
+
bld->entrycount = 0;
|
|
715
788
|
}
|
|
716
789
|
|
|
717
790
|
void git_treebuilder_free(git_treebuilder *bld)
|
|
@@ -797,24 +870,25 @@ int git_tree_entry_bypath(
|
|
|
797
870
|
}
|
|
798
871
|
|
|
799
872
|
static int tree_walk(
|
|
800
|
-
git_tree *tree,
|
|
873
|
+
const git_tree *tree,
|
|
801
874
|
git_treewalk_cb callback,
|
|
802
875
|
git_buf *path,
|
|
803
876
|
void *payload,
|
|
804
877
|
bool preorder)
|
|
805
878
|
{
|
|
806
879
|
int error = 0;
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
for (i = 0; i < tree->entries.length; ++i) {
|
|
810
|
-
git_tree_entry *entry = tree->entries.contents[i];
|
|
880
|
+
size_t i;
|
|
881
|
+
const git_tree_entry *entry;
|
|
811
882
|
|
|
883
|
+
git_vector_foreach(&tree->entries, i, entry) {
|
|
812
884
|
if (preorder) {
|
|
813
885
|
error = callback(path->ptr, entry, payload);
|
|
814
886
|
if (error > 0)
|
|
815
887
|
continue;
|
|
816
|
-
if (error < 0)
|
|
888
|
+
if (error < 0) {
|
|
889
|
+
giterr_clear();
|
|
817
890
|
return GIT_EUSER;
|
|
891
|
+
}
|
|
818
892
|
}
|
|
819
893
|
|
|
820
894
|
if (git_tree_entry__is_tree(entry)) {
|
|
@@ -841,6 +915,7 @@ static int tree_walk(
|
|
|
841
915
|
}
|
|
842
916
|
|
|
843
917
|
if (!preorder && callback(path->ptr, entry, payload) < 0) {
|
|
918
|
+
giterr_clear();
|
|
844
919
|
error = GIT_EUSER;
|
|
845
920
|
break;
|
|
846
921
|
}
|
|
@@ -849,25 +924,23 @@ static int tree_walk(
|
|
|
849
924
|
return error;
|
|
850
925
|
}
|
|
851
926
|
|
|
852
|
-
int git_tree_walk(
|
|
927
|
+
int git_tree_walk(
|
|
928
|
+
const git_tree *tree,
|
|
929
|
+
git_treewalk_mode mode,
|
|
930
|
+
git_treewalk_cb callback,
|
|
931
|
+
void *payload)
|
|
853
932
|
{
|
|
854
933
|
int error = 0;
|
|
855
934
|
git_buf root_path = GIT_BUF_INIT;
|
|
856
935
|
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
break;
|
|
861
|
-
|
|
862
|
-
case GIT_TREEWALK_PRE:
|
|
863
|
-
error = tree_walk(tree, callback, &root_path, payload, true);
|
|
864
|
-
break;
|
|
865
|
-
|
|
866
|
-
default:
|
|
867
|
-
giterr_set(GITERR_INVALID, "Invalid walking mode for tree walk");
|
|
868
|
-
return -1;
|
|
936
|
+
if (mode != GIT_TREEWALK_POST && mode != GIT_TREEWALK_PRE) {
|
|
937
|
+
giterr_set(GITERR_INVALID, "Invalid walking mode for tree walk");
|
|
938
|
+
return -1;
|
|
869
939
|
}
|
|
870
940
|
|
|
941
|
+
error = tree_walk(
|
|
942
|
+
tree, callback, &root_path, payload, (mode == GIT_TREEWALK_PRE));
|
|
943
|
+
|
|
871
944
|
git_buf_free(&root_path);
|
|
872
945
|
|
|
873
946
|
return error;
|